Merge branch 'prep-for-new-index' into 'master'
prep for new index-v1 Closes #819 See merge request !439
This commit is contained in:
commit
6ac62d791a
@ -10,10 +10,16 @@ before_script:
|
||||
|
||||
test:
|
||||
script:
|
||||
- cd app
|
||||
- ./tools/langs-list-check.py
|
||||
- ./tools/check-string-format.py
|
||||
- cd ..
|
||||
- ./gradlew assemble -PdisablePreDex
|
||||
# always report on lint errors to the build log
|
||||
- sed -i -e 's,textReport .*,textReport true,' app/build.gradle
|
||||
- ./gradlew lint -PdisablePreDex
|
||||
- ./gradlew pmd -PdisablePreDex
|
||||
- ./gradlew checkstyle -PdisablePreDex
|
||||
- ./gradlew test -PdisablePreDex || {
|
||||
for log in app/build/reports/*ests/*/*ml; do
|
||||
echo "read $log here:";
|
||||
@ -64,24 +70,6 @@ connected24:
|
||||
done
|
||||
- exit $EXITVALUE
|
||||
|
||||
pmd:
|
||||
script:
|
||||
- ./gradlew pmd -PdisablePreDex
|
||||
|
||||
checkstyle:
|
||||
script:
|
||||
- ./gradlew checkstyle -PdisablePreDex
|
||||
|
||||
tools:
|
||||
before_script:
|
||||
- echo "ignored, no gradle needed"
|
||||
script:
|
||||
- cd app
|
||||
- ./tools/langs-list-check.py
|
||||
- ./tools/check-string-format.py
|
||||
after_script:
|
||||
- echo "ignored, no gradle needed"
|
||||
|
||||
after_script:
|
||||
# this file changes every time but should not be cached
|
||||
- rm -f $GRADLE_USER_HOME/caches/modules-2/modules-2.lock
|
||||
|
@ -1163,23 +1163,23 @@ public class AppDetails extends AppCompatActivity {
|
||||
App app = appDetails.getApp();
|
||||
switch (v.getId()) {
|
||||
case R.id.website:
|
||||
url = app.webURL;
|
||||
url = app.webSite;
|
||||
break;
|
||||
case R.id.email:
|
||||
final String subject = Uri.encode(getString(R.string.app_details_subject, app.name));
|
||||
url = "mailto:" + app.email + "?subject=" + subject;
|
||||
url = "mailto:" + app.authorEmail + "?subject=" + subject;
|
||||
break;
|
||||
case R.id.source:
|
||||
url = app.sourceURL;
|
||||
url = app.sourceCode;
|
||||
break;
|
||||
case R.id.issues:
|
||||
url = app.trackerURL;
|
||||
url = app.issueTracker;
|
||||
break;
|
||||
case R.id.changelog:
|
||||
url = app.changelogURL;
|
||||
url = app.changelog;
|
||||
break;
|
||||
case R.id.donate:
|
||||
url = app.donateURL;
|
||||
url = app.donate;
|
||||
break;
|
||||
case R.id.bitcoin:
|
||||
url = app.getBitcoinUri();
|
||||
@ -1267,7 +1267,7 @@ public class AppDetails extends AppCompatActivity {
|
||||
|
||||
// Website button
|
||||
View tv = view.findViewById(R.id.website);
|
||||
if (!TextUtils.isEmpty(app.webURL)) {
|
||||
if (!TextUtils.isEmpty(app.webSite)) {
|
||||
tv.setOnClickListener(onClickListener);
|
||||
} else {
|
||||
tv.setVisibility(View.GONE);
|
||||
@ -1275,7 +1275,7 @@ public class AppDetails extends AppCompatActivity {
|
||||
|
||||
// Email button
|
||||
tv = view.findViewById(R.id.email);
|
||||
if (!TextUtils.isEmpty(app.email)) {
|
||||
if (!TextUtils.isEmpty(app.authorEmail)) {
|
||||
tv.setOnClickListener(onClickListener);
|
||||
} else {
|
||||
tv.setVisibility(View.GONE);
|
||||
@ -1283,7 +1283,7 @@ public class AppDetails extends AppCompatActivity {
|
||||
|
||||
// Source button
|
||||
tv = view.findViewById(R.id.source);
|
||||
if (!TextUtils.isEmpty(app.sourceURL)) {
|
||||
if (!TextUtils.isEmpty(app.sourceCode)) {
|
||||
tv.setOnClickListener(onClickListener);
|
||||
} else {
|
||||
tv.setVisibility(View.GONE);
|
||||
@ -1291,7 +1291,7 @@ public class AppDetails extends AppCompatActivity {
|
||||
|
||||
// Issues button
|
||||
tv = view.findViewById(R.id.issues);
|
||||
if (!TextUtils.isEmpty(app.trackerURL)) {
|
||||
if (!TextUtils.isEmpty(app.issueTracker)) {
|
||||
tv.setOnClickListener(onClickListener);
|
||||
} else {
|
||||
tv.setVisibility(View.GONE);
|
||||
@ -1299,7 +1299,7 @@ public class AppDetails extends AppCompatActivity {
|
||||
|
||||
// Changelog button
|
||||
tv = view.findViewById(R.id.changelog);
|
||||
if (!TextUtils.isEmpty(app.changelogURL)) {
|
||||
if (!TextUtils.isEmpty(app.changelog)) {
|
||||
tv.setOnClickListener(onClickListener);
|
||||
} else {
|
||||
tv.setVisibility(View.GONE);
|
||||
@ -1307,7 +1307,7 @@ public class AppDetails extends AppCompatActivity {
|
||||
|
||||
// Donate button
|
||||
tv = view.findViewById(R.id.donate);
|
||||
if (!TextUtils.isEmpty(app.donateURL)) {
|
||||
if (!TextUtils.isEmpty(app.donate)) {
|
||||
tv.setOnClickListener(onClickListener);
|
||||
} else {
|
||||
tv.setVisibility(View.GONE);
|
||||
@ -1315,7 +1315,7 @@ public class AppDetails extends AppCompatActivity {
|
||||
|
||||
// Bitcoin
|
||||
tv = view.findViewById(R.id.bitcoin);
|
||||
if (!TextUtils.isEmpty(app.bitcoinAddr)) {
|
||||
if (!TextUtils.isEmpty(app.bitcoin)) {
|
||||
tv.setOnClickListener(onClickListener);
|
||||
} else {
|
||||
tv.setVisibility(View.GONE);
|
||||
@ -1323,7 +1323,7 @@ public class AppDetails extends AppCompatActivity {
|
||||
|
||||
// Litecoin
|
||||
tv = view.findViewById(R.id.litecoin);
|
||||
if (!TextUtils.isEmpty(app.litecoinAddr)) {
|
||||
if (!TextUtils.isEmpty(app.litecoin)) {
|
||||
tv.setOnClickListener(onClickListener);
|
||||
} else {
|
||||
tv.setVisibility(View.GONE);
|
||||
@ -1642,8 +1642,8 @@ public class AppDetails extends AppCompatActivity {
|
||||
btMain.setEnabled(true);
|
||||
}
|
||||
TextView author = (TextView) view.findViewById(R.id.author);
|
||||
if (!TextUtils.isEmpty(app.author)) {
|
||||
author.setText(getString(R.string.by_author) + " " + app.author);
|
||||
if (!TextUtils.isEmpty(app.authorName)) {
|
||||
author.setText(getString(R.string.by_author) + " " + app.authorName);
|
||||
author.setVisibility(View.VISIBLE);
|
||||
}
|
||||
TextView currentVersion = (TextView) view.findViewById(R.id.current_version);
|
||||
|
@ -58,6 +58,7 @@ import java.security.CodeSigner;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.jar.JarEntry;
|
||||
@ -195,9 +196,11 @@ public class RepoUpdater {
|
||||
private RepoXMLHandler.IndexReceiver createIndexReceiver() {
|
||||
return new RepoXMLHandler.IndexReceiver() {
|
||||
@Override
|
||||
public void receiveRepo(String name, String description, String signingCert, int maxAge, int version, long timestamp) {
|
||||
public void receiveRepo(String name, String description, String signingCert, int maxAge,
|
||||
int version, long timestamp, String icon, String[] mirrors) {
|
||||
signingCertFromIndexXml = signingCert;
|
||||
repoDetailsToSave = prepareRepoDetailsForSaving(name, description, maxAge, version, timestamp);
|
||||
repoDetailsToSave = prepareRepoDetailsForSaving(name, description, maxAge, version,
|
||||
timestamp, icon, mirrors);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -294,7 +297,9 @@ public class RepoUpdater {
|
||||
* Update tracking data for the repo represented by this instance (index version, etag,
|
||||
* description, human-readable name, etc.
|
||||
*/
|
||||
private ContentValues prepareRepoDetailsForSaving(String name, String description, int maxAge, int version, long timestamp) {
|
||||
private ContentValues prepareRepoDetailsForSaving(String name, String description, int maxAge,
|
||||
int version, long timestamp, String icon,
|
||||
String[] mirrors) {
|
||||
ContentValues values = new ContentValues();
|
||||
|
||||
values.put(RepoTable.Cols.LAST_UPDATED, Utils.formatTime(new Date(), ""));
|
||||
@ -329,6 +334,14 @@ public class RepoUpdater {
|
||||
// timestamp.
|
||||
values.put(RepoTable.Cols.TIMESTAMP, timestamp);
|
||||
|
||||
if (icon != null && !icon.equals(repo.icon)) {
|
||||
values.put(RepoTable.Cols.ICON, icon);
|
||||
}
|
||||
|
||||
if (mirrors != null && mirrors.length > 0 && !Arrays.equals(mirrors, repo.mirrors)) {
|
||||
values.put(RepoTable.Cols.MIRRORS, Utils.serializeCommaSeparatedString(mirrors));
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
|
@ -59,6 +59,8 @@ public class RepoXMLHandler extends DefaultHandler {
|
||||
private long repoTimestamp;
|
||||
private String repoDescription;
|
||||
private String repoName;
|
||||
private String repoIcon;
|
||||
private final ArrayList<String> repoMirrors = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Set of requested permissions per package/APK
|
||||
@ -73,7 +75,8 @@ public class RepoXMLHandler extends DefaultHandler {
|
||||
private final StringBuilder curchars = new StringBuilder();
|
||||
|
||||
public interface IndexReceiver {
|
||||
void receiveRepo(String name, String description, String signingCert, int maxage, int version, long timestamp);
|
||||
void receiveRepo(String name, String description, String signingCert, int maxage, int version,
|
||||
long timestamp, String icon, String[] mirrors);
|
||||
|
||||
void receiveApp(App app, List<Apk> packages);
|
||||
|
||||
@ -205,34 +208,34 @@ public class RepoXMLHandler extends DefaultHandler {
|
||||
curapp.license = str;
|
||||
break;
|
||||
case "author":
|
||||
curapp.author = str;
|
||||
curapp.authorName = str;
|
||||
break;
|
||||
case "email":
|
||||
curapp.email = str;
|
||||
curapp.authorEmail = str;
|
||||
break;
|
||||
case "source":
|
||||
curapp.sourceURL = str;
|
||||
curapp.sourceCode = str;
|
||||
break;
|
||||
case "changelog":
|
||||
curapp.changelogURL = str;
|
||||
curapp.changelog = str;
|
||||
break;
|
||||
case "donate":
|
||||
curapp.donateURL = str;
|
||||
curapp.donate = str;
|
||||
break;
|
||||
case "bitcoin":
|
||||
curapp.bitcoinAddr = str;
|
||||
curapp.bitcoin = str;
|
||||
break;
|
||||
case "litecoin":
|
||||
curapp.litecoinAddr = str;
|
||||
curapp.litecoin = str;
|
||||
break;
|
||||
case "flattr":
|
||||
curapp.flattrID = str;
|
||||
break;
|
||||
case "web":
|
||||
curapp.webURL = str;
|
||||
curapp.webSite = str;
|
||||
break;
|
||||
case "tracker":
|
||||
curapp.trackerURL = str;
|
||||
curapp.issueTracker = str;
|
||||
break;
|
||||
case "added":
|
||||
curapp.added = Utils.parseDate(str, null);
|
||||
@ -258,6 +261,8 @@ public class RepoXMLHandler extends DefaultHandler {
|
||||
}
|
||||
} else if ("description".equals(localName)) {
|
||||
repoDescription = cleanWhiteSpace(str);
|
||||
} else if ("mirror".equals(localName)) {
|
||||
repoMirrors.add(str);
|
||||
}
|
||||
}
|
||||
|
||||
@ -312,7 +317,8 @@ public class RepoXMLHandler extends DefaultHandler {
|
||||
}
|
||||
|
||||
private void onRepoParsed() {
|
||||
receiver.receiveRepo(repoName, repoDescription, repoSigningCert, repoMaxAge, repoVersion, repoTimestamp);
|
||||
receiver.receiveRepo(repoName, repoDescription, repoSigningCert, repoMaxAge, repoVersion,
|
||||
repoTimestamp, repoIcon, repoMirrors.toArray(new String[repoMirrors.size()]));
|
||||
}
|
||||
|
||||
private void onRepoPushRequestParsed(RepoPushRequest repoPushRequest) {
|
||||
@ -331,6 +337,7 @@ public class RepoXMLHandler extends DefaultHandler {
|
||||
repoName = cleanWhiteSpace(attributes.getValue("", "name"));
|
||||
repoDescription = cleanWhiteSpace(attributes.getValue("", "description"));
|
||||
repoTimestamp = parseLong(attributes.getValue("", "timestamp"), 0);
|
||||
repoIcon = attributes.getValue("", "icon");
|
||||
} else if (RepoPushRequest.INSTALL.equals(localName)
|
||||
|| RepoPushRequest.UNINSTALL.equals(localName)) {
|
||||
if (repo.pushRequests == Repo.PUSH_REQUEST_ACCEPT_ALWAYS) {
|
||||
|
@ -2,6 +2,7 @@ package org.fdroid.fdroid.data;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.ContentValues;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.database.Cursor;
|
||||
import android.os.Build;
|
||||
import android.os.Parcel;
|
||||
@ -73,6 +74,8 @@ public class Apk extends ValueObject implements Comparable<Apk>, Parcelable {
|
||||
public String repoAddress;
|
||||
public String[] incompatibleReasons;
|
||||
|
||||
public String[] antiFeatures;
|
||||
|
||||
/**
|
||||
* The numeric primary key of the Metadata table, which is used to join apks.
|
||||
*/
|
||||
@ -203,6 +206,9 @@ public class Apk extends ValueObject implements Comparable<Apk>, Parcelable {
|
||||
case Cols.Repo.ADDRESS:
|
||||
repoAddress = cursor.getString(i);
|
||||
break;
|
||||
case Cols.ANTI_FEATURES:
|
||||
antiFeatures = Utils.parseCommaSeparatedString(cursor.getString(i));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -303,6 +309,7 @@ public class Apk extends ValueObject implements Comparable<Apk>, Parcelable {
|
||||
values.put(Cols.FEATURES, Utils.serializeCommaSeparatedString(features));
|
||||
values.put(Cols.NATIVE_CODE, Utils.serializeCommaSeparatedString(nativecode));
|
||||
values.put(Cols.INCOMPATIBLE_REASONS, Utils.serializeCommaSeparatedString(incompatibleReasons));
|
||||
values.put(Cols.ANTI_FEATURES, Utils.serializeCommaSeparatedString(antiFeatures));
|
||||
values.put(Cols.IS_COMPATIBLE, compatible ? 1 : 0);
|
||||
return values;
|
||||
}
|
||||
@ -349,6 +356,7 @@ public class Apk extends ValueObject implements Comparable<Apk>, Parcelable {
|
||||
dest.writeInt(this.repoVersion);
|
||||
dest.writeString(this.repoAddress);
|
||||
dest.writeStringArray(this.incompatibleReasons);
|
||||
dest.writeStringArray(this.antiFeatures);
|
||||
dest.writeLong(this.appId);
|
||||
}
|
||||
|
||||
@ -380,6 +388,7 @@ public class Apk extends ValueObject implements Comparable<Apk>, Parcelable {
|
||||
this.repoVersion = in.readInt();
|
||||
this.repoAddress = in.readString();
|
||||
this.incompatibleReasons = in.createStringArray();
|
||||
this.antiFeatures = in.createStringArray();
|
||||
this.appId = in.readLong();
|
||||
}
|
||||
|
||||
|
@ -65,22 +65,22 @@ public class App extends ValueObject implements Comparable<App>, Parcelable {
|
||||
|
||||
public String license = "Unknown";
|
||||
|
||||
public String author;
|
||||
public String email;
|
||||
public String authorName;
|
||||
public String authorEmail;
|
||||
|
||||
public String webURL;
|
||||
public String webSite;
|
||||
|
||||
public String trackerURL;
|
||||
public String issueTracker;
|
||||
|
||||
public String sourceURL;
|
||||
public String sourceCode;
|
||||
|
||||
public String changelogURL;
|
||||
public String changelog;
|
||||
|
||||
public String donateURL;
|
||||
public String donate;
|
||||
|
||||
public String bitcoinAddr;
|
||||
public String bitcoin;
|
||||
|
||||
public String litecoinAddr;
|
||||
public String litecoin;
|
||||
|
||||
public String flattrID;
|
||||
|
||||
@ -113,8 +113,9 @@ public class App extends ValueObject implements Comparable<App>, Parcelable {
|
||||
public String[] antiFeatures;
|
||||
|
||||
/**
|
||||
* List of special requirements (such as root privileges) or null if there aren't any.
|
||||
* Requires root access (only ever used for root)
|
||||
*/
|
||||
@Deprecated
|
||||
public String[] requirements;
|
||||
|
||||
private AppPrefs prefs;
|
||||
@ -185,32 +186,32 @@ public class App extends ValueObject implements Comparable<App>, Parcelable {
|
||||
case Cols.LICENSE:
|
||||
license = cursor.getString(i);
|
||||
break;
|
||||
case Cols.AUTHOR:
|
||||
author = cursor.getString(i);
|
||||
case Cols.AUTHOR_NAME:
|
||||
authorName = cursor.getString(i);
|
||||
break;
|
||||
case Cols.EMAIL:
|
||||
email = cursor.getString(i);
|
||||
case Cols.AUTHOR_EMAIL:
|
||||
authorEmail = cursor.getString(i);
|
||||
break;
|
||||
case Cols.WEB_URL:
|
||||
webURL = cursor.getString(i);
|
||||
case Cols.WEBSITE:
|
||||
webSite = cursor.getString(i);
|
||||
break;
|
||||
case Cols.TRACKER_URL:
|
||||
trackerURL = cursor.getString(i);
|
||||
case Cols.ISSUE_TRACKER:
|
||||
issueTracker = cursor.getString(i);
|
||||
break;
|
||||
case Cols.SOURCE_URL:
|
||||
sourceURL = cursor.getString(i);
|
||||
case Cols.SOURCE_CODE:
|
||||
sourceCode = cursor.getString(i);
|
||||
break;
|
||||
case Cols.CHANGELOG_URL:
|
||||
changelogURL = cursor.getString(i);
|
||||
case Cols.CHANGELOG:
|
||||
changelog = cursor.getString(i);
|
||||
break;
|
||||
case Cols.DONATE_URL:
|
||||
donateURL = cursor.getString(i);
|
||||
case Cols.DONATE:
|
||||
donate = cursor.getString(i);
|
||||
break;
|
||||
case Cols.BITCOIN_ADDR:
|
||||
bitcoinAddr = cursor.getString(i);
|
||||
case Cols.BITCOIN:
|
||||
bitcoin = cursor.getString(i);
|
||||
break;
|
||||
case Cols.LITECOIN_ADDR:
|
||||
litecoinAddr = cursor.getString(i);
|
||||
case Cols.LITECOIN:
|
||||
litecoin = cursor.getString(i);
|
||||
break;
|
||||
case Cols.FLATTR_ID:
|
||||
flattrID = cursor.getString(i);
|
||||
@ -489,15 +490,15 @@ public class App extends ValueObject implements Comparable<App>, Parcelable {
|
||||
values.put(Cols.ICON_URL_LARGE, iconUrlLarge);
|
||||
values.put(Cols.DESCRIPTION, description);
|
||||
values.put(Cols.LICENSE, license);
|
||||
values.put(Cols.AUTHOR, author);
|
||||
values.put(Cols.EMAIL, email);
|
||||
values.put(Cols.WEB_URL, webURL);
|
||||
values.put(Cols.TRACKER_URL, trackerURL);
|
||||
values.put(Cols.SOURCE_URL, sourceURL);
|
||||
values.put(Cols.CHANGELOG_URL, changelogURL);
|
||||
values.put(Cols.DONATE_URL, donateURL);
|
||||
values.put(Cols.BITCOIN_ADDR, bitcoinAddr);
|
||||
values.put(Cols.LITECOIN_ADDR, litecoinAddr);
|
||||
values.put(Cols.AUTHOR_NAME, authorName);
|
||||
values.put(Cols.AUTHOR_EMAIL, authorEmail);
|
||||
values.put(Cols.WEBSITE, webSite);
|
||||
values.put(Cols.ISSUE_TRACKER, issueTracker);
|
||||
values.put(Cols.SOURCE_CODE, sourceCode);
|
||||
values.put(Cols.CHANGELOG, changelog);
|
||||
values.put(Cols.DONATE, donate);
|
||||
values.put(Cols.BITCOIN, bitcoin);
|
||||
values.put(Cols.LITECOIN, litecoin);
|
||||
values.put(Cols.FLATTR_ID, flattrID);
|
||||
values.put(Cols.ADDED, Utils.formatDate(added, ""));
|
||||
values.put(Cols.LAST_UPDATED, Utils.formatDate(lastUpdated, ""));
|
||||
@ -555,12 +556,12 @@ public class App extends ValueObject implements Comparable<App>, Parcelable {
|
||||
|
||||
@Nullable
|
||||
public String getBitcoinUri() {
|
||||
return TextUtils.isEmpty(bitcoinAddr) ? null : "bitcoin:" + bitcoinAddr;
|
||||
return TextUtils.isEmpty(bitcoin) ? null : "bitcoin:" + bitcoin;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getLitecoinUri() {
|
||||
return TextUtils.isEmpty(litecoinAddr) ? null : "litecoin:" + litecoinAddr;
|
||||
return TextUtils.isEmpty(bitcoin) ? null : "litecoin:" + bitcoin;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@ -631,15 +632,15 @@ public class App extends ValueObject implements Comparable<App>, Parcelable {
|
||||
dest.writeString(this.icon);
|
||||
dest.writeString(this.description);
|
||||
dest.writeString(this.license);
|
||||
dest.writeString(this.author);
|
||||
dest.writeString(this.email);
|
||||
dest.writeString(this.webURL);
|
||||
dest.writeString(this.trackerURL);
|
||||
dest.writeString(this.sourceURL);
|
||||
dest.writeString(this.changelogURL);
|
||||
dest.writeString(this.donateURL);
|
||||
dest.writeString(this.bitcoinAddr);
|
||||
dest.writeString(this.litecoinAddr);
|
||||
dest.writeString(this.authorName);
|
||||
dest.writeString(this.authorEmail);
|
||||
dest.writeString(this.webSite);
|
||||
dest.writeString(this.issueTracker);
|
||||
dest.writeString(this.sourceCode);
|
||||
dest.writeString(this.changelog);
|
||||
dest.writeString(this.donate);
|
||||
dest.writeString(this.bitcoin);
|
||||
dest.writeString(this.litecoin);
|
||||
dest.writeString(this.flattrID);
|
||||
dest.writeString(this.upstreamVersionName);
|
||||
dest.writeInt(this.upstreamVersionCode);
|
||||
@ -668,15 +669,15 @@ public class App extends ValueObject implements Comparable<App>, Parcelable {
|
||||
this.icon = in.readString();
|
||||
this.description = in.readString();
|
||||
this.license = in.readString();
|
||||
this.author = in.readString();
|
||||
this.email = in.readString();
|
||||
this.webURL = in.readString();
|
||||
this.trackerURL = in.readString();
|
||||
this.sourceURL = in.readString();
|
||||
this.changelogURL = in.readString();
|
||||
this.donateURL = in.readString();
|
||||
this.bitcoinAddr = in.readString();
|
||||
this.litecoinAddr = in.readString();
|
||||
this.authorName = in.readString();
|
||||
this.authorEmail = in.readString();
|
||||
this.webSite = in.readString();
|
||||
this.issueTracker = in.readString();
|
||||
this.sourceCode = in.readString();
|
||||
this.changelog = in.readString();
|
||||
this.donate = in.readString();
|
||||
this.bitcoin = in.readString();
|
||||
this.litecoin = in.readString();
|
||||
this.flattrID = in.readString();
|
||||
this.upstreamVersionName = in.readString();
|
||||
this.upstreamVersionCode = in.readInt();
|
||||
|
@ -12,9 +12,9 @@ import android.util.Log;
|
||||
import org.fdroid.fdroid.Preferences;
|
||||
import org.fdroid.fdroid.Utils;
|
||||
import org.fdroid.fdroid.data.Schema.ApkTable;
|
||||
import org.fdroid.fdroid.data.Schema.AppPrefsTable;
|
||||
import org.fdroid.fdroid.data.Schema.AppMetadataTable;
|
||||
import org.fdroid.fdroid.data.Schema.AppMetadataTable.Cols;
|
||||
import org.fdroid.fdroid.data.Schema.AppPrefsTable;
|
||||
import org.fdroid.fdroid.data.Schema.CatJoinTable;
|
||||
import org.fdroid.fdroid.data.Schema.CategoryTable;
|
||||
import org.fdroid.fdroid.data.Schema.InstalledAppTable;
|
||||
@ -837,6 +837,11 @@ public class AppProvider extends FDroidProvider {
|
||||
values.remove(Cols.Package.PACKAGE_NAME);
|
||||
values.put(Cols.PACKAGE_ID, packageId);
|
||||
|
||||
if (!values.containsKey(Cols.DESCRIPTION) || values.getAsString(Cols.DESCRIPTION) == null) {
|
||||
// the current structure assumes that description is always present and non-null
|
||||
values.put(Cols.DESCRIPTION, "");
|
||||
}
|
||||
|
||||
String[] categories = null;
|
||||
boolean saveCategories = false;
|
||||
if (values.containsKey(Cols.ForWriting.Categories.CATEGORIES)) {
|
||||
|
@ -76,6 +76,8 @@ class DBHelper extends SQLiteOpenHelper {
|
||||
+ RepoTable.Cols.USERNAME + " string, "
|
||||
+ RepoTable.Cols.PASSWORD + " string,"
|
||||
+ RepoTable.Cols.TIMESTAMP + " integer not null default 0, "
|
||||
+ RepoTable.Cols.ICON + " string, "
|
||||
+ RepoTable.Cols.MIRRORS + " string, "
|
||||
+ RepoTable.Cols.PUSH_REQUESTS + " integer not null default " + Repo.PUSH_REQUEST_IGNORE
|
||||
+ ");";
|
||||
|
||||
@ -104,6 +106,7 @@ class DBHelper extends SQLiteOpenHelper {
|
||||
+ ApkTable.Cols.ADDED_DATE + " string, "
|
||||
+ ApkTable.Cols.IS_COMPATIBLE + " int not null, "
|
||||
+ ApkTable.Cols.INCOMPATIBLE_REASONS + " text, "
|
||||
+ ApkTable.Cols.ANTI_FEATURES + " string, "
|
||||
+ "PRIMARY KEY (" + ApkTable.Cols.APP_ID + ", " + ApkTable.Cols.VERSION_CODE + ", " + ApkTable.Cols.REPO_ID + ")"
|
||||
+ ");";
|
||||
|
||||
@ -116,19 +119,19 @@ class DBHelper extends SQLiteOpenHelper {
|
||||
+ AppMetadataTable.Cols.ICON + " text, "
|
||||
+ AppMetadataTable.Cols.DESCRIPTION + " text not null, "
|
||||
+ AppMetadataTable.Cols.LICENSE + " text not null, "
|
||||
+ AppMetadataTable.Cols.AUTHOR + " text, "
|
||||
+ AppMetadataTable.Cols.EMAIL + " text, "
|
||||
+ AppMetadataTable.Cols.WEB_URL + " text, "
|
||||
+ AppMetadataTable.Cols.TRACKER_URL + " text, "
|
||||
+ AppMetadataTable.Cols.SOURCE_URL + " text, "
|
||||
+ AppMetadataTable.Cols.CHANGELOG_URL + " text, "
|
||||
+ AppMetadataTable.Cols.AUTHOR_NAME + " text, "
|
||||
+ AppMetadataTable.Cols.AUTHOR_EMAIL + " text, "
|
||||
+ AppMetadataTable.Cols.WEBSITE + " text, "
|
||||
+ AppMetadataTable.Cols.ISSUE_TRACKER + " text, "
|
||||
+ AppMetadataTable.Cols.SOURCE_CODE + " text, "
|
||||
+ AppMetadataTable.Cols.CHANGELOG + " text, "
|
||||
+ AppMetadataTable.Cols.SUGGESTED_VERSION_CODE + " text,"
|
||||
+ AppMetadataTable.Cols.UPSTREAM_VERSION_NAME + " text,"
|
||||
+ AppMetadataTable.Cols.UPSTREAM_VERSION_CODE + " integer,"
|
||||
+ AppMetadataTable.Cols.ANTI_FEATURES + " string,"
|
||||
+ AppMetadataTable.Cols.DONATE_URL + " string,"
|
||||
+ AppMetadataTable.Cols.BITCOIN_ADDR + " string,"
|
||||
+ AppMetadataTable.Cols.LITECOIN_ADDR + " string,"
|
||||
+ AppMetadataTable.Cols.DONATE + " string,"
|
||||
+ AppMetadataTable.Cols.BITCOIN + " string,"
|
||||
+ AppMetadataTable.Cols.LITECOIN + " string,"
|
||||
+ AppMetadataTable.Cols.FLATTR_ID + " string,"
|
||||
+ AppMetadataTable.Cols.REQUIREMENTS + " string,"
|
||||
+ AppMetadataTable.Cols.ADDED + " string,"
|
||||
@ -178,7 +181,7 @@ class DBHelper extends SQLiteOpenHelper {
|
||||
+ InstalledAppTable.Cols.HASH + " TEXT NOT NULL"
|
||||
+ " );";
|
||||
|
||||
protected static final int DB_VERSION = 65;
|
||||
protected static final int DB_VERSION = 66;
|
||||
|
||||
private final Context context;
|
||||
|
||||
@ -258,6 +261,27 @@ class DBHelper extends SQLiteOpenHelper {
|
||||
migrateToPackageTable(db, oldVersion);
|
||||
addObbFiles(db, oldVersion);
|
||||
addCategoryTables(db, oldVersion);
|
||||
addIndexV1Fields(db, oldVersion);
|
||||
}
|
||||
|
||||
private void addIndexV1Fields(SQLiteDatabase db, int oldVersion) {
|
||||
if (oldVersion >= 66) {
|
||||
return;
|
||||
}
|
||||
if (!columnExists(db, Schema.RepoTable.NAME, RepoTable.Cols.ICON)) {
|
||||
Utils.debugLog(TAG, "Adding " + RepoTable.Cols.ICON + " field to " + RepoTable.NAME + " table in db.");
|
||||
db.execSQL("alter table " + RepoTable.NAME + " add column " + RepoTable.Cols.ICON + " string;");
|
||||
}
|
||||
|
||||
if (!columnExists(db, RepoTable.NAME, RepoTable.Cols.MIRRORS)) {
|
||||
Utils.debugLog(TAG, "Adding " + RepoTable.Cols.MIRRORS + " field to " + RepoTable.NAME + " table in db.");
|
||||
db.execSQL("alter table " + RepoTable.NAME + " add column " + RepoTable.Cols.MIRRORS + " string;");
|
||||
}
|
||||
|
||||
if (!columnExists(db, ApkTable.NAME, ApkTable.Cols.ANTI_FEATURES)) {
|
||||
Utils.debugLog(TAG, "Adding " + ApkTable.Cols.ANTI_FEATURES + " field to " + ApkTable.NAME + " table in db.");
|
||||
db.execSQL("alter table " + ApkTable.NAME + " add column " + ApkTable.Cols.ANTI_FEATURES + " string;");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -756,11 +780,11 @@ class DBHelper extends SQLiteOpenHelper {
|
||||
}
|
||||
|
||||
private void addChangelogToApp(SQLiteDatabase db, int oldVersion) {
|
||||
if (oldVersion >= 48 || columnExists(db, AppMetadataTable.NAME, AppMetadataTable.Cols.CHANGELOG_URL)) {
|
||||
if (oldVersion >= 48 || columnExists(db, AppMetadataTable.NAME, AppMetadataTable.Cols.CHANGELOG)) {
|
||||
return;
|
||||
}
|
||||
Utils.debugLog(TAG, "Adding " + AppMetadataTable.Cols.CHANGELOG_URL + " column to " + AppMetadataTable.NAME);
|
||||
db.execSQL("alter table " + AppMetadataTable.NAME + " add column " + AppMetadataTable.Cols.CHANGELOG_URL + " text");
|
||||
Utils.debugLog(TAG, "Adding " + AppMetadataTable.Cols.CHANGELOG + " column to " + AppMetadataTable.NAME);
|
||||
db.execSQL("alter table " + AppMetadataTable.NAME + " add column " + AppMetadataTable.Cols.CHANGELOG + " text");
|
||||
}
|
||||
|
||||
private void addIconUrlLargeToApp(SQLiteDatabase db, int oldVersion) {
|
||||
@ -809,13 +833,13 @@ class DBHelper extends SQLiteOpenHelper {
|
||||
if (oldVersion >= 53) {
|
||||
return;
|
||||
}
|
||||
if (!columnExists(db, AppMetadataTable.NAME, AppMetadataTable.Cols.AUTHOR)) {
|
||||
Utils.debugLog(TAG, "Adding " + AppMetadataTable.Cols.AUTHOR + " column to " + AppMetadataTable.NAME);
|
||||
db.execSQL("alter table " + AppMetadataTable.NAME + " add column " + AppMetadataTable.Cols.AUTHOR + " text");
|
||||
if (!columnExists(db, AppMetadataTable.NAME, AppMetadataTable.Cols.AUTHOR_NAME)) {
|
||||
Utils.debugLog(TAG, "Adding " + AppMetadataTable.Cols.AUTHOR_NAME + " column to " + AppMetadataTable.NAME);
|
||||
db.execSQL("alter table " + AppMetadataTable.NAME + " add column " + AppMetadataTable.Cols.AUTHOR_NAME + " text");
|
||||
}
|
||||
if (!columnExists(db, AppMetadataTable.NAME, AppMetadataTable.Cols.EMAIL)) {
|
||||
Utils.debugLog(TAG, "Adding " + AppMetadataTable.Cols.EMAIL + " column to " + AppMetadataTable.NAME);
|
||||
db.execSQL("alter table " + AppMetadataTable.NAME + " add column " + AppMetadataTable.Cols.EMAIL + " text");
|
||||
if (!columnExists(db, AppMetadataTable.NAME, AppMetadataTable.Cols.AUTHOR_EMAIL)) {
|
||||
Utils.debugLog(TAG, "Adding " + AppMetadataTable.Cols.AUTHOR_EMAIL + " column to " + AppMetadataTable.NAME);
|
||||
db.execSQL("alter table " + AppMetadataTable.NAME + " add column " + AppMetadataTable.Cols.AUTHOR_EMAIL + " text");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -124,13 +124,21 @@ public class InstalledAppProviderService extends IntentService {
|
||||
* is in sync with what the {@link PackageManager} tells us is installed. Once
|
||||
* completed, the relevant {@link android.content.ContentProvider}s will be
|
||||
* notified of any changes to installed statuses.
|
||||
* <p/>
|
||||
* <p>
|
||||
* The installed app cache could get out of sync, e.g. if F-Droid crashed/ or
|
||||
* ran out of battery half way through responding to {@link Intent#ACTION_PACKAGE_ADDED}.
|
||||
* This method returns immediately, and will continue to work in an
|
||||
* {@link IntentService}. It doesn't really matter where we put this in the
|
||||
* bootstrap process, because it runs in its own thread, at the lowest priority:
|
||||
* {@link Process#THREAD_PRIORITY_LOWEST}.
|
||||
* <p>
|
||||
* APKs installed in {@code /system} will often have zeroed out timestamps, like
|
||||
* 2008-01-01 (ziptime) or 2009-01-01. So instead anything older than 2010 every
|
||||
* time since we have no way to know whether an APK wasn't changed as part of an
|
||||
* OTA update. An OTA update could change the APK without changing the
|
||||
* {@link PackageInfo#versionCode} or {@link PackageInfo#lastUpdateTime}.
|
||||
*
|
||||
* @see <a href="https://gitlab.com/fdroid/fdroidclient/issues/819>issue #819</a>
|
||||
*/
|
||||
public static void compareToPackageManager(Context context) {
|
||||
Map<String, Long> cachedInfo = InstalledAppProvider.Helper.all(context);
|
||||
@ -139,7 +147,8 @@ public class InstalledAppProviderService extends IntentService {
|
||||
.getInstalledPackages(PackageManager.GET_SIGNATURES);
|
||||
for (PackageInfo packageInfo : packageInfoList) {
|
||||
if (cachedInfo.containsKey(packageInfo.packageName)) {
|
||||
if (packageInfo.lastUpdateTime > cachedInfo.get(packageInfo.packageName)) {
|
||||
if (packageInfo.lastUpdateTime < 1262300400000L // 2010-01-01 00:00
|
||||
|| packageInfo.lastUpdateTime > cachedInfo.get(packageInfo.packageName)) {
|
||||
insert(context, packageInfo);
|
||||
}
|
||||
cachedInfo.remove(packageInfo.packageName);
|
||||
@ -207,7 +216,7 @@ public class InstalledAppProviderService extends IntentService {
|
||||
* broadcast. In the first case, it will already have a {@link PackageInfo} for us. However if
|
||||
* it is from the later case, we'll need to query the {@link PackageManager} ourselves to get
|
||||
* this info.
|
||||
*
|
||||
* <p>
|
||||
* Can still return null, as there is potentially race conditions to do with uninstalling apps
|
||||
* such that querying the {@link PackageManager} for a given package may throw an exception.
|
||||
*/
|
||||
|
@ -47,6 +47,7 @@ public class Repo extends ValueObject {
|
||||
public String address;
|
||||
public String name;
|
||||
public String description;
|
||||
public String icon;
|
||||
/** index version, i.e. what fdroidserver built it - 0 if not specified */
|
||||
public int version;
|
||||
public boolean inuse;
|
||||
@ -71,6 +72,9 @@ public class Repo extends ValueObject {
|
||||
/** When the signed repo index was generated, used to protect against replay attacks */
|
||||
public long timestamp;
|
||||
|
||||
/** Official mirrors of this repo, considered automatically interchangeable */
|
||||
public String[] mirrors;
|
||||
|
||||
/** How to treat push requests included in this repo's index XML */
|
||||
public int pushRequests = PUSH_REQUEST_IGNORE;
|
||||
|
||||
@ -131,6 +135,12 @@ public class Repo extends ValueObject {
|
||||
case Cols.TIMESTAMP:
|
||||
timestamp = cursor.getLong(i);
|
||||
break;
|
||||
case Cols.ICON:
|
||||
icon = cursor.getString(i);
|
||||
break;
|
||||
case Cols.MIRRORS:
|
||||
mirrors = Utils.parseCommaSeparatedString(cursor.getString(i));
|
||||
break;
|
||||
case Cols.PUSH_REQUESTS:
|
||||
pushRequests = cursor.getInt(i);
|
||||
break;
|
||||
@ -257,6 +267,14 @@ public class Repo extends ValueObject {
|
||||
timestamp = toInt(values.getAsInteger(Cols.TIMESTAMP));
|
||||
}
|
||||
|
||||
if (values.containsKey(Cols.ICON)) {
|
||||
icon = values.getAsString(Cols.ICON);
|
||||
}
|
||||
|
||||
if (values.containsKey(Cols.MIRRORS)) {
|
||||
mirrors = Utils.parseCommaSeparatedString(values.getAsString(Cols.MIRRORS));
|
||||
}
|
||||
|
||||
if (values.containsKey(Cols.PUSH_REQUESTS)) {
|
||||
pushRequests = toInt(values.getAsInteger(Cols.PUSH_REQUESTS));
|
||||
}
|
||||
|
@ -124,15 +124,15 @@ public interface Schema {
|
||||
String ICON = "icon";
|
||||
String DESCRIPTION = "description";
|
||||
String LICENSE = "license";
|
||||
String AUTHOR = "author";
|
||||
String EMAIL = "email";
|
||||
String WEB_URL = "webURL";
|
||||
String TRACKER_URL = "trackerURL";
|
||||
String SOURCE_URL = "sourceURL";
|
||||
String CHANGELOG_URL = "changelogURL";
|
||||
String DONATE_URL = "donateURL";
|
||||
String BITCOIN_ADDR = "bitcoinAddr";
|
||||
String LITECOIN_ADDR = "litecoinAddr";
|
||||
String AUTHOR_NAME = "author";
|
||||
String AUTHOR_EMAIL = "email";
|
||||
String WEBSITE = "webURL";
|
||||
String ISSUE_TRACKER = "trackerURL";
|
||||
String SOURCE_CODE = "sourceURL";
|
||||
String CHANGELOG = "changelogURL";
|
||||
String DONATE = "donateURL";
|
||||
String BITCOIN = "bitcoinAddr";
|
||||
String LITECOIN = "litecoinAddr";
|
||||
String FLATTR_ID = "flattrID";
|
||||
String SUGGESTED_VERSION_CODE = "suggestedVercode";
|
||||
String UPSTREAM_VERSION_NAME = "upstreamVersion";
|
||||
@ -176,8 +176,8 @@ public interface Schema {
|
||||
*/
|
||||
String[] ALL_COLS = {
|
||||
ROW_ID, PACKAGE_ID, REPO_ID, IS_COMPATIBLE, NAME, SUMMARY, ICON, DESCRIPTION,
|
||||
LICENSE, AUTHOR, EMAIL, WEB_URL, TRACKER_URL, SOURCE_URL,
|
||||
CHANGELOG_URL, DONATE_URL, BITCOIN_ADDR, LITECOIN_ADDR, FLATTR_ID,
|
||||
LICENSE, AUTHOR_NAME, AUTHOR_EMAIL, WEBSITE, ISSUE_TRACKER, SOURCE_CODE,
|
||||
CHANGELOG, DONATE, BITCOIN, LITECOIN, FLATTR_ID,
|
||||
UPSTREAM_VERSION_NAME, UPSTREAM_VERSION_CODE, ADDED, LAST_UPDATED,
|
||||
ANTI_FEATURES, REQUIREMENTS, ICON_URL, ICON_URL_LARGE,
|
||||
SUGGESTED_VERSION_CODE,
|
||||
@ -190,8 +190,8 @@ public interface Schema {
|
||||
*/
|
||||
String[] ALL = {
|
||||
_ID, ROW_ID, REPO_ID, IS_COMPATIBLE, NAME, SUMMARY, ICON, DESCRIPTION,
|
||||
LICENSE, AUTHOR, EMAIL, WEB_URL, TRACKER_URL, SOURCE_URL,
|
||||
CHANGELOG_URL, DONATE_URL, BITCOIN_ADDR, LITECOIN_ADDR, FLATTR_ID,
|
||||
LICENSE, AUTHOR_NAME, AUTHOR_EMAIL, WEBSITE, ISSUE_TRACKER, SOURCE_CODE,
|
||||
CHANGELOG, DONATE, BITCOIN, LITECOIN, FLATTR_ID,
|
||||
UPSTREAM_VERSION_NAME, UPSTREAM_VERSION_CODE, ADDED, LAST_UPDATED,
|
||||
ANTI_FEATURES, REQUIREMENTS, ICON_URL, ICON_URL_LARGE,
|
||||
SUGGESTED_VERSION_CODE, SuggestedApk.VERSION_NAME,
|
||||
@ -240,6 +240,7 @@ public interface Schema {
|
||||
String ADDED_DATE = "added";
|
||||
String IS_COMPATIBLE = "compatible";
|
||||
String INCOMPATIBLE_REASONS = "incompatibleReasons";
|
||||
String ANTI_FEATURES = "antiFeatures";
|
||||
|
||||
interface Repo {
|
||||
String VERSION = "repoVersion";
|
||||
@ -258,7 +259,7 @@ public interface Schema {
|
||||
SIZE, SIGNATURE, SOURCE_NAME, MIN_SDK_VERSION, TARGET_SDK_VERSION, MAX_SDK_VERSION,
|
||||
OBB_MAIN_FILE, OBB_MAIN_FILE_SHA256, OBB_PATCH_FILE, OBB_PATCH_FILE_SHA256,
|
||||
REQUESTED_PERMISSIONS, FEATURES, NATIVE_CODE, HASH_TYPE, ADDED_DATE,
|
||||
IS_COMPATIBLE, INCOMPATIBLE_REASONS,
|
||||
IS_COMPATIBLE, INCOMPATIBLE_REASONS, ANTI_FEATURES,
|
||||
};
|
||||
|
||||
/**
|
||||
@ -270,6 +271,7 @@ public interface Schema {
|
||||
OBB_MAIN_FILE, OBB_MAIN_FILE_SHA256, OBB_PATCH_FILE, OBB_PATCH_FILE_SHA256,
|
||||
REQUESTED_PERMISSIONS, FEATURES, NATIVE_CODE, HASH_TYPE, ADDED_DATE,
|
||||
IS_COMPATIBLE, Repo.VERSION, Repo.ADDRESS, INCOMPATIBLE_REASONS,
|
||||
ANTI_FEATURES,
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -295,12 +297,14 @@ public interface Schema {
|
||||
String USERNAME = "username";
|
||||
String PASSWORD = "password";
|
||||
String TIMESTAMP = "timestamp";
|
||||
String ICON = "icon";
|
||||
String MIRRORS = "mirrors";
|
||||
String PUSH_REQUESTS = "pushRequests";
|
||||
|
||||
String[] ALL = {
|
||||
_ID, ADDRESS, NAME, DESCRIPTION, IN_USE, PRIORITY, SIGNING_CERT,
|
||||
FINGERPRINT, MAX_AGE, LAST_UPDATED, LAST_ETAG, VERSION, IS_SWAP,
|
||||
USERNAME, PASSWORD, TIMESTAMP, PUSH_REQUESTS,
|
||||
USERNAME, PASSWORD, TIMESTAMP, ICON, MIRRORS, PUSH_REQUESTS,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -176,7 +176,7 @@ public class AppDetailsRecyclerViewAdapter
|
||||
}
|
||||
|
||||
private boolean shouldShowDonate() {
|
||||
return uriIsSetAndCanBeOpened(app.donateURL) ||
|
||||
return uriIsSetAndCanBeOpened(app.donate) ||
|
||||
uriIsSetAndCanBeOpened(app.getBitcoinUri()) ||
|
||||
uriIsSetAndCanBeOpened(app.getLitecoinUri()) ||
|
||||
uriIsSetAndCanBeOpened(app.getFlattrUri());
|
||||
@ -382,8 +382,8 @@ public class AppDetailsRecyclerViewAdapter
|
||||
public void bindModel() {
|
||||
ImageLoader.getInstance().displayImage(app.iconUrlLarge, iconView, displayImageOptions);
|
||||
titleView.setText(app.name);
|
||||
if (!TextUtils.isEmpty(app.author)) {
|
||||
authorView.setText(context.getString(R.string.by_author) + " " + app.author);
|
||||
if (!TextUtils.isEmpty(app.authorName)) {
|
||||
authorView.setText(context.getString(R.string.by_author) + " " + app.authorName);
|
||||
authorView.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
authorView.setVisibility(View.GONE);
|
||||
@ -523,18 +523,18 @@ public class AppDetailsRecyclerViewAdapter
|
||||
}
|
||||
|
||||
public void bindModel() {
|
||||
if (TextUtils.isEmpty(app.author)) {
|
||||
if (TextUtils.isEmpty(app.authorName)) {
|
||||
donateHeading.setText(context.getString(R.string.app_details_donate_prompt_unknown_author, app.name));
|
||||
} else {
|
||||
String author = "<strong>" + app.author + "</strong>";
|
||||
String author = "<strong>" + app.authorName + "</strong>";
|
||||
donateHeading.setText(Html.fromHtml(context.getString(R.string.app_details_donate_prompt, app.name, author)));
|
||||
}
|
||||
|
||||
donationOptionsLayout.removeAllViews();
|
||||
|
||||
// Donate button
|
||||
if (uriIsSetAndCanBeOpened(app.donateURL)) {
|
||||
addDonateOption(R.layout.donate_generic, app.donateURL);
|
||||
if (uriIsSetAndCanBeOpened(app.donate)) {
|
||||
addDonateOption(R.layout.donate_generic, app.donate);
|
||||
}
|
||||
|
||||
// Bitcoin
|
||||
@ -639,28 +639,28 @@ public class AppDetailsRecyclerViewAdapter
|
||||
contentView.removeAllViews();
|
||||
|
||||
// Source button
|
||||
if (uriIsSetAndCanBeOpened(app.sourceURL)) {
|
||||
addLinkItemView(contentView, R.string.menu_source, R.drawable.ic_source_code, app.sourceURL);
|
||||
if (uriIsSetAndCanBeOpened(app.sourceCode)) {
|
||||
addLinkItemView(contentView, R.string.menu_source, R.drawable.ic_source_code, app.sourceCode);
|
||||
}
|
||||
|
||||
// Issues button
|
||||
if (uriIsSetAndCanBeOpened(app.trackerURL)) {
|
||||
addLinkItemView(contentView, R.string.menu_issues, R.drawable.ic_issues, app.trackerURL);
|
||||
if (uriIsSetAndCanBeOpened(app.issueTracker)) {
|
||||
addLinkItemView(contentView, R.string.menu_issues, R.drawable.ic_issues, app.issueTracker);
|
||||
}
|
||||
|
||||
// Changelog button
|
||||
if (uriIsSetAndCanBeOpened(app.changelogURL)) {
|
||||
addLinkItemView(contentView, R.string.menu_changelog, R.drawable.ic_changelog, app.changelogURL);
|
||||
if (uriIsSetAndCanBeOpened(app.changelog)) {
|
||||
addLinkItemView(contentView, R.string.menu_changelog, R.drawable.ic_changelog, app.changelog);
|
||||
}
|
||||
|
||||
// Website button
|
||||
if (uriIsSetAndCanBeOpened(app.webURL)) {
|
||||
addLinkItemView(contentView, R.string.menu_website, R.drawable.ic_website, app.webURL);
|
||||
if (uriIsSetAndCanBeOpened(app.webSite)) {
|
||||
addLinkItemView(contentView, R.string.menu_website, R.drawable.ic_website, app.webSite);
|
||||
}
|
||||
|
||||
// Email button
|
||||
final String subject = Uri.encode(context.getString(R.string.app_details_subject, app.name));
|
||||
String emailUrl = app.email == null ? null : ("mailto:" + app.email + "?subject=" + subject);
|
||||
String emailUrl = app.authorEmail == null ? null : ("mailto:" + app.authorEmail + "?subject=" + subject);
|
||||
if (uriIsSetAndCanBeOpened(emailUrl)) {
|
||||
addLinkItemView(contentView, R.string.menu_email, R.drawable.ic_email, emailUrl);
|
||||
}
|
||||
|
@ -274,9 +274,9 @@ public class ProperMultiRepoUpdaterTest extends MultiRepoUpdaterTest {
|
||||
assertEquals("2048", a2048.name);
|
||||
assertEquals(String.format("<p>2048 from %s repo.</p>", id), a2048.description);
|
||||
assertEquals(String.format("Puzzle game (%s)", id), a2048.summary);
|
||||
assertEquals(String.format("https://github.com/uberspot/2048-android?%s", id), a2048.webURL);
|
||||
assertEquals(String.format("https://github.com/uberspot/2048-android?code&%s", id), a2048.sourceURL);
|
||||
assertEquals(String.format("https://github.com/uberspot/2048-android/issues?%s", id), a2048.trackerURL);
|
||||
assertEquals(String.format("https://github.com/uberspot/2048-android?%s", id), a2048.webSite);
|
||||
assertEquals(String.format("https://github.com/uberspot/2048-android?code&%s", id), a2048.sourceCode);
|
||||
assertEquals(String.format("https://github.com/uberspot/2048-android/issues?%s", id), a2048.issueTracker);
|
||||
}
|
||||
|
||||
private void assertAdAwayMetadata(Repo repo, @RepoIdentifier String id) {
|
||||
@ -290,11 +290,11 @@ public class ProperMultiRepoUpdaterTest extends MultiRepoUpdaterTest {
|
||||
assertEquals(String.format("AdAway", id), adaway.name);
|
||||
assertEquals(String.format("<p>AdAway from %s repo.</p>", id), adaway.description);
|
||||
assertEquals(String.format("Block advertisements (%s)", id), adaway.summary);
|
||||
assertEquals(String.format("http://sufficientlysecure.org/index.php/adaway?%s", id), adaway.webURL);
|
||||
assertEquals(String.format("https://github.com/dschuermann/ad-away?%s", id), adaway.sourceURL);
|
||||
assertEquals(String.format("https://github.com/dschuermann/ad-away/issues?%s", id), adaway.trackerURL);
|
||||
assertEquals(String.format("https://github.com/dschuermann/ad-away/raw/HEAD/CHANGELOG?%s", id), adaway.changelogURL);
|
||||
assertEquals(String.format("http://sufficientlysecure.org/index.php/adaway?%s", id), adaway.donateURL);
|
||||
assertEquals(String.format("http://sufficientlysecure.org/index.php/adaway?%s", id), adaway.webSite);
|
||||
assertEquals(String.format("https://github.com/dschuermann/ad-away?%s", id), adaway.sourceCode);
|
||||
assertEquals(String.format("https://github.com/dschuermann/ad-away/issues?%s", id), adaway.issueTracker);
|
||||
assertEquals(String.format("https://github.com/dschuermann/ad-away/raw/HEAD/CHANGELOG?%s", id), adaway.changelog);
|
||||
assertEquals(String.format("http://sufficientlysecure.org/index.php/adaway?%s", id), adaway.donate);
|
||||
assertEquals(String.format("369138", id), adaway.flattrID);
|
||||
}
|
||||
|
||||
@ -309,9 +309,9 @@ public class ProperMultiRepoUpdaterTest extends MultiRepoUpdaterTest {
|
||||
assertEquals("adbWireless", adb.name);
|
||||
assertEquals(String.format("<p>adbWireless from %s repo.</p>", id), adb.description);
|
||||
assertEquals(String.format("Wireless adb (%s)", id), adb.summary);
|
||||
assertEquals(String.format("https://adbwireless.example.com?%s", id), adb.webURL);
|
||||
assertEquals(String.format("https://adbwireless.example.com/source?%s", id), adb.sourceURL);
|
||||
assertEquals(String.format("https://adbwireless.example.com/issues?%s", id), adb.trackerURL);
|
||||
assertEquals(String.format("https://adbwireless.example.com?%s", id), adb.webSite);
|
||||
assertEquals(String.format("https://adbwireless.example.com/source?%s", id), adb.sourceCode);
|
||||
assertEquals(String.format("https://adbwireless.example.com/issues?%s", id), adb.issueTracker);
|
||||
}
|
||||
|
||||
private void assertCalendarMetadata(Repo repo, @RepoIdentifier String id) {
|
||||
@ -325,9 +325,9 @@ public class ProperMultiRepoUpdaterTest extends MultiRepoUpdaterTest {
|
||||
assertEquals("Add to calendar", calendar.name);
|
||||
assertEquals(String.format("<p>Add to calendar from %s repo.</p>", id), calendar.description);
|
||||
assertEquals(String.format("Import .ics files into calendar (%s)", id), calendar.summary);
|
||||
assertEquals(String.format("https://github.com/danielegobbetti/ICSImport/blob/HEAD/README.md?%s", id), calendar.webURL);
|
||||
assertEquals(String.format("https://github.com/danielegobbetti/ICSImport?%s", id), calendar.sourceURL);
|
||||
assertEquals(String.format("https://github.com/danielegobbetti/ICSImport/issues?%s", id), calendar.trackerURL);
|
||||
assertEquals(String.format("https://github.com/danielegobbetti/ICSImport/blob/HEAD/README.md?%s", id), calendar.webSite);
|
||||
assertEquals(String.format("https://github.com/danielegobbetti/ICSImport?%s", id), calendar.sourceCode);
|
||||
assertEquals(String.format("https://github.com/danielegobbetti/ICSImport/issues?%s", id), calendar.issueTracker);
|
||||
assertEquals("2225390", calendar.flattrID);
|
||||
}
|
||||
|
||||
|
@ -31,19 +31,24 @@ public class RepoDetails implements RepoXMLHandler.IndexReceiver {
|
||||
public int maxAge;
|
||||
public int version;
|
||||
public long timestamp;
|
||||
public String icon;
|
||||
public String[] mirrors;
|
||||
|
||||
public List<Apk> apks = new ArrayList<>();
|
||||
public List<App> apps = new ArrayList<>();
|
||||
public List<RepoPushRequest> repoPushRequestList = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void receiveRepo(String name, String description, String signingCert, int maxage, int version, long timestamp) {
|
||||
public void receiveRepo(String name, String description, String signingCert, int maxage,
|
||||
int version, long timestamp, String icon, String[] mirrors) {
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.signingCert = signingCert;
|
||||
this.maxAge = maxage;
|
||||
this.version = version;
|
||||
this.timestamp = timestamp;
|
||||
this.icon = icon;
|
||||
this.mirrors = mirrors;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Loading…
x
Reference in New Issue
Block a user