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

Commit 0f836ce2 authored by JW Wang's avatar JW Wang Committed by Android (Google) Code Review
Browse files

Merge changes I1f4a2825,Ie8fe5e98,Ice304186

* changes:
  Rewrite some methods (3/n)
  Make #sendPendingStreaming a static method (2/n)
  Some code cleanup (1/n)
parents f806c211 82278d78
Loading
Loading
Loading
Loading
+120 −75
Original line number Diff line number Diff line
@@ -459,12 +459,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
                    final int returnCode = args.argi1;
                    args.recycle();

                    final boolean showNotification;
                    synchronized (mLock) {
                        showNotification = isInstallerDeviceOwnerOrAffiliatedProfileOwnerLocked();
                    }
                    sendOnPackageInstalled(mContext, statusReceiver, sessionId,
                            showNotification, userId,
                            isInstallerDeviceOwnerOrAffiliatedProfileOwner(), userId,
                            packageName, returnCode, message, extras);

                    break;
@@ -494,8 +490,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
    /**
     * @return {@code true} iff the installing is app an device owner or affiliated profile owner.
     */
    @GuardedBy("mLock")
    private boolean isInstallerDeviceOwnerOrAffiliatedProfileOwnerLocked() {
    private boolean isInstallerDeviceOwnerOrAffiliatedProfileOwner() {
        assertNotLocked("isInstallerDeviceOwnerOrAffiliatedProfileOwner");
        // It is safe to access mInstallerUid and mInstallSource without lock
        // because they are immutable after sealing.
        assertSealed("isInstallerDeviceOwnerOrAffiliatedProfileOwner");
        if (userId != UserHandle.getUserId(mInstallerUid)) {
            return false;
        }
@@ -513,12 +512,17 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
     *
     * @return {@code true} iff we need to ask to confirm the permissions?
     */
    @GuardedBy("mLock")
    private boolean needToAskForPermissionsLocked() {
    private boolean needToAskForPermissions() {
        final String packageName;
        synchronized (mLock) {
            if (mPermissionsManuallyAccepted) {
                return false;
            }
            packageName = mPackageName;
        }

        // It is safe to access mInstallerUid and mInstallSource without lock
        // because they are immutable after sealing.
        final boolean isInstallPermissionGranted =
                (mPm.checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES,
                        mInstallerUid) == PackageManager.PERMISSION_GRANTED);
@@ -528,7 +532,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
        final boolean isUpdatePermissionGranted =
                (mPm.checkUidPermission(android.Manifest.permission.INSTALL_PACKAGE_UPDATES,
                        mInstallerUid) == PackageManager.PERMISSION_GRANTED);
        final int targetPackageUid = mPm.getPackageUid(mPackageName, 0, userId);
        final int targetPackageUid = mPm.getPackageUid(packageName, 0, userId);
        final boolean isPermissionGranted = isInstallPermissionGranted
                || (isUpdatePermissionGranted && targetPackageUid != -1)
                || (isSelfUpdatePermissionGranted && targetPackageUid == mInstallerUid);
@@ -540,7 +544,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
        // Device owners and affiliated profile owners  are allowed to silently install packages, so
        // the permission check is waived if the installer is the device owner.
        return forcePermissionPrompt || !(isPermissionGranted || isInstallerRoot
                || isInstallerSystem || isInstallerDeviceOwnerOrAffiliatedProfileOwnerLocked());
                || isInstallerSystem || isInstallerDeviceOwnerOrAffiliatedProfileOwner());
    }

    public PackageInstallerSession(PackageInstallerService.InternalCallback callback,
@@ -740,6 +744,18 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
        }
    }

    private void assertNotLocked(String cookie) {
        if (Thread.holdsLock(mLock)) {
            throw new IllegalStateException(cookie + " is holding mLock");
        }
    }

    private void assertSealed(String cookie) {
        if (!isSealed()) {
            throw new IllegalStateException(cookie + " before sealing");
        }
    }

    @GuardedBy("mLock")
    private void assertPreparedAndNotSealedLocked(String cookie) {
        assertPreparedAndNotCommittedOrDestroyedLocked(cookie);
@@ -1693,11 +1709,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
    }

    private void handleInstall() {
        final boolean needsLogging;
        synchronized (mLock) {
            needsLogging = isInstallerDeviceOwnerOrAffiliatedProfileOwnerLocked();
        }
        if (needsLogging) {
        if (isInstallerDeviceOwnerOrAffiliatedProfileOwner()) {
            DevicePolicyEventLogger
                    .createEvent(DevicePolicyEnums.INSTALL_PACKAGE)
                    .setAdmin(mInstallSource.installerPackageName)
@@ -1724,9 +1736,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
        List<PackageInstallerSession> childSessions = getChildSessionsNotLocked();

        try {
            synchronized (mLock) {
                installNonStagedLocked(childSessions);
            }
            installNonStaged(childSessions);
        } catch (PackageManagerException e) {
            final String completeMsg = ExceptionUtils.getCompleteMessage(e);
            Slog.e(TAG, "Commit of session " + sessionId + " failed: " + completeMsg);
@@ -1735,11 +1745,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
        }
    }

    @GuardedBy("mLock")
    private void installNonStagedLocked(List<PackageInstallerSession> childSessions)
    private void installNonStaged(List<PackageInstallerSession> childSessions)
            throws PackageManagerException {
        final PackageManagerService.ActiveInstallSession installingSession =
                makeSessionActiveLocked();
                makeSessionActive();
        if (installingSession == null) {
            return;
        }
@@ -1752,7 +1761,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
                final PackageInstallerSession session = childSessions.get(i);
                try {
                    final PackageManagerService.ActiveInstallSession installingChildSession =
                            session.makeSessionActiveLocked();
                            session.makeSessionActive();
                    if (installingChildSession != null) {
                        installingChildSessions.add(installingChildSession);
                    }
@@ -1762,8 +1771,12 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
                }
            }
            if (!success) {
                sendOnPackageInstalled(mContext, mRemoteStatusReceiver, sessionId,
                        isInstallerDeviceOwnerOrAffiliatedProfileOwnerLocked(), userId, null,
                final IntentSender statusReceiver;
                synchronized (mLock) {
                    statusReceiver = mRemoteStatusReceiver;
                }
                sendOnPackageInstalled(mContext, statusReceiver, sessionId,
                        isInstallerDeviceOwnerOrAffiliatedProfileOwner(), userId, null,
                        failure.error, failure.getLocalizedMessage(), null);
                return;
            }
@@ -1778,26 +1791,26 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
     * {@link PackageManagerService.ActiveInstallSession} representing this new staged state or null
     * in case permissions need to be requested before install can proceed.
     */
    @GuardedBy("mLock")
    private PackageManagerService.ActiveInstallSession makeSessionActiveLocked()
    private PackageManagerService.ActiveInstallSession makeSessionActive()
            throws PackageManagerException {
        assertNotLocked("makeSessionActive");

        synchronized (mLock) {
            if (mRelinquished) {
                throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
                        "Session relinquished");
            }
            if (mDestroyed) {
            throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, "Session destroyed");
                throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
                        "Session destroyed");
            }
            if (!mSealed) {
            throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, "Session not sealed");
                throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
                        "Session not sealed");
            }
        }

        if (!params.isMultiPackage) {
            Objects.requireNonNull(mPackageName);
            Objects.requireNonNull(mSigningDetails);
            Objects.requireNonNull(mResolvedBaseFile);

            if (needToAskForPermissionsLocked()) {
        if (!params.isMultiPackage && needToAskForPermissions()) {
            // User needs to confirm installation;
            // give installer an intent they can use to involve
            // user.
@@ -1805,7 +1818,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
            intent.setPackage(mPm.getPackageInstallerPackageName());
            intent.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId);

                sendOnUserActionRequired(mContext, mRemoteStatusReceiver, sessionId, intent);
            final IntentSender statusReceiver;
            synchronized (mLock) {
                statusReceiver = mRemoteStatusReceiver;
            }
            sendOnUserActionRequired(mContext, statusReceiver, sessionId, intent);

            // Commit was keeping session marked as active until now; release
            // that extra refcount so session appears idle.
@@ -1813,6 +1830,19 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
            return null;
        }

        synchronized (mLock) {
            return makeSessionActiveLocked();
        }
    }

    @GuardedBy("mLock")
    private PackageManagerService.ActiveInstallSession makeSessionActiveLocked()
            throws PackageManagerException {
        if (!params.isMultiPackage) {
            Objects.requireNonNull(mPackageName);
            Objects.requireNonNull(mSigningDetails);
            Objects.requireNonNull(mResolvedBaseFile);

            // Inherit any packages and native libraries from existing install that
            // haven't been overridden.
            if (params.mode == SessionParams.MODE_INHERIT_EXISTING) {
@@ -2438,7 +2468,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
     * Determine if creating hard links between source and destination is
     * possible. That is, do they all live on the same underlying device.
     */
    private boolean isLinkPossible(List<File> fromFiles, File toDir) {
    private static boolean isLinkPossible(List<File> fromFiles, File toDir) {
        try {
            final StructStat toStat = Os.stat(toDir.getAbsolutePath());
            for (File fromFile : fromFiles) {
@@ -2915,7 +2945,12 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
                        }
                        case IDataLoaderStatusListener.DATA_LOADER_UNAVAILABLE: {
                            // Don't fail or commit the session. Allow caller to commit again.
                            sendPendingStreaming("DataLoader unavailable");
                            final IntentSender statusReceiver;
                            synchronized (mLock) {
                                statusReceiver = mRemoteStatusReceiver;
                            }
                            sendPendingStreaming(mContext, statusReceiver, sessionId,
                                    "DataLoader unavailable");
                            break;
                        }
                        case IDataLoaderStatusListener.DATA_LOADER_UNRECOVERABLE:
@@ -2929,7 +2964,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
                } catch (RemoteException e) {
                    // In case of streaming failure we don't want to fail or commit the session.
                    // Just return from this method and allow caller to commit again.
                    sendPendingStreaming(e.getMessage());
                    final IntentSender statusReceiver;
                    synchronized (mLock) {
                        statusReceiver = mRemoteStatusReceiver;
                    }
                    sendPendingStreaming(mContext, statusReceiver, sessionId, e.getMessage());
                }
            }
        };
@@ -3004,16 +3043,17 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
                detailMessage).sendToTarget();
    }

    @GuardedBy("mLock")
    private int[] getChildSessionIdsLocked() {
        final int[] childSessionIds = mChildSessionIds.copyKeys();
        return childSessionIds != null ? childSessionIds : EMPTY_CHILD_SESSION_ARRAY;
    }

    @Override
    public int[] getChildSessionIds() {
        final int[] childSessionIds;
        synchronized (mLock) {
            childSessionIds = mChildSessionIds.copyKeys();
            return getChildSessionIdsLocked();
        }
        if (childSessionIds != null) {
            return childSessionIds;
        }
        return EMPTY_CHILD_SESSION_ARRAY;
    }

    private boolean canBeAddedAsChild(int parentCandidate) {
@@ -3323,6 +3363,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
        pw.decreaseIndent();
    }

    /**
     * This method doesn't change internal states and is safe to call outside the lock.
     */
    private static void sendOnUserActionRequired(Context context, IntentSender target,
            int sessionId, Intent intent) {
        final Intent fillIn = new Intent();
@@ -3335,6 +3378,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
        }
    }

    /**
     * This method doesn't change internal states and is safe to call outside the lock.
     */
    private static void sendOnPackageInstalled(Context context, IntentSender target, int sessionId,
            boolean showNotification, int userId, String basePackageName, int returnCode,
            String msg, Bundle extras) {
@@ -3375,13 +3421,12 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
        }
    }

    private void sendPendingStreaming(@Nullable String cause) {
        final IntentSender statusReceiver;
        synchronized (mLock) {
            statusReceiver = mRemoteStatusReceiver;
        }

        if (statusReceiver == null) {
    /**
     * This method doesn't change internal states and is safe to call outside the lock.
     */
    private static void sendPendingStreaming(Context context, IntentSender target, int sessionId,
            @Nullable String cause) {
        if (target == null) {
            Slog.e(TAG, "Missing receiver for pending streaming status.");
            return;
        }
@@ -3396,7 +3441,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
            intent.putExtra(PackageInstaller.EXTRA_STATUS_MESSAGE, "Staging Image Not Ready");
        }
        try {
            statusReceiver.sendIntent(mContext, 0, intent, null, null);
            target.sendIntent(context, 0, intent, null, null);
        } catch (IntentSender.SendIntentException ignored) {
        }
    }
@@ -3470,10 +3515,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
            if (stageCid != null) {
                writeStringAttribute(out, ATTR_SESSION_STAGE_CID, stageCid);
            }
            writeBooleanAttribute(out, ATTR_PREPARED, isPrepared());
            writeBooleanAttribute(out, ATTR_COMMITTED, isCommitted());
            writeBooleanAttribute(out, ATTR_DESTROYED, isDestroyed());
            writeBooleanAttribute(out, ATTR_SEALED, isSealed());
            writeBooleanAttribute(out, ATTR_PREPARED, mPrepared);
            writeBooleanAttribute(out, ATTR_COMMITTED, mCommitted);
            writeBooleanAttribute(out, ATTR_DESTROYED, mDestroyed);
            writeBooleanAttribute(out, ATTR_SEALED, mSealed);

            writeBooleanAttribute(out, ATTR_MULTI_PACKAGE, params.isMultiPackage);
            writeBooleanAttribute(out, ATTR_STAGED_SESSION, params.isStaged);
@@ -3535,7 +3580,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {

                params.appIconLastModified = appIconFile.lastModified();
            }
            final int[] childSessionIds = getChildSessionIds();
            final int[] childSessionIds = getChildSessionIdsLocked();
            for (int childSessionId : childSessionIds) {
                out.startTag(null, TAG_CHILD_SESSION);
                writeIntAttribute(out, ATTR_SESSION_ID, childSessionId);
@@ -3543,7 +3588,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
            }

            final InstallationFile[] files = getInstallationFilesLocked();
            for (InstallationFile file : getInstallationFilesLocked()) {
            for (InstallationFile file : files) {
                out.startTag(null, TAG_SESSION_FILE);
                writeIntAttribute(out, ATTR_LOCATION, file.getLocation());
                writeStringAttribute(out, ATTR_NAME, file.getName());