Merge branch 'fix-installer-NPE' into 'master'
Make App and Apk parcelable and fix related installer NPEs Installations fails currently due to ``` 885 ACRA E Caused by: java.lang.NullPointerException 885 ACRA E at org.fdroid.fdroid.installer.InstallManagerService.getAppName(InstallManagerService.java:327) 885 ACRA E at org.fdroid.fdroid.installer.InstallManagerService.createNotificationBuilder(InstallManagerService.java:318) 885 ACRA E at org.fdroid.fdroid.installer.InstallManagerService.onStartCommand(InstallManagerService.java:158) 885 ACRA E at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2039) 885 ACRA E ... 10 more ``` This bug has been introduced in https://gitlab.com/fdroid/fdroidclient/merge_requests/359 where the packageName has been removed from the toContentValues() method. The usage of ContentValues to send App/Apk objects to services was an hack in my opinion. Thus, this PRs introduces proper parceling of App and Apk classes. @pserwylo @eighthave @mvdan See merge request !362
This commit is contained in:
commit
f4de353900
@ -4,6 +4,7 @@ import android.annotation.TargetApi;
|
|||||||
import android.content.ContentValues;
|
import android.content.ContentValues;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
import android.os.Parcel;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
|
|
||||||
import org.fdroid.fdroid.Utils;
|
import org.fdroid.fdroid.Utils;
|
||||||
@ -13,7 +14,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
|
||||||
public class Apk extends ValueObject implements Comparable<Apk> {
|
public class Apk extends ValueObject implements Comparable<Apk>, Parcelable {
|
||||||
|
|
||||||
// Using only byte-range keeps it only 8-bits in the SQLite database
|
// 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_MAX_VALUE = Byte.MAX_VALUE;
|
||||||
@ -69,10 +70,6 @@ public class Apk extends ValueObject implements Comparable<Apk> {
|
|||||||
public Apk() {
|
public Apk() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Apk(Parcelable parcelable) {
|
|
||||||
this(new ContentValuesCursor((ContentValues) parcelable));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Apk(Cursor cursor) {
|
public Apk(Cursor cursor) {
|
||||||
|
|
||||||
checkCursorPosition(cursor);
|
checkCursorPosition(cursor);
|
||||||
@ -231,4 +228,74 @@ public class Apk extends ValueObject implements Comparable<Apk> {
|
|||||||
return Integer.compare(versionCode, apk.versionCode);
|
return Integer.compare(versionCode, apk.versionCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(Parcel dest, int flags) {
|
||||||
|
dest.writeString(this.packageName);
|
||||||
|
dest.writeString(this.versionName);
|
||||||
|
dest.writeInt(this.versionCode);
|
||||||
|
dest.writeInt(this.size);
|
||||||
|
dest.writeLong(this.repo);
|
||||||
|
dest.writeString(this.hash);
|
||||||
|
dest.writeString(this.hashType);
|
||||||
|
dest.writeInt(this.minSdkVersion);
|
||||||
|
dest.writeInt(this.targetSdkVersion);
|
||||||
|
dest.writeInt(this.maxSdkVersion);
|
||||||
|
dest.writeLong(this.added != null ? this.added.getTime() : -1);
|
||||||
|
dest.writeStringArray(this.permissions);
|
||||||
|
dest.writeStringArray(this.features);
|
||||||
|
dest.writeStringArray(this.nativecode);
|
||||||
|
dest.writeString(this.sig);
|
||||||
|
dest.writeByte(this.compatible ? (byte) 1 : (byte) 0);
|
||||||
|
dest.writeString(this.apkName);
|
||||||
|
dest.writeSerializable(this.installedFile);
|
||||||
|
dest.writeString(this.srcname);
|
||||||
|
dest.writeInt(this.repoVersion);
|
||||||
|
dest.writeString(this.repoAddress);
|
||||||
|
dest.writeStringArray(this.incompatibleReasons);
|
||||||
|
dest.writeLong(this.appId);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Apk(Parcel in) {
|
||||||
|
this.packageName = in.readString();
|
||||||
|
this.versionName = in.readString();
|
||||||
|
this.versionCode = in.readInt();
|
||||||
|
this.size = in.readInt();
|
||||||
|
this.repo = in.readLong();
|
||||||
|
this.hash = in.readString();
|
||||||
|
this.hashType = in.readString();
|
||||||
|
this.minSdkVersion = in.readInt();
|
||||||
|
this.targetSdkVersion = in.readInt();
|
||||||
|
this.maxSdkVersion = in.readInt();
|
||||||
|
long tmpAdded = in.readLong();
|
||||||
|
this.added = tmpAdded == -1 ? null : new Date(tmpAdded);
|
||||||
|
this.permissions = in.createStringArray();
|
||||||
|
this.features = in.createStringArray();
|
||||||
|
this.nativecode = in.createStringArray();
|
||||||
|
this.sig = in.readString();
|
||||||
|
this.compatible = in.readByte() != 0;
|
||||||
|
this.apkName = in.readString();
|
||||||
|
this.installedFile = (SanitizedFile) in.readSerializable();
|
||||||
|
this.srcname = in.readString();
|
||||||
|
this.repoVersion = in.readInt();
|
||||||
|
this.repoAddress = in.readString();
|
||||||
|
this.incompatibleReasons = in.createStringArray();
|
||||||
|
this.appId = in.readLong();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Parcelable.Creator<Apk> CREATOR = new Parcelable.Creator<Apk>() {
|
||||||
|
@Override
|
||||||
|
public Apk createFromParcel(Parcel source) {
|
||||||
|
return new Apk(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Apk[] newArray(int size) {
|
||||||
|
return new Apk[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import android.content.pm.PackageManager;
|
|||||||
import android.content.res.AssetManager;
|
import android.content.res.AssetManager;
|
||||||
import android.content.res.XmlResourceParser;
|
import android.content.res.XmlResourceParser;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
|
import android.os.Parcel;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@ -34,7 +35,7 @@ import java.util.regex.Pattern;
|
|||||||
|
|
||||||
import org.fdroid.fdroid.data.Schema.AppTable.Cols;
|
import org.fdroid.fdroid.data.Schema.AppTable.Cols;
|
||||||
|
|
||||||
public class App extends ValueObject implements Comparable<App> {
|
public class App extends ValueObject implements Comparable<App>, Parcelable {
|
||||||
|
|
||||||
private static final String TAG = "App";
|
private static final String TAG = "App";
|
||||||
|
|
||||||
@ -144,10 +145,6 @@ public class App extends ValueObject implements Comparable<App> {
|
|||||||
public App() {
|
public App() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public App(Parcelable parcelable) {
|
|
||||||
this(new ContentValuesCursor((ContentValues) parcelable));
|
|
||||||
}
|
|
||||||
|
|
||||||
public App(Cursor cursor) {
|
public App(Cursor cursor) {
|
||||||
|
|
||||||
checkCursorPosition(cursor);
|
checkCursorPosition(cursor);
|
||||||
@ -560,4 +557,100 @@ public class App extends ValueObject implements Comparable<App> {
|
|||||||
public long getId() {
|
public long getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(Parcel dest, int flags) {
|
||||||
|
dest.writeByte(this.compatible ? (byte) 1 : (byte) 0);
|
||||||
|
dest.writeString(this.packageName);
|
||||||
|
dest.writeString(this.name);
|
||||||
|
dest.writeString(this.summary);
|
||||||
|
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.flattrID);
|
||||||
|
dest.writeString(this.upstreamVersionName);
|
||||||
|
dest.writeInt(this.upstreamVersionCode);
|
||||||
|
dest.writeString(this.suggestedVersionName);
|
||||||
|
dest.writeInt(this.suggestedVersionCode);
|
||||||
|
dest.writeLong(this.added != null ? this.added.getTime() : -1);
|
||||||
|
dest.writeLong(this.lastUpdated != null ? this.lastUpdated.getTime() : -1);
|
||||||
|
dest.writeStringArray(this.categories);
|
||||||
|
dest.writeStringArray(this.antiFeatures);
|
||||||
|
dest.writeStringArray(this.requirements);
|
||||||
|
dest.writeByte(this.ignoreAllUpdates ? (byte) 1 : (byte) 0);
|
||||||
|
dest.writeInt(this.ignoreThisUpdate);
|
||||||
|
dest.writeString(this.iconUrl);
|
||||||
|
dest.writeString(this.iconUrlLarge);
|
||||||
|
dest.writeString(this.installedVersionName);
|
||||||
|
dest.writeInt(this.installedVersionCode);
|
||||||
|
dest.writeParcelable(this.installedApk, flags);
|
||||||
|
dest.writeString(this.installedSig);
|
||||||
|
dest.writeLong(this.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected App(Parcel in) {
|
||||||
|
this.compatible = in.readByte() != 0;
|
||||||
|
this.packageName = in.readString();
|
||||||
|
this.name = in.readString();
|
||||||
|
this.summary = in.readString();
|
||||||
|
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.flattrID = in.readString();
|
||||||
|
this.upstreamVersionName = in.readString();
|
||||||
|
this.upstreamVersionCode = in.readInt();
|
||||||
|
this.suggestedVersionName = in.readString();
|
||||||
|
this.suggestedVersionCode = in.readInt();
|
||||||
|
long tmpAdded = in.readLong();
|
||||||
|
this.added = tmpAdded == -1 ? null : new Date(tmpAdded);
|
||||||
|
long tmpLastUpdated = in.readLong();
|
||||||
|
this.lastUpdated = tmpLastUpdated == -1 ? null : new Date(tmpLastUpdated);
|
||||||
|
this.categories = in.createStringArray();
|
||||||
|
this.antiFeatures = in.createStringArray();
|
||||||
|
this.requirements = in.createStringArray();
|
||||||
|
this.ignoreAllUpdates = in.readByte() != 0;
|
||||||
|
this.ignoreThisUpdate = in.readInt();
|
||||||
|
this.iconUrl = in.readString();
|
||||||
|
this.iconUrlLarge = in.readString();
|
||||||
|
this.installedVersionName = in.readString();
|
||||||
|
this.installedVersionCode = in.readInt();
|
||||||
|
this.installedApk = in.readParcelable(Apk.class.getClassLoader());
|
||||||
|
this.installedSig = in.readString();
|
||||||
|
this.id = in.readLong();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Parcelable.Creator<App> CREATOR = new Parcelable.Creator<App>() {
|
||||||
|
@Override
|
||||||
|
public App createFromParcel(Parcel source) {
|
||||||
|
return new App(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public App[] newArray(int size) {
|
||||||
|
return new App[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@ -151,8 +151,8 @@ public class InstallManagerService extends Service {
|
|||||||
return START_NOT_STICKY;
|
return START_NOT_STICKY;
|
||||||
}
|
}
|
||||||
|
|
||||||
App app = new App(intent.getParcelableExtra(EXTRA_APP));
|
App app = intent.getParcelableExtra(EXTRA_APP);
|
||||||
Apk apk = new Apk(intent.getParcelableExtra(EXTRA_APK));
|
Apk apk = intent.getParcelableExtra(EXTRA_APK);
|
||||||
addToActive(urlString, app, apk);
|
addToActive(urlString, app, apk);
|
||||||
|
|
||||||
NotificationCompat.Builder builder = createNotificationBuilder(urlString, apk);
|
NotificationCompat.Builder builder = createNotificationBuilder(urlString, apk);
|
||||||
@ -454,8 +454,8 @@ public class InstallManagerService extends Service {
|
|||||||
Intent intent = new Intent(context, InstallManagerService.class);
|
Intent intent = new Intent(context, InstallManagerService.class);
|
||||||
intent.setAction(ACTION_INSTALL);
|
intent.setAction(ACTION_INSTALL);
|
||||||
intent.setData(Uri.parse(urlString));
|
intent.setData(Uri.parse(urlString));
|
||||||
intent.putExtra(EXTRA_APP, app.toContentValues());
|
intent.putExtra(EXTRA_APP, app);
|
||||||
intent.putExtra(EXTRA_APK, apk.toContentValues());
|
intent.putExtra(EXTRA_APK, apk);
|
||||||
context.startService(intent);
|
context.startService(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,6 @@ import android.app.IntentService;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Parcelable;
|
|
||||||
|
|
||||||
import org.fdroid.fdroid.data.Apk;
|
import org.fdroid.fdroid.data.Apk;
|
||||||
|
|
||||||
@ -52,8 +51,7 @@ public class InstallerService extends IntentService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onHandleIntent(Intent intent) {
|
protected void onHandleIntent(Intent intent) {
|
||||||
Parcelable apkParcel = intent.getParcelableExtra(Installer.EXTRA_APK);
|
Apk apk = intent.getParcelableExtra(Installer.EXTRA_APK);
|
||||||
Apk apk = apkParcel == null ? null : new Apk(apkParcel);
|
|
||||||
|
|
||||||
Installer installer = InstallerFactory.create(this, apk);
|
Installer installer = InstallerFactory.create(this, apk);
|
||||||
|
|
||||||
@ -80,7 +78,7 @@ public class InstallerService extends IntentService {
|
|||||||
intent.setAction(ACTION_INSTALL);
|
intent.setAction(ACTION_INSTALL);
|
||||||
intent.setData(localApkUri);
|
intent.setData(localApkUri);
|
||||||
intent.putExtra(Installer.EXTRA_DOWNLOAD_URI, downloadUri);
|
intent.putExtra(Installer.EXTRA_DOWNLOAD_URI, downloadUri);
|
||||||
intent.putExtra(Installer.EXTRA_APK, apk.toContentValues());
|
intent.putExtra(Installer.EXTRA_APK, apk);
|
||||||
context.startService(intent);
|
context.startService(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user