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

Commit dc7b7cc2 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Revert "Revert "Adds new atomic install API"""

parents eeca4f5a 0aff9b1d
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -11176,12 +11176,17 @@ package android.content.pm {
  public static class PackageInstaller.Session implements java.io.Closeable {
    method public void abandon();
    method public void addChildSessionId(int);
    method public void close();
    method public void commit(android.content.IntentSender);
    method public void fsync(java.io.OutputStream) throws java.io.IOException;
    method public int[] getChildSessionIds();
    method public java.lang.String[] getNames() throws java.io.IOException;
    method public int getParentSessionId();
    method public boolean isMultiPackage();
    method public java.io.InputStream openRead(java.lang.String) throws java.io.IOException;
    method public java.io.OutputStream openWrite(java.lang.String, long, long) throws java.io.IOException;
    method public void removeChildSessionId(int);
    method public void removeSplit(java.lang.String) throws java.io.IOException;
    method public void setStagingProgress(float);
    method public void transfer(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
@@ -11202,20 +11207,24 @@ package android.content.pm {
    method public android.graphics.Bitmap getAppIcon();
    method public java.lang.CharSequence getAppLabel();
    method public java.lang.String getAppPackageName();
    method public int[] getChildSessionIds();
    method public int getInstallLocation();
    method public int getInstallReason();
    method public java.lang.String getInstallerPackageName();
    method public int getMode();
    method public int getOriginatingUid();
    method public android.net.Uri getOriginatingUri();
    method public int getParentSessionId();
    method public float getProgress();
    method public android.net.Uri getReferrerUri();
    method public int getSessionId();
    method public long getSize();
    method public boolean isActive();
    method public boolean isMultiPackage();
    method public boolean isSealed();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.content.pm.PackageInstaller.SessionInfo> CREATOR;
    field public static final int INVALID_ID = -1; // 0xffffffff
  }
  public static class PackageInstaller.SessionParams implements android.os.Parcelable {
@@ -11226,6 +11235,7 @@ package android.content.pm {
    method public void setAppPackageName(java.lang.String);
    method public void setInstallLocation(int);
    method public void setInstallReason(int);
    method public void setMultiPackage();
    method public void setOriginatingUid(int);
    method public void setOriginatingUri(android.net.Uri);
    method public void setReferrerUri(android.net.Uri);
+5 −0
Original line number Diff line number Diff line
@@ -38,4 +38,9 @@ interface IPackageInstallerSession {
    void commit(in IntentSender statusReceiver, boolean forTransferred);
    void transfer(in String packageName);
    void abandon();
    boolean isMultiPackage();
    int[] getChildSessionIds();
    void addChildSessionId(in int sessionId);
    void removeChildSessionId(in int sessionId);
    int getParentSessionId();
}
+142 −4
Original line number Diff line number Diff line
@@ -364,13 +364,15 @@ public class PackageInstaller {
     *             the session is invalid.
     */
    public @NonNull Session openSession(int sessionId) throws IOException {
        try {
            try {
                return new Session(mInstaller.openSession(sessionId));
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        } catch (RuntimeException e) {
            ExceptionUtils.maybeUnwrapIOException(e);
            throw e;
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

@@ -769,9 +771,18 @@ public class PackageInstaller {
     * If an APK included in this session is already defined by the existing
     * installation (for example, the same split name), the APK in this session
     * will replace the existing APK.
     * <p>
     * In such a case that multiple packages need to be commited simultaneously,
     * multiple sessions can be referenced by a single multi-package session.
     * This session is created with no package name and calling
     * {@link SessionParams#setMultiPackage()} with {@code true}. The
     * individual session IDs can be added with {@link #addChildSessionId(int)}
     * and commit of the multi-package session will result in all child sessions
     * being committed atomically.
     */
    public static class Session implements Closeable {
        private IPackageInstallerSession mSession;
        /** {@hide} */
        protected final IPackageInstallerSession mSession;

        /** {@hide} */
        public Session(IPackageInstallerSession session) {
@@ -1080,6 +1091,71 @@ public class PackageInstaller {
                throw e.rethrowFromSystemServer();
            }
        }

        /**
         * @return {@code true} if this session will commit more than one package when it is
         * committed.
         */
        public boolean isMultiPackage() {
            try {
                return mSession.isMultiPackage();
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }

        /**
         * @return the session ID of the multi-package session that this belongs to or
         * {@link SessionInfo#INVALID_ID} if it does not belong to a multi-package session.
         */
        public int getParentSessionId() {
            try {
                return mSession.getParentSessionId();
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }

        /**
         * @return the set of session IDs that will be committed atomically when this session is
         * committed if this is a multi-package session or null if none exist.
         */
        @NonNull
        public int[] getChildSessionIds() {
            try {
                return mSession.getChildSessionIds();
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }

        /**
         * Adds a session ID to the set of sessions that will be committed atomically
         * when this session is committed.
         *
         * @param sessionId the session ID to add to this multi-package session.
         */
        public void addChildSessionId(int sessionId) {
            try {
                mSession.addChildSessionId(sessionId);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }

        /**
         * Removes a session ID from the set of sessions that will be committed
         * atomically when this session is committed.
         *
         * @param sessionId the session ID to remove from this multi-package session.
         */
        public void removeChildSessionId(int sessionId) {
            try {
                mSession.removeChildSessionId(sessionId);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }
    }

    /**
@@ -1149,6 +1225,8 @@ public class PackageInstaller {
        public String[] grantedRuntimePermissions;
        /** {@hide} */
        public String installerPackageName;
        /** {@hide} */
        public boolean isMultiPackage;

        /**
         * Construct parameters for a new package install session.
@@ -1178,6 +1256,7 @@ public class PackageInstaller {
            volumeUuid = source.readString();
            grantedRuntimePermissions = source.readStringArray();
            installerPackageName = source.readString();
            isMultiPackage = source.readBoolean();
        }

        /**
@@ -1392,6 +1471,18 @@ public class PackageInstaller {
            this.installerPackageName = installerPackageName;
        }

        /**
         * Set this session to be the parent of a multi-package install.
         *
         * A multi-package install session contains no APKs and only references other install
         * sessions via ID. When a multi-package session is committed, all of its children
         * are committed to the system in an atomic manner. If any children fail to install,
         * all of them do, including the multi-package session.
         */
        public void setMultiPackage() {
            this.isMultiPackage = true;
        }

        /** {@hide} */
        public void dump(IndentingPrintWriter pw) {
            pw.printPair("mode", mode);
@@ -1408,6 +1499,7 @@ public class PackageInstaller {
            pw.printPair("volumeUuid", volumeUuid);
            pw.printPair("grantedRuntimePermissions", grantedRuntimePermissions);
            pw.printPair("installerPackageName", installerPackageName);
            pw.printPair("isMultiPackage", isMultiPackage);
            pw.println();
        }

@@ -1433,6 +1525,7 @@ public class PackageInstaller {
            dest.writeString(volumeUuid);
            dest.writeStringArray(grantedRuntimePermissions);
            dest.writeString(installerPackageName);
            dest.writeBoolean(isMultiPackage);
        }

        public static final Parcelable.Creator<SessionParams>
@@ -1454,6 +1547,12 @@ public class PackageInstaller {
     */
    public static class SessionInfo implements Parcelable {

        /**
         * A session ID that does not exist or is invalid.
         */
        public static final int INVALID_ID = -1;
        /** {@hide} */
        private static final int[] NO_SESSIONS = {};
        /** {@hide} */
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
        public int sessionId;
@@ -1503,6 +1602,12 @@ public class PackageInstaller {
        public String[] grantedRuntimePermissions;
        /** {@hide} */
        public int installFlags;
        /** {@hide} */
        public boolean isMultiPackage;
        /** {@hide} */
        public int parentSessionId = INVALID_ID;
        /** {@hide} */
        public int[] childSessionIds = NO_SESSIONS;

        /** {@hide} */
        @UnsupportedAppUsage
@@ -1531,6 +1636,12 @@ public class PackageInstaller {
            referrerUri = source.readParcelable(null);
            grantedRuntimePermissions = source.readStringArray();
            installFlags = source.readInt();
            isMultiPackage = source.readBoolean();
            parentSessionId = source.readInt();
            childSessionIds = source.createIntArray();
            if (childSessionIds == null) {
                childSessionIds = NO_SESSIONS;
            }
        }

        /**
@@ -1784,6 +1895,30 @@ public class PackageInstaller {
            return createDetailsIntent();
        }

        /**
         * Returns true if this session is a multi-package session containing references to other
         * sessions.
         */
        public boolean isMultiPackage() {
            return isMultiPackage;
        }

        /**
         * Returns the parent multi-package session ID if this session belongs to one,
         * {@link #INVALID_ID} otherwise.
         */
        public int getParentSessionId() {
            return parentSessionId;
        }

        /**
         * Returns the set of session IDs that will be committed when this session is commited if
         * this session is a multi-package session.
         */
        public int[] getChildSessionIds() {
            return childSessionIds;
        }

        @Override
        public int describeContents() {
            return 0;
@@ -1811,6 +1946,9 @@ public class PackageInstaller {
            dest.writeParcelable(referrerUri, flags);
            dest.writeStringArray(grantedRuntimePermissions);
            dest.writeInt(installFlags);
            dest.writeBoolean(isMultiPackage);
            dest.writeInt(parentSessionId);
            dest.writeIntArray(childSessionIds);
        }

        public static final Parcelable.Creator<SessionInfo>
+5 −0
Original line number Diff line number Diff line
@@ -914,6 +914,11 @@ public abstract class PackageManager {
     */
    public static final int INSTALL_REASON_USER = 4;

    /**
     * @hide
     */
    public static final int INSTALL_UNKNOWN = 0;

    /**
     * Installation return code: this is passed in the {@link PackageInstaller#EXTRA_LEGACY_STATUS}
     * on success.
+89 −69
Original line number Diff line number Diff line
@@ -107,7 +107,9 @@ import java.util.List;
import java.util.Objects;
import java.util.Random;

public class PackageInstallerService extends IPackageInstaller.Stub {
/** The service responsible for installing packages. */
public class PackageInstallerService extends IPackageInstaller.Stub implements
        PackageSessionProvider {
    private static final String TAG = "PackageInstaller";
    private static final boolean LOGD = false;

@@ -296,6 +298,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub {
            in.setInput(fis, StandardCharsets.UTF_8.name());

            int type;
            PackageInstallerSession currentSession = null;
            while ((type = in.next()) != END_DOCUMENT) {
                if (type == START_TAG) {
                    final String tag = in.getName();
@@ -303,8 +306,10 @@ public class PackageInstallerService extends IPackageInstaller.Stub {
                        final PackageInstallerSession session;
                        try {
                            session = PackageInstallerSession.readFromXml(in, mInternalCallback,
                                    mContext, mPm, mInstallThread.getLooper(), mSessionsDir);
                                    mContext, mPm, mInstallThread.getLooper(), mSessionsDir, this);
                            currentSession = session;
                        } catch (Exception e) {
                            currentSession = null;
                            Slog.e(TAG, "Could not read session", e);
                            continue;
                        }
@@ -329,6 +334,10 @@ public class PackageInstallerService extends IPackageInstaller.Stub {
                            addHistoricalSessionLocked(session);
                        }
                        mAllocatedSessions.put(session.sessionId, true);
                    } else if (currentSession != null
                            && PackageInstallerSession.TAG_CHILD_SESSION.equals(tag)) {
                        currentSession.addChildSessionIdInternal(
                                PackageInstallerSession.readChildSessionIdFromXml(in));
                    }
                }
            }
@@ -436,6 +445,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub {
            }
        }

        if (!params.isMultiPackage) {
            // Only system components can circumvent runtime permissions when installing.
            if ((params.installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0
                    && mContext.checkCallingOrSelfPermission(Manifest.permission
@@ -502,6 +512,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub {
                    Binder.restoreCallingIdentity(ident);
                }
            }
        }

        final int sessionId;
        final PackageInstallerSession session;
@@ -525,6 +536,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub {
        // We're staging to exactly one location
        File stageDir = null;
        String stageCid = null;
        if (!params.isMultiPackage) {
            if ((params.installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
                final boolean isInstant =
                        (params.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
@@ -532,10 +544,11 @@ public class PackageInstallerService extends IPackageInstaller.Stub {
            } else {
                stageCid = buildExternalStageCid(sessionId);
            }

        session = new PackageInstallerSession(mInternalCallback, mContext, mPm,
                mInstallThread.getLooper(), sessionId, userId, installerPackageName, callingUid,
                params, createdMillis, stageDir, stageCid, false, false);
        }
        session = new PackageInstallerSession(mInternalCallback, mContext, mPm, this,
                mInstallThread.getLooper(), sessionId, userId, installerPackageName,
                callingUid, params, createdMillis, stageDir, stageCid, false, false, null,
                SessionInfo.INVALID_ID);

        synchronized (mSessions) {
            mSessions.put(sessionId, session);
@@ -678,7 +691,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub {
        synchronized (mSessions) {
            for (int i = 0; i < mSessions.size(); i++) {
                final PackageInstallerSession session = mSessions.valueAt(i);
                if (session.userId == userId) {
                if (session.userId == userId && !session.hasParentSessionId()) {
                    result.add(session.generateInfo(false));
                }
            }
@@ -699,7 +712,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub {

                SessionInfo info = session.generateInfo(false);
                if (Objects.equals(info.getInstallerPackageName(), installerPackageName)
                        && session.userId == userId) {
                        && session.userId == userId && !session.hasParentSessionId()) {
                    result.add(info);
                }
            }
@@ -781,6 +794,13 @@ public class PackageInstallerService extends IPackageInstaller.Stub {
        mCallbacks.unregister(callback);
    }

    @Override
    public PackageInstallerSession getSession(int sessionId) {
        synchronized (mSessions) {
            return mSessions.get(sessionId);
        }
    }

    private static int getSessionCount(SparseArray<PackageInstallerSession> sessions,
            int installerUid) {
        int count = 0;
Loading