Make AppSnippet parcelable
AppSnippet is used in Pia in 4 activities. Each time, it is expensive to parse the app's logo and label from PackageManager and the APK file of the app being installed. Thus, lets compute the AppSnippet once and pass it as an intent extra to whichever activity needs it. This also solves the bug where InstallSuccess showed an activity's name in place of the app label since the temporary directory used to create AppSnippet is already destroyed after app installation. Bug: 290862169 Test: Manually install an APK and observe the app install / update dialog Change-Id: I2095b092e1a7b3186ff4cdc4c81effce51377b19
This commit is contained in:
@@ -33,8 +33,6 @@ import android.view.View;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Installation failed: Return status code to the caller or display failure UI to user
|
||||
*/
|
||||
@@ -101,14 +99,8 @@ public class InstallFailed extends AlertActivity {
|
||||
// Set header icon and title
|
||||
PackageUtil.AppSnippet as;
|
||||
PackageManager pm = getPackageManager();
|
||||
|
||||
if ("package".equals(packageURI.getScheme())) {
|
||||
as = new PackageUtil.AppSnippet(pm.getApplicationLabel(appInfo),
|
||||
pm.getApplicationIcon(appInfo));
|
||||
} else {
|
||||
final File sourceFile = new File(packageURI.getPath());
|
||||
as = PackageUtil.getAppSnippet(this, appInfo, sourceFile);
|
||||
}
|
||||
as = intent.getParcelableExtra(PackageInstallerActivity.EXTRA_APP_SNIPPET,
|
||||
PackageUtil.AppSnippet.class);
|
||||
|
||||
// Store label for dialog
|
||||
mLabel = as.label;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.packageinstaller;
|
||||
|
||||
import static com.android.packageinstaller.PackageInstallerActivity.EXTRA_APP_SNIPPET;
|
||||
import static com.android.packageinstaller.PackageInstallerActivity.EXTRA_STAGED_SESSION_ID;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
@@ -86,7 +87,8 @@ public class InstallInstalling extends AlertActivity {
|
||||
// ContentResolver.SCHEME_FILE
|
||||
// STAGED_SESSION_ID extra contains an ID of a previously staged install session.
|
||||
final File sourceFile = new File(mPackageURI.getPath());
|
||||
PackageUtil.AppSnippet as = PackageUtil.getAppSnippet(this, appInfo, sourceFile);
|
||||
PackageUtil.AppSnippet as = getIntent()
|
||||
.getParcelableExtra(EXTRA_APP_SNIPPET, PackageUtil.AppSnippet.class);
|
||||
|
||||
mAlert.setIcon(as.icon);
|
||||
mAlert.setTitle(as.label);
|
||||
|
||||
@@ -22,7 +22,6 @@ import android.content.Intent;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
@@ -30,7 +29,6 @@ import android.widget.Button;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -65,18 +63,8 @@ public class InstallSuccess extends AlertActivity {
|
||||
ApplicationInfo appInfo =
|
||||
intent.getParcelableExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO);
|
||||
mAppPackageName = appInfo.packageName;
|
||||
Uri packageURI = intent.getData();
|
||||
|
||||
// Set header icon and title
|
||||
PackageManager pm = getPackageManager();
|
||||
|
||||
if ("package".equals(packageURI.getScheme())) {
|
||||
mAppSnippet = new PackageUtil.AppSnippet(pm.getApplicationLabel(appInfo),
|
||||
pm.getApplicationIcon(appInfo));
|
||||
} else {
|
||||
File sourceFile = new File(packageURI.getPath());
|
||||
mAppSnippet = PackageUtil.getAppSnippet(this, appInfo, sourceFile);
|
||||
}
|
||||
mAppSnippet = intent.getParcelableExtra(PackageInstallerActivity.EXTRA_APP_SNIPPET,
|
||||
PackageUtil.AppSnippet.class);
|
||||
|
||||
mLaunchIntent = getPackageManager().getLaunchIntentForPackage(mAppPackageName);
|
||||
|
||||
|
||||
@@ -84,6 +84,7 @@ public class PackageInstallerActivity extends AlertActivity {
|
||||
static final String EXTRA_CALLING_ATTRIBUTION_TAG = "EXTRA_CALLING_ATTRIBUTION_TAG";
|
||||
static final String EXTRA_ORIGINAL_SOURCE_INFO = "EXTRA_ORIGINAL_SOURCE_INFO";
|
||||
static final String EXTRA_STAGED_SESSION_ID = "EXTRA_STAGED_SESSION_ID";
|
||||
static final String EXTRA_APP_SNIPPET = "EXTRA_APP_SNIPPET";
|
||||
private static final String ALLOW_UNKNOWN_SOURCES_KEY =
|
||||
PackageInstallerActivity.class.getName() + "ALLOW_UNKNOWN_SOURCES_KEY";
|
||||
|
||||
@@ -708,6 +709,9 @@ public class PackageInstallerActivity extends AlertActivity {
|
||||
if (stagedSessionId > 0) {
|
||||
newIntent.putExtra(EXTRA_STAGED_SESSION_ID, stagedSessionId);
|
||||
}
|
||||
if (mAppSnippet != null) {
|
||||
newIntent.putExtra(EXTRA_APP_SNIPPET, mAppSnippet);
|
||||
}
|
||||
newIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
|
||||
if (mLocalLOGV) Log.i(TAG, "downloaded app uri=" + mPackageURI);
|
||||
startActivity(newIntent);
|
||||
|
||||
@@ -28,8 +28,13 @@ import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ProviderInfo;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
@@ -117,7 +122,7 @@ public class PackageUtil {
|
||||
icon);
|
||||
}
|
||||
|
||||
static final class AppSnippet {
|
||||
static final class AppSnippet implements Parcelable {
|
||||
@NonNull public CharSequence label;
|
||||
@Nullable public Drawable icon;
|
||||
public AppSnippet(@NonNull CharSequence label, @Nullable Drawable icon) {
|
||||
@@ -125,10 +130,52 @@ public class PackageUtil {
|
||||
this.icon = icon;
|
||||
}
|
||||
|
||||
private AppSnippet(Parcel in) {
|
||||
label = in.readString();
|
||||
Bitmap bmp = in.readParcelable(getClass().getClassLoader(), Bitmap.class);
|
||||
icon = new BitmapDrawable(Resources.getSystem(), bmp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AppSnippet[" + label + (icon != null ? "(has" : "(no ") + " icon)]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
dest.writeString(label.toString());
|
||||
Bitmap bmp = getBitmapFromDrawable(icon);
|
||||
dest.writeParcelable(bmp, 0);
|
||||
}
|
||||
|
||||
private Bitmap getBitmapFromDrawable(Drawable drawable) {
|
||||
// Create an empty bitmap with the dimensions of our drawable
|
||||
final Bitmap bmp = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
|
||||
drawable.getIntrinsicHeight(),
|
||||
Bitmap.Config.ARGB_8888);
|
||||
// Associate it with a canvas. This canvas will draw the icon on the bitmap
|
||||
final Canvas canvas = new Canvas(bmp);
|
||||
// Draw the drawable in the canvas. The canvas will ultimately paint the drawable in the
|
||||
// bitmap held within
|
||||
drawable.draw(canvas);
|
||||
|
||||
return bmp;
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<AppSnippet> CREATOR = new Parcelable.Creator<>() {
|
||||
public AppSnippet createFromParcel(Parcel in) {
|
||||
return new AppSnippet(in);
|
||||
}
|
||||
|
||||
public AppSnippet[] newArray(int size) {
|
||||
return new AppSnippet[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user