Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 719d00a9 authored by Sumedh Sen's avatar Sumedh Sen
Browse files

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
parent 8a77a846
Loading
Loading
Loading
Loading
+2 −10
Original line number Original line Diff line number Diff line
@@ -33,8 +33,6 @@ import android.view.View;


import androidx.annotation.Nullable;
import androidx.annotation.Nullable;


import java.io.File;

/**
/**
 * Installation failed: Return status code to the caller or display failure UI to user
 * 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
            // Set header icon and title
            PackageUtil.AppSnippet as;
            PackageUtil.AppSnippet as;
            PackageManager pm = getPackageManager();
            PackageManager pm = getPackageManager();

            as = intent.getParcelableExtra(PackageInstallerActivity.EXTRA_APP_SNIPPET,
            if ("package".equals(packageURI.getScheme())) {
                    PackageUtil.AppSnippet.class);
                as = new PackageUtil.AppSnippet(pm.getApplicationLabel(appInfo),
                        pm.getApplicationIcon(appInfo));
            } else {
                final File sourceFile = new File(packageURI.getPath());
                as = PackageUtil.getAppSnippet(this, appInfo, sourceFile);
            }


            // Store label for dialog
            // Store label for dialog
            mLabel = as.label;
            mLabel = as.label;
+3 −1
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@


package com.android.packageinstaller;
package com.android.packageinstaller;


import static com.android.packageinstaller.PackageInstallerActivity.EXTRA_APP_SNIPPET;
import static com.android.packageinstaller.PackageInstallerActivity.EXTRA_STAGED_SESSION_ID;
import static com.android.packageinstaller.PackageInstallerActivity.EXTRA_STAGED_SESSION_ID;


import android.app.PendingIntent;
import android.app.PendingIntent;
@@ -86,7 +87,8 @@ public class InstallInstalling extends AlertActivity {
            // ContentResolver.SCHEME_FILE
            // ContentResolver.SCHEME_FILE
            // STAGED_SESSION_ID extra contains an ID of a previously staged install session.
            // STAGED_SESSION_ID extra contains an ID of a previously staged install session.
            final File sourceFile = new File(mPackageURI.getPath());
            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.setIcon(as.icon);
            mAlert.setTitle(as.label);
            mAlert.setTitle(as.label);
+2 −14
Original line number Original line Diff line number Diff line
@@ -22,7 +22,6 @@ import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Bundle;
import android.os.Bundle;
import android.util.Log;
import android.util.Log;
import android.view.View;
import android.view.View;
@@ -30,7 +29,6 @@ import android.widget.Button;


import androidx.annotation.Nullable;
import androidx.annotation.Nullable;


import java.io.File;
import java.util.List;
import java.util.List;


/**
/**
@@ -65,18 +63,8 @@ public class InstallSuccess extends AlertActivity {
            ApplicationInfo appInfo =
            ApplicationInfo appInfo =
                    intent.getParcelableExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO);
                    intent.getParcelableExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO);
            mAppPackageName = appInfo.packageName;
            mAppPackageName = appInfo.packageName;
            Uri packageURI = intent.getData();
            mAppSnippet = intent.getParcelableExtra(PackageInstallerActivity.EXTRA_APP_SNIPPET,

                    PackageUtil.AppSnippet.class);
            // 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);
            }


            mLaunchIntent = getPackageManager().getLaunchIntentForPackage(mAppPackageName);
            mLaunchIntent = getPackageManager().getLaunchIntentForPackage(mAppPackageName);


+4 −0
Original line number Original line Diff line number Diff line
@@ -84,6 +84,7 @@ public class PackageInstallerActivity extends AlertActivity {
    static final String EXTRA_CALLING_ATTRIBUTION_TAG = "EXTRA_CALLING_ATTRIBUTION_TAG";
    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_ORIGINAL_SOURCE_INFO = "EXTRA_ORIGINAL_SOURCE_INFO";
    static final String EXTRA_STAGED_SESSION_ID = "EXTRA_STAGED_SESSION_ID";
    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 =
    private static final String ALLOW_UNKNOWN_SOURCES_KEY =
            PackageInstallerActivity.class.getName() + "ALLOW_UNKNOWN_SOURCES_KEY";
            PackageInstallerActivity.class.getName() + "ALLOW_UNKNOWN_SOURCES_KEY";


@@ -708,6 +709,9 @@ public class PackageInstallerActivity extends AlertActivity {
        if (stagedSessionId > 0) {
        if (stagedSessionId > 0) {
            newIntent.putExtra(EXTRA_STAGED_SESSION_ID, stagedSessionId);
            newIntent.putExtra(EXTRA_STAGED_SESSION_ID, stagedSessionId);
        }
        }
        if (mAppSnippet != null) {
            newIntent.putExtra(EXTRA_APP_SNIPPET, mAppSnippet);
        }
        newIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
        newIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
        if (mLocalLOGV) Log.i(TAG, "downloaded app uri=" + mPackageURI);
        if (mLocalLOGV) Log.i(TAG, "downloaded app uri=" + mPackageURI);
        startActivity(newIntent);
        startActivity(newIntent);
+48 −1
Original line number Original line Diff line number Diff line
@@ -28,8 +28,13 @@ import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
import android.content.pm.ProviderInfo;
import android.content.res.Resources;
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.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.UserHandle;
import android.os.UserHandle;
import android.util.Log;
import android.util.Log;
import android.view.View;
import android.view.View;
@@ -117,7 +122,7 @@ public class PackageUtil {
                icon);
                icon);
    }
    }


    static final class AppSnippet {
    static final class AppSnippet implements Parcelable {
        @NonNull public CharSequence label;
        @NonNull public CharSequence label;
        @Nullable public Drawable icon;
        @Nullable public Drawable icon;
        public AppSnippet(@NonNull CharSequence label, @Nullable Drawable icon) {
        public AppSnippet(@NonNull CharSequence label, @Nullable Drawable icon) {
@@ -125,10 +130,52 @@ public class PackageUtil {
            this.icon = icon;
            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
        @Override
        public String toString() {
        public String toString() {
            return "AppSnippet[" + label + (icon != null ? "(has" : "(no ") + " icon)]";
            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];
            }
        };
    }
    }


    /**
    /**