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

Commit a15f2080 authored by Alex Buynytskyy's avatar Alex Buynytskyy
Browse files

Public API for Install Archived.

Bug: 297916136
Test: adb shell device_config put package_manager_service android.content.pm.archiving true && atest PackageManagerTest
Test: adb shell device_config put package_manager_service android.content.pm.archiving false && atest PackageManagerTest

Change-Id: Icb57c73f4ccb376b5e88d92fea29f21d0e166d1e
parent d01c2a56
Loading
Loading
Loading
Loading
+37 −1
Original line number Diff line number Diff line
@@ -11101,7 +11101,7 @@ package android.content {
    field public static final String EXTRA_ALLOW_MULTIPLE = "android.intent.extra.ALLOW_MULTIPLE";
    field @Deprecated public static final String EXTRA_ALLOW_REPLACE = "android.intent.extra.ALLOW_REPLACE";
    field public static final String EXTRA_ALTERNATE_INTENTS = "android.intent.extra.ALTERNATE_INTENTS";
    field public static final String EXTRA_ARCHIVAL = "android.intent.extra.ARCHIVAL";
    field @FlaggedApi("android.content.pm.archiving") public static final String EXTRA_ARCHIVAL = "android.intent.extra.ARCHIVAL";
    field public static final String EXTRA_ASSIST_CONTEXT = "android.intent.extra.ASSIST_CONTEXT";
    field public static final String EXTRA_ASSIST_INPUT_DEVICE_ID = "android.intent.extra.ASSIST_INPUT_DEVICE_ID";
    field public static final String EXTRA_ASSIST_INPUT_HINT_KEYBOARD = "android.intent.extra.ASSIST_INPUT_HINT_KEYBOARD";
@@ -11988,6 +11988,40 @@ package android.content.pm {
    method public final int compare(android.content.pm.ApplicationInfo, android.content.pm.ApplicationInfo);
  }
  @FlaggedApi("android.content.pm.archiving") public final class ArchivedActivity {
    ctor public ArchivedActivity(@NonNull CharSequence, @NonNull android.content.ComponentName);
    method @NonNull public android.content.ComponentName getComponentName();
    method @Nullable public android.graphics.drawable.Drawable getIcon();
    method @NonNull public CharSequence getLabel();
    method @Nullable public android.graphics.drawable.Drawable getMonochromeIcon();
    method @NonNull public android.content.pm.ArchivedActivity setComponentName(@NonNull android.content.ComponentName);
    method @NonNull public android.content.pm.ArchivedActivity setIcon(@NonNull android.graphics.drawable.Drawable);
    method @NonNull public android.content.pm.ArchivedActivity setLabel(@NonNull CharSequence);
    method @NonNull public android.content.pm.ArchivedActivity setMonochromeIcon(@NonNull android.graphics.drawable.Drawable);
  }
  @FlaggedApi("android.content.pm.archiving") public final class ArchivedPackage {
    ctor public ArchivedPackage(@NonNull String, @NonNull android.content.pm.SigningInfo, @NonNull java.util.List<android.content.pm.ArchivedActivity>);
    method @Nullable public String getDefaultToDeviceProtectedStorage();
    method @NonNull public java.util.List<android.content.pm.ArchivedActivity> getLauncherActivities();
    method @NonNull public String getPackageName();
    method @Nullable public String getRequestLegacyExternalStorage();
    method @NonNull public android.content.pm.SigningInfo getSigningInfo();
    method public int getTargetSdkVersion();
    method @Nullable public String getUserDataFragile();
    method public int getVersionCode();
    method public int getVersionCodeMajor();
    method @NonNull public android.content.pm.ArchivedPackage setDefaultToDeviceProtectedStorage(@NonNull String);
    method @NonNull public android.content.pm.ArchivedPackage setLauncherActivities(@NonNull java.util.List<android.content.pm.ArchivedActivity>);
    method @NonNull public android.content.pm.ArchivedPackage setPackageName(@NonNull String);
    method @NonNull public android.content.pm.ArchivedPackage setRequestLegacyExternalStorage(@NonNull String);
    method @NonNull public android.content.pm.ArchivedPackage setSigningInfo(@NonNull android.content.pm.SigningInfo);
    method @NonNull public android.content.pm.ArchivedPackage setTargetSdkVersion(int);
    method @NonNull public android.content.pm.ArchivedPackage setUserDataFragile(@NonNull String);
    method @NonNull public android.content.pm.ArchivedPackage setVersionCode(int);
    method @NonNull public android.content.pm.ArchivedPackage setVersionCodeMajor(int);
  }
  public final class Attribution implements android.os.Parcelable {
    method public int describeContents();
    method @IdRes public int getLabel();
@@ -12320,6 +12354,7 @@ package android.content.pm {
    method @Nullable public android.content.pm.PackageInstaller.SessionInfo getSessionInfo(int);
    method @NonNull public java.util.List<android.content.pm.PackageInstaller.SessionInfo> getStagedSessions();
    method @RequiresPermission(allOf={android.Manifest.permission.INSTALL_PACKAGES, "com.android.permission.INSTALL_EXISTING_PACKAGES"}) public void installExistingPackage(@NonNull String, int, @Nullable android.content.IntentSender);
    method @FlaggedApi("android.content.pm.archiving") @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void installPackageArchived(@NonNull android.content.pm.ArchivedPackage, @NonNull android.content.pm.PackageInstaller.SessionParams, @NonNull android.content.IntentSender);
    method @NonNull public android.content.pm.PackageInstaller.Session openSession(int) throws java.io.IOException;
    method public void registerSessionCallback(@NonNull android.content.pm.PackageInstaller.SessionCallback);
    method public void registerSessionCallback(@NonNull android.content.pm.PackageInstaller.SessionCallback, @NonNull android.os.Handler);
@@ -12601,6 +12636,7 @@ package android.content.pm {
    method @NonNull public abstract CharSequence getApplicationLabel(@NonNull android.content.pm.ApplicationInfo);
    method @Nullable public abstract android.graphics.drawable.Drawable getApplicationLogo(@NonNull android.content.pm.ApplicationInfo);
    method @Nullable public abstract android.graphics.drawable.Drawable getApplicationLogo(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException;
    method @FlaggedApi("android.content.pm.archiving") @Nullable public android.content.pm.ArchivedPackage getArchivedPackage(@NonNull String);
    method @NonNull public CharSequence getBackgroundPermissionOptionLabel();
    method @Nullable public abstract android.content.pm.ChangedPackages getChangedPackages(@IntRange(from=0) int);
    method public abstract int getComponentEnabledSetting(@NonNull android.content.ComponentName);
+14 −0
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ import android.content.IntentSender;
import android.content.pm.ActivityInfo;
import android.content.pm.ApkChecksum;
import android.content.pm.ApplicationInfo;
import android.content.pm.ArchivedPackage;
import android.content.pm.ChangedPackages;
import android.content.pm.Checksum;
import android.content.pm.ComponentInfo;
@@ -3935,6 +3936,19 @@ public class ApplicationPackageManager extends PackageManager {
        }
    }

    @Override
    public @Nullable ArchivedPackage getArchivedPackage(@NonNull String packageName) {
        try {
            var parcel = mPM.getArchivedPackage(packageName, mContext.getUserId());
            if (parcel == null) {
                return null;
            }
            return new ArchivedPackage(parcel);
        } catch (RemoteException e) {
            throw e.rethrowAsRuntimeException();
        }
    }

    @Override
    public boolean canUserUninstall(String packageName, UserHandle user) {
        try {
+1 −0
Original line number Diff line number Diff line
@@ -6340,6 +6340,7 @@ public class Intent implements Parcelable, Cloneable {
     * the package is being archived. Either by removing the existing APK, or by installing
     * a package without an APK.
     */
    @FlaggedApi(android.content.pm.Flags.FLAG_ARCHIVING)
    public static final String EXTRA_ARCHIVAL = "android.intent.extra.ARCHIVAL";
    /**
+246 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.content.pm;

import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ComponentName;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;

import com.android.internal.util.DataClass;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Objects;

@DataClass(genBuilder = false, genConstructor = false, genSetters = true)
@FlaggedApi(Flags.FLAG_ARCHIVING)
public final class ArchivedActivity {
    /** The label for the activity. */
    private @NonNull CharSequence mLabel;
    /** The component name of this activity. */
    private @NonNull ComponentName mComponentName;
    /**
     * Icon of the activity in the app's locale. if null then the default icon would be shown in the
     * launcher.
     */
    private @Nullable Drawable mIcon;
    /** Monochrome icon, if defined, of the activity. */
    private @Nullable Drawable mMonochromeIcon;

    public ArchivedActivity(@NonNull CharSequence label, @NonNull ComponentName componentName) {
        Objects.requireNonNull(label);
        Objects.requireNonNull(componentName);
        mLabel = label;
        mComponentName = componentName;
    }

    /* @hide */
    ArchivedActivity(@NonNull ArchivedActivityParcel parcel) {
        mLabel = parcel.title;
        mComponentName = parcel.originalComponentName;
        mIcon = drawableFromCompressedBitmap(parcel.iconBitmap);
        mMonochromeIcon = drawableFromCompressedBitmap(parcel.monochromeIconBitmap);
    }

    /* @hide */
    @NonNull ArchivedActivityParcel getParcel() {
        var parcel = new ArchivedActivityParcel();
        parcel.title = mLabel.toString();
        parcel.originalComponentName = mComponentName;
        parcel.iconBitmap = mIcon == null ? null :
                bytesFromBitmap(drawableToBitmap(mIcon));
        parcel.monochromeIconBitmap = mMonochromeIcon == null ? null :
                bytesFromBitmap(drawableToBitmap(mMonochromeIcon));
        return parcel;
    }

    /**
     * Convert a generic drawable into a bitmap.
     * @hide
     */
    public static Bitmap drawableToBitmap(Drawable drawable) {
        return drawableToBitmap(drawable, /* maxIconSize= */ Integer.MAX_VALUE);
    }

    /**
     * Same as above, but.
     * @hide
     */
    public static Bitmap drawableToBitmap(Drawable drawable, int maxIconSize) {
        if (drawable instanceof BitmapDrawable) {
            return ((BitmapDrawable) drawable).getBitmap();

        }

        Bitmap bitmap;
        if (drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) {
            // Needed for drawables that are just a single color.
            bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
        } else {
            bitmap =
                    Bitmap.createBitmap(
                            drawable.getIntrinsicWidth(),
                            drawable.getIntrinsicHeight(),
                            Bitmap.Config.ARGB_8888);
        }
        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
        drawable.draw(canvas);
        if (bitmap.getWidth() > maxIconSize || bitmap.getHeight() > maxIconSize) {
            var scaledBitmap = Bitmap.createScaledBitmap(bitmap, maxIconSize, maxIconSize, true);
            if (scaledBitmap != bitmap) {
                bitmap.recycle();
            }
            return scaledBitmap;
        }
        return bitmap;
    }

    /**
     * Compress bitmap to PNG format.
     * The bitmap is going to be recycled.
     * @hide
     */
    public static byte[] bytesFromBitmap(Bitmap bitmap) {
        if (bitmap == null) {
            return null;
        }

        try (ByteArrayOutputStream baos = new ByteArrayOutputStream(
                bitmap.getByteCount())) {
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
            return baos.toByteArray();
        } catch (IOException ignored) {
            return null;
        }
    }

    private static Drawable drawableFromCompressedBitmap(byte[] bytes) {
        if (bytes == null) {
            return null;
        }
        return new BitmapDrawable(null /*res*/, new ByteArrayInputStream(bytes));
    }



    // Code below generated by codegen v1.0.23.
    //
    // DO NOT MODIFY!
    // CHECKSTYLE:OFF Generated code
    //
    // To regenerate run:
    // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/content/pm/ArchivedActivity.java
    //
    // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
    //   Settings > Editor > Code Style > Formatter Control
    //@formatter:off


    /**
     * The label for the activity.
     */
    @DataClass.Generated.Member
    public @NonNull CharSequence getLabel() {
        return mLabel;
    }

    /**
     * The component name of this activity.
     */
    @DataClass.Generated.Member
    public @NonNull ComponentName getComponentName() {
        return mComponentName;
    }

    /**
     * Icon of the activity in the app's locale. if null then the default icon would be shown in the
     * launcher.
     */
    @DataClass.Generated.Member
    public @Nullable Drawable getIcon() {
        return mIcon;
    }

    /**
     * Monochrome icon, if defined, of the activity.
     */
    @DataClass.Generated.Member
    public @Nullable Drawable getMonochromeIcon() {
        return mMonochromeIcon;
    }

    /**
     * The label for the activity.
     */
    @DataClass.Generated.Member
    public @NonNull ArchivedActivity setLabel(@NonNull CharSequence value) {
        mLabel = value;
        com.android.internal.util.AnnotationValidations.validate(
                NonNull.class, null, mLabel);
        return this;
    }

    /**
     * The component name of this activity.
     */
    @DataClass.Generated.Member
    public @NonNull ArchivedActivity setComponentName(@NonNull ComponentName value) {
        mComponentName = value;
        com.android.internal.util.AnnotationValidations.validate(
                NonNull.class, null, mComponentName);
        return this;
    }

    /**
     * Icon of the activity in the app's locale. if null then the default icon would be shown in the
     * launcher.
     */
    @DataClass.Generated.Member
    public @NonNull ArchivedActivity setIcon(@NonNull Drawable value) {
        mIcon = value;
        return this;
    }

    /**
     * Monochrome icon, if defined, of the activity.
     */
    @DataClass.Generated.Member
    public @NonNull ArchivedActivity setMonochromeIcon(@NonNull Drawable value) {
        mMonochromeIcon = value;
        return this;
    }

    @DataClass.Generated(
            time = 1698173429911L,
            codegenVersion = "1.0.23",
            sourceFile = "frameworks/base/core/java/android/content/pm/ArchivedActivity.java",
            inputSignatures = "private @android.annotation.NonNull java.lang.CharSequence mLabel\nprivate @android.annotation.NonNull android.content.ComponentName mComponentName\nprivate @android.annotation.Nullable android.graphics.drawable.Drawable mIcon\nprivate @android.annotation.Nullable android.graphics.drawable.Drawable mMonochromeIcon\n @android.annotation.NonNull android.content.pm.ArchivedActivityParcel getParcel()\npublic static  android.graphics.Bitmap drawableToBitmap(android.graphics.drawable.Drawable)\npublic static  android.graphics.Bitmap drawableToBitmap(android.graphics.drawable.Drawable,int)\npublic static  byte[] bytesFromBitmap(android.graphics.Bitmap)\nprivate static  android.graphics.drawable.Drawable drawableFromCompressedBitmap(byte[])\nclass ArchivedActivity extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genBuilder=false, genConstructor=false, genSetters=true)")
    @Deprecated
    private void __metadata() {}


    //@formatter:on
    // End of generated code

}
+344 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading