Add "preferredSigner" field to App.
At present, this is chosen from the first package in the index-v1 metadata.
This commit is contained in:
parent
6b42b802b3
commit
caac895442
@ -217,9 +217,14 @@ public class IndexV1Updater extends RepoUpdater {
|
|||||||
if (packages != null) {
|
if (packages != null) {
|
||||||
apks = packages.get(app.packageName);
|
apks = packages.get(app.packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (apks == null) {
|
if (apks == null) {
|
||||||
Log.i(TAG, "processIndexV1 empty packages");
|
Log.i(TAG, "processIndexV1 empty packages");
|
||||||
apks = new ArrayList<Apk>(0);
|
apks = new ArrayList<>(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (apks.size() > 0) {
|
||||||
|
app.preferredSigner = apks.get(0).sig;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (appCount % 50 == 0) {
|
if (appCount % 50 == 0) {
|
||||||
|
@ -8,6 +8,7 @@ import android.database.Cursor;
|
|||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import org.fdroid.fdroid.data.Schema.ApkTable;
|
import org.fdroid.fdroid.data.Schema.ApkTable;
|
||||||
@ -75,8 +76,22 @@ public class ApkProvider extends FDroidProvider {
|
|||||||
return resolver.delete(uri, null, null);
|
return resolver.delete(uri, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find an app which is closest to the version code suggested by the server, with some caveates:
|
||||||
|
* <ul>
|
||||||
|
* <li>If installed, limit to apks signed by the same signer as the installed apk.</li>
|
||||||
|
* <li>Otherwise, limit to apks signed by the "preferred" signer (see {@link App#preferredSigner}).</li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
public static Apk findSuggestedApk(Context context, App app) {
|
public static Apk findSuggestedApk(Context context, App app) {
|
||||||
return findApkFromAnyRepo(context, app.packageName, app.suggestedVersionCode, app.installedSig);
|
String preferredSignature = null;
|
||||||
|
if (!TextUtils.isEmpty(app.installedSig)) {
|
||||||
|
preferredSignature = app.installedSig;
|
||||||
|
} else if (!TextUtils.isEmpty(app.preferredSigner)) {
|
||||||
|
preferredSignature = app.preferredSigner;
|
||||||
|
}
|
||||||
|
|
||||||
|
return findApkFromAnyRepo(context, app.packageName, app.suggestedVersionCode, preferredSignature);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Apk findApkFromAnyRepo(Context context, String packageName, int versionCode) {
|
public static Apk findApkFromAnyRepo(Context context, String packageName, int versionCode) {
|
||||||
|
@ -98,6 +98,8 @@ public class App extends ValueObject implements Comparable<App>, Parcelable {
|
|||||||
private long id;
|
private long id;
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
private AppPrefs prefs;
|
private AppPrefs prefs;
|
||||||
|
@JsonIgnore
|
||||||
|
public String preferredSigner;
|
||||||
|
|
||||||
@JacksonInject("repoId")
|
@JacksonInject("repoId")
|
||||||
public long repoId;
|
public long repoId;
|
||||||
@ -286,6 +288,9 @@ public class App extends ValueObject implements Comparable<App>, Parcelable {
|
|||||||
case Cols.SuggestedApk.VERSION_NAME:
|
case Cols.SuggestedApk.VERSION_NAME:
|
||||||
suggestedVersionName = cursor.getString(i);
|
suggestedVersionName = cursor.getString(i);
|
||||||
break;
|
break;
|
||||||
|
case Cols.PREFERRED_SIGNER:
|
||||||
|
preferredSigner = cursor.getString(i);
|
||||||
|
break;
|
||||||
case Cols.SUGGESTED_VERSION_CODE:
|
case Cols.SUGGESTED_VERSION_CODE:
|
||||||
suggestedVersionCode = cursor.getInt(i);
|
suggestedVersionCode = cursor.getInt(i);
|
||||||
break;
|
break;
|
||||||
@ -828,6 +833,7 @@ public class App extends ValueObject implements Comparable<App>, Parcelable {
|
|||||||
values.put(Cols.FLATTR_ID, flattrID);
|
values.put(Cols.FLATTR_ID, flattrID);
|
||||||
values.put(Cols.ADDED, Utils.formatDate(added, ""));
|
values.put(Cols.ADDED, Utils.formatDate(added, ""));
|
||||||
values.put(Cols.LAST_UPDATED, Utils.formatDate(lastUpdated, ""));
|
values.put(Cols.LAST_UPDATED, Utils.formatDate(lastUpdated, ""));
|
||||||
|
values.put(Cols.PREFERRED_SIGNER, preferredSigner);
|
||||||
values.put(Cols.SUGGESTED_VERSION_CODE, suggestedVersionCode);
|
values.put(Cols.SUGGESTED_VERSION_CODE, suggestedVersionCode);
|
||||||
values.put(Cols.UPSTREAM_VERSION_NAME, upstreamVersionName);
|
values.put(Cols.UPSTREAM_VERSION_NAME, upstreamVersionName);
|
||||||
values.put(Cols.UPSTREAM_VERSION_CODE, upstreamVersionCode);
|
values.put(Cols.UPSTREAM_VERSION_CODE, upstreamVersionCode);
|
||||||
@ -1003,6 +1009,7 @@ public class App extends ValueObject implements Comparable<App>, Parcelable {
|
|||||||
dest.writeString(this.bitcoin);
|
dest.writeString(this.bitcoin);
|
||||||
dest.writeString(this.litecoin);
|
dest.writeString(this.litecoin);
|
||||||
dest.writeString(this.flattrID);
|
dest.writeString(this.flattrID);
|
||||||
|
dest.writeString(this.preferredSigner);
|
||||||
dest.writeString(this.upstreamVersionName);
|
dest.writeString(this.upstreamVersionName);
|
||||||
dest.writeInt(this.upstreamVersionCode);
|
dest.writeInt(this.upstreamVersionCode);
|
||||||
dest.writeString(this.suggestedVersionName);
|
dest.writeString(this.suggestedVersionName);
|
||||||
@ -1050,6 +1057,7 @@ public class App extends ValueObject implements Comparable<App>, Parcelable {
|
|||||||
this.bitcoin = in.readString();
|
this.bitcoin = in.readString();
|
||||||
this.litecoin = in.readString();
|
this.litecoin = in.readString();
|
||||||
this.flattrID = in.readString();
|
this.flattrID = in.readString();
|
||||||
|
this.preferredSigner = in.readString();
|
||||||
this.upstreamVersionName = in.readString();
|
this.upstreamVersionName = in.readString();
|
||||||
this.upstreamVersionCode = in.readInt();
|
this.upstreamVersionCode = in.readInt();
|
||||||
this.suggestedVersionName = in.readString();
|
this.suggestedVersionName = in.readString();
|
||||||
|
@ -128,6 +128,7 @@ class DBHelper extends SQLiteOpenHelper {
|
|||||||
+ AppMetadataTable.Cols.SOURCE_CODE + " text, "
|
+ AppMetadataTable.Cols.SOURCE_CODE + " text, "
|
||||||
+ AppMetadataTable.Cols.VIDEO + " string, "
|
+ AppMetadataTable.Cols.VIDEO + " string, "
|
||||||
+ AppMetadataTable.Cols.CHANGELOG + " text, "
|
+ AppMetadataTable.Cols.CHANGELOG + " text, "
|
||||||
|
+ AppMetadataTable.Cols.PREFERRED_SIGNER + " text,"
|
||||||
+ AppMetadataTable.Cols.SUGGESTED_VERSION_CODE + " text,"
|
+ AppMetadataTable.Cols.SUGGESTED_VERSION_CODE + " text,"
|
||||||
+ AppMetadataTable.Cols.UPSTREAM_VERSION_NAME + " text,"
|
+ AppMetadataTable.Cols.UPSTREAM_VERSION_NAME + " text,"
|
||||||
+ AppMetadataTable.Cols.UPSTREAM_VERSION_CODE + " integer,"
|
+ AppMetadataTable.Cols.UPSTREAM_VERSION_CODE + " integer,"
|
||||||
@ -192,7 +193,7 @@ class DBHelper extends SQLiteOpenHelper {
|
|||||||
+ InstalledAppTable.Cols.HASH + " TEXT NOT NULL"
|
+ InstalledAppTable.Cols.HASH + " TEXT NOT NULL"
|
||||||
+ " );";
|
+ " );";
|
||||||
|
|
||||||
protected static final int DB_VERSION = 71;
|
protected static final int DB_VERSION = 72;
|
||||||
|
|
||||||
private final Context context;
|
private final Context context;
|
||||||
|
|
||||||
@ -278,6 +279,18 @@ class DBHelper extends SQLiteOpenHelper {
|
|||||||
addWhatsNewAndVideo(db, oldVersion);
|
addWhatsNewAndVideo(db, oldVersion);
|
||||||
dropApkPrimaryKey(db, oldVersion);
|
dropApkPrimaryKey(db, oldVersion);
|
||||||
addIntegerPrimaryKeyToInstalledApps(db, oldVersion);
|
addIntegerPrimaryKeyToInstalledApps(db, oldVersion);
|
||||||
|
addPreferredSignerToApp(db, oldVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addPreferredSignerToApp(SQLiteDatabase db, int oldVersion) {
|
||||||
|
if (oldVersion >= 72) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!columnExists(db, AppMetadataTable.NAME, AppMetadataTable.Cols.PREFERRED_SIGNER)) {
|
||||||
|
Log.i(TAG, "Adding preferred signer to app table.");
|
||||||
|
db.execSQL("alter table " + AppMetadataTable.NAME + " add column " + AppMetadataTable.Cols.PREFERRED_SIGNER + " text;");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addIntegerPrimaryKeyToInstalledApps(SQLiteDatabase db, int oldVersion) {
|
private void addIntegerPrimaryKeyToInstalledApps(SQLiteDatabase db, int oldVersion) {
|
||||||
|
@ -136,6 +136,7 @@ public interface Schema {
|
|||||||
String BITCOIN = "bitcoinAddr";
|
String BITCOIN = "bitcoinAddr";
|
||||||
String LITECOIN = "litecoinAddr";
|
String LITECOIN = "litecoinAddr";
|
||||||
String FLATTR_ID = "flattrID";
|
String FLATTR_ID = "flattrID";
|
||||||
|
String PREFERRED_SIGNER = "preferredSigner";
|
||||||
String SUGGESTED_VERSION_CODE = "suggestedVercode";
|
String SUGGESTED_VERSION_CODE = "suggestedVercode";
|
||||||
String UPSTREAM_VERSION_NAME = "upstreamVersion";
|
String UPSTREAM_VERSION_NAME = "upstreamVersion";
|
||||||
String UPSTREAM_VERSION_CODE = "upstreamVercode";
|
String UPSTREAM_VERSION_CODE = "upstreamVercode";
|
||||||
@ -192,7 +193,7 @@ public interface Schema {
|
|||||||
ANTI_FEATURES, REQUIREMENTS, ICON_URL, ICON_URL_LARGE,
|
ANTI_FEATURES, REQUIREMENTS, ICON_URL, ICON_URL_LARGE,
|
||||||
FEATURE_GRAPHIC, PROMO_GRAPHIC, TV_BANNER, PHONE_SCREENSHOTS,
|
FEATURE_GRAPHIC, PROMO_GRAPHIC, TV_BANNER, PHONE_SCREENSHOTS,
|
||||||
SEVEN_INCH_SCREENSHOTS, TEN_INCH_SCREENSHOTS, TV_SCREENSHOTS, WEAR_SCREENSHOTS,
|
SEVEN_INCH_SCREENSHOTS, TEN_INCH_SCREENSHOTS, TV_SCREENSHOTS, WEAR_SCREENSHOTS,
|
||||||
SUGGESTED_VERSION_CODE,
|
PREFERRED_SIGNER, SUGGESTED_VERSION_CODE,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -208,7 +209,7 @@ public interface Schema {
|
|||||||
ANTI_FEATURES, REQUIREMENTS, ICON_URL, ICON_URL_LARGE,
|
ANTI_FEATURES, REQUIREMENTS, ICON_URL, ICON_URL_LARGE,
|
||||||
FEATURE_GRAPHIC, PROMO_GRAPHIC, TV_BANNER, PHONE_SCREENSHOTS,
|
FEATURE_GRAPHIC, PROMO_GRAPHIC, TV_BANNER, PHONE_SCREENSHOTS,
|
||||||
SEVEN_INCH_SCREENSHOTS, TEN_INCH_SCREENSHOTS, TV_SCREENSHOTS, WEAR_SCREENSHOTS,
|
SEVEN_INCH_SCREENSHOTS, TEN_INCH_SCREENSHOTS, TV_SCREENSHOTS, WEAR_SCREENSHOTS,
|
||||||
SUGGESTED_VERSION_CODE, SuggestedApk.VERSION_NAME,
|
PREFERRED_SIGNER, SUGGESTED_VERSION_CODE, SuggestedApk.VERSION_NAME,
|
||||||
InstalledApp.VERSION_CODE, InstalledApp.VERSION_NAME,
|
InstalledApp.VERSION_CODE, InstalledApp.VERSION_NAME,
|
||||||
InstalledApp.SIGNATURE, Package.PACKAGE_NAME,
|
InstalledApp.SIGNATURE, Package.PACKAGE_NAME,
|
||||||
};
|
};
|
||||||
|
@ -92,10 +92,11 @@ public class TestUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static App insertApp(Context context, String packageName, String appName, int upstreamVersionCode,
|
public static App insertApp(Context context, String packageName, String appName, int upstreamVersionCode,
|
||||||
Repo repo) {
|
Repo repo, String preferredSigner) {
|
||||||
ContentValues values = new ContentValues();
|
ContentValues values = new ContentValues();
|
||||||
values.put(Schema.AppMetadataTable.Cols.REPO_ID, repo.getId());
|
values.put(Schema.AppMetadataTable.Cols.REPO_ID, repo.getId());
|
||||||
values.put(Schema.AppMetadataTable.Cols.UPSTREAM_VERSION_CODE, upstreamVersionCode);
|
values.put(Schema.AppMetadataTable.Cols.UPSTREAM_VERSION_CODE, upstreamVersionCode);
|
||||||
|
values.put(Schema.AppMetadataTable.Cols.PREFERRED_SIGNER, preferredSigner);
|
||||||
return Assert.insertApp(context, packageName, appName, values);
|
return Assert.insertApp(context, packageName, appName, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ public class PreferredSignatureTest extends FDroidProviderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private App populateFDroidRepo(Repo repo) {
|
private App populateFDroidRepo(Repo repo) {
|
||||||
App app = TestUtils.insertApp(context, PACKAGE_NAME, "App", 3100, repo);
|
App app = TestUtils.insertApp(context, PACKAGE_NAME, "App", 3100, repo, TestUtils.UPSTREAM_SIG);
|
||||||
|
|
||||||
TestUtils.insertApk(context, app, 1100, TestUtils.FDROID_SIG); // 1.0
|
TestUtils.insertApk(context, app, 1100, TestUtils.FDROID_SIG); // 1.0
|
||||||
TestUtils.insertApk(context, app, 2100, TestUtils.FDROID_SIG); // 2.0
|
TestUtils.insertApk(context, app, 2100, TestUtils.FDROID_SIG); // 2.0
|
||||||
@ -54,7 +54,7 @@ public class PreferredSignatureTest extends FDroidProviderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private App populateDevRepo(Repo repo) {
|
private App populateDevRepo(Repo repo) {
|
||||||
App app = TestUtils.insertApp(context, PACKAGE_NAME, "App", 4100, repo);
|
App app = TestUtils.insertApp(context, PACKAGE_NAME, "App", 4100, repo, TestUtils.THIRD_PARTY_SIG);
|
||||||
|
|
||||||
TestUtils.insertApk(context, app, 1001, TestUtils.THIRD_PARTY_SIG); // 1.0-rc2
|
TestUtils.insertApk(context, app, 1001, TestUtils.THIRD_PARTY_SIG); // 1.0-rc2
|
||||||
TestUtils.insertApk(context, app, 1100, TestUtils.THIRD_PARTY_SIG); // 1.0
|
TestUtils.insertApk(context, app, 1100, TestUtils.THIRD_PARTY_SIG); // 1.0
|
||||||
@ -78,7 +78,7 @@ public class PreferredSignatureTest extends FDroidProviderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private App populateUpstreamRepo(Repo repo) {
|
private App populateUpstreamRepo(Repo repo) {
|
||||||
App app = TestUtils.insertApp(context, PACKAGE_NAME, "App", 4100, repo);
|
App app = TestUtils.insertApp(context, PACKAGE_NAME, "App", 4100, repo, TestUtils.UPSTREAM_SIG);
|
||||||
|
|
||||||
TestUtils.insertApk(context, app, 2100, TestUtils.UPSTREAM_SIG);
|
TestUtils.insertApk(context, app, 2100, TestUtils.UPSTREAM_SIG);
|
||||||
TestUtils.insertApk(context, app, 3100, TestUtils.UPSTREAM_SIG);
|
TestUtils.insertApk(context, app, 3100, TestUtils.UPSTREAM_SIG);
|
||||||
|
@ -263,6 +263,7 @@ public class IndexV1UpdaterTest extends FDroidProviderTest {
|
|||||||
"installedSig",
|
"installedSig",
|
||||||
"installedVersionCode",
|
"installedVersionCode",
|
||||||
"installedVersionName",
|
"installedVersionName",
|
||||||
|
"preferredSigner",
|
||||||
"prefs",
|
"prefs",
|
||||||
"TAG",
|
"TAG",
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user