Merge branch 'parsing-and-notifications' into 'master'

parsing and notification fixes

This is a follow up to !306

See merge request !309
This commit is contained in:
Daniel Martí 2016-05-24 15:35:26 +00:00
commit 3f525c9bae
7 changed files with 69 additions and 49 deletions

View File

@ -1,9 +1,11 @@
package mock;
import android.annotation.SuppressLint;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
@SuppressLint("ParcelCreator")
public class MockApplicationInfo extends ApplicationInfo {
private final PackageInfo info;

View File

@ -126,10 +126,14 @@ public class RepoXMLHandler extends DefaultHandler {
curapk.apkName = str;
break;
case "sdkver":
curapk.minSdkVersion = Utils.parseInt(str, 0);
curapk.minSdkVersion = Utils.parseInt(str, Apk.SDK_VERSION_MIN_VALUE);
break;
case "maxsdkver":
curapk.maxSdkVersion = Utils.parseInt(str, 0);
curapk.maxSdkVersion = Utils.parseInt(str, Apk.SDK_VERSION_MAX_VALUE);
if (curapk.maxSdkVersion == 0) {
// before fc0df0dcf4dd0d5f13de82d7cd9254b2b48cb62d, this could be 0
curapk.maxSdkVersion = Apk.SDK_VERSION_MAX_VALUE;
}
break;
case "added":
curapk.added = Utils.parseDate(str, null);

View File

@ -20,8 +20,6 @@ package org.fdroid.fdroid;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.content.res.XmlResourceParser;
import android.graphics.Bitmap;
import android.net.Uri;
import android.support.annotation.NonNull;
@ -42,8 +40,6 @@ import org.fdroid.fdroid.compat.FileCompat;
import org.fdroid.fdroid.data.Repo;
import org.fdroid.fdroid.data.SanitizedFile;
import org.xml.sax.XMLReader;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.BufferedInputStream;
import java.io.Closeable;
@ -224,38 +220,6 @@ public final class Utils {
return ANDROID_VERSION_NAMES[sdkLevel];
}
/* PackageManager doesn't give us the min and max sdk versions, so we have
* to parse it */
private static int getMinMaxSdkVersion(Context context, String packageName,
String attrName) {
try {
AssetManager am = context.createPackageContext(packageName, 0).getAssets();
XmlResourceParser xml = am.openXmlResourceParser("AndroidManifest.xml");
int eventType = xml.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.START_TAG && "uses-sdk".equals(xml.getName())) {
for (int j = 0; j < xml.getAttributeCount(); j++) {
if (xml.getAttributeName(j).equals(attrName)) {
return Integer.parseInt(xml.getAttributeValue(j));
}
}
}
eventType = xml.nextToken();
}
} catch (PackageManager.NameNotFoundException | IOException | XmlPullParserException e) {
Log.e(TAG, "Could not get min/max sdk version", e);
}
return 0;
}
public static int getMinSdkVersion(Context context, String packageName) {
return getMinMaxSdkVersion(context, packageName, "minSdkVersion");
}
public static int getMaxSdkVersion(Context context, String packageName) {
return getMinMaxSdkVersion(context, packageName, "maxSdkVersion");
}
// return a fingerprint formatted for display
public static String formatFingerprint(Context context, String fingerprint) {
if (TextUtils.isEmpty(fingerprint)

View File

@ -14,6 +14,7 @@ public class Apk extends ValueObject implements Comparable<Apk> {
// Using only byte-range keeps it only 8-bits in the SQLite database
public static final int SDK_VERSION_MAX_VALUE = Byte.MAX_VALUE;
public static final int SDK_VERSION_MIN_VALUE = 0;
public String packageName;
public String versionName;
@ -22,7 +23,7 @@ public class Apk extends ValueObject implements Comparable<Apk> {
public long repo; // ID of the repo it comes from
public String hash;
public String hashType;
public int minSdkVersion; // 0 if unknown
public int minSdkVersion = SDK_VERSION_MIN_VALUE; // 0 if unknown
public int maxSdkVersion = SDK_VERSION_MAX_VALUE; // "infinity" if not set
public Date added;
public Utils.CommaSeparatedList permissions; // null if empty or

View File

@ -7,6 +7,8 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.FeatureInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.content.res.XmlResourceParser;
import android.database.Cursor;
import android.os.Parcelable;
import android.text.TextUtils;
@ -15,6 +17,8 @@ import android.util.Log;
import org.fdroid.fdroid.AppFilter;
import org.fdroid.fdroid.FDroidApp;
import org.fdroid.fdroid.Utils;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.File;
import java.io.IOException;
@ -293,8 +297,9 @@ public class App extends ValueObject implements Comparable<App> {
apk.versionName = packageInfo.versionName;
apk.versionCode = packageInfo.versionCode;
apk.added = this.added;
apk.minSdkVersion = Utils.getMinSdkVersion(context, packageName);
apk.maxSdkVersion = Utils.getMaxSdkVersion(context, packageName);
int[] minMaxSdkVersions = getMinMaxSdkVersions(context, packageName);
apk.minSdkVersion = minMaxSdkVersions[0];
apk.maxSdkVersion = minMaxSdkVersions[1];
apk.packageName = this.packageName;
apk.permissions = Utils.CommaSeparatedList.make(packageInfo.requestedPermissions);
apk.apkName = apk.packageName + "_" + apk.versionCode + ".apk";
@ -476,4 +481,34 @@ public class App extends ValueObject implements Comparable<App> {
public String getSuggestedVersionName() {
return suggestedVersionName;
}
/**
* {@link PackageManager} doesn't give us {@code minSdkVersion} and {@code maxSdkVersion},
* so we have to parse it straight from {@code <uses-sdk>} in {@code AndroidManifest.xml}.
*/
private static int[] getMinMaxSdkVersions(Context context, String packageName) {
int minSdkVersion = Apk.SDK_VERSION_MIN_VALUE;
int maxSdkVersion = Apk.SDK_VERSION_MAX_VALUE;
try {
AssetManager am = context.createPackageContext(packageName, 0).getAssets();
XmlResourceParser xml = am.openXmlResourceParser("AndroidManifest.xml");
int eventType = xml.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.START_TAG && "uses-sdk".equals(xml.getName())) {
for (int j = 0; j < xml.getAttributeCount(); j++) {
if (xml.getAttributeName(j).equals("minSdkVersion")) {
minSdkVersion = Integer.parseInt(xml.getAttributeValue(j));
} else if (xml.getAttributeName(j).equals("maxSdkVersion")) {
maxSdkVersion = Integer.parseInt(xml.getAttributeValue(j));
}
}
break;
}
eventType = xml.nextToken();
}
} catch (PackageManager.NameNotFoundException | IOException | XmlPullParserException e) {
Log.e(TAG, "Could not get min/max sdk version", e);
}
return new int[]{minSdkVersion, maxSdkVersion};
}
}

View File

@ -240,7 +240,7 @@ public class InstallManagerService extends Service {
if (AppDetails.isAppVisible(apk.packageName)) {
cancelNotification(urlString);
} else {
notifyDownloadComplete(urlString, builder, apk);
notifyDownloadComplete(urlString, apk);
}
unregisterDownloaderReceivers(urlString);
}
@ -312,9 +312,14 @@ public class InstallManagerService extends Service {
/**
* Post a notification about a completed download. {@code packageName} must be a valid
* and currently in the app index database.
* and currently in the app index database. This must create a new {@code Builder}
* instance otherwise the progress/cancel stuff does not go away.
*
* @see <a href=https://code.google.com/p/android/issues/detail?id=47809> Issue 47809:
* Removing the progress bar from a notification should cause the notification's content
* text to return to normal size</a>
*/
private void notifyDownloadComplete(String urlString, NotificationCompat.Builder builder, Apk apk) {
private void notifyDownloadComplete(String urlString, Apk apk) {
String title;
try {
PackageManager pm = getPackageManager();
@ -325,12 +330,16 @@ public class InstallManagerService extends Service {
}
int downloadUrlId = urlString.hashCode();
builder.setAutoCancel(true)
notificationManager.cancel(downloadUrlId);
Notification notification = new NotificationCompat.Builder(this)
.setAutoCancel(true)
.setOngoing(false)
.setContentTitle(title)
.setContentIntent(getAppDetailsIntent(downloadUrlId, apk))
.setSmallIcon(android.R.drawable.stat_sys_download_done)
.setContentText(getString(R.string.tap_to_install));
notificationManager.notify(downloadUrlId, builder.build());
.setContentText(getString(R.string.tap_to_install))
.build();
notificationManager.notify(downloadUrlId, notification);
}
/**

View File

@ -23,6 +23,7 @@ import org.fdroid.fdroid.Hasher;
import org.fdroid.fdroid.Preferences;
import org.fdroid.fdroid.R;
import org.fdroid.fdroid.Utils;
import org.fdroid.fdroid.data.Apk;
import org.fdroid.fdroid.data.App;
import org.fdroid.fdroid.data.SanitizedFile;
import org.xmlpull.v1.XmlPullParserException;
@ -452,9 +453,13 @@ public final class LocalRepoManager {
tagHash(app);
tag("sig", app.installedApk.sig.toLowerCase(Locale.US));
tag("size", app.installedApk.installedFile.length());
tag("sdkver", app.installedApk.minSdkVersion);
tag("maxsdkver", app.installedApk.maxSdkVersion);
tag("added", app.installedApk.added);
if (app.installedApk.minSdkVersion > Apk.SDK_VERSION_MIN_VALUE) {
tag("sdkver", app.installedApk.minSdkVersion);
}
if (app.installedApk.maxSdkVersion < Apk.SDK_VERSION_MAX_VALUE) {
tag("maxsdkver", app.installedApk.maxSdkVersion);
}
tagFeatures(app);
tagPermissions(app);
tagNativecode(app);