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

Commit 2ea086d3 authored by Songchun Fan's avatar Songchun Fan
Browse files

[pm/incremental] disable unstartable state and hide related APIs

Per discussions in go/incremental-when-to-freeze, we will not mark an
app unstartable, regarless of streaming health metrics.

This CL is a temporary disablement. The startable state will remain true,
and there will be no broadcasts about startability.

The event tracking and health monitoring is kept as is.

If we get feedback and need to put it back, it'll be a small change.
Otherwise, we will clean up the related code.

+ also fix storage health monitoring params

BUG: 171920377
Test: builds
Change-Id: Idf7d32d0ca3a6e08c9673914f27f22b531b91ac2
parent 68ef6737
Loading
Loading
Loading
Loading
+0 −5
Original line number Diff line number Diff line
@@ -10683,8 +10683,6 @@ package android.content {
    field public static final String ACTION_PACKAGE_REMOVED = "android.intent.action.PACKAGE_REMOVED";
    field public static final String ACTION_PACKAGE_REPLACED = "android.intent.action.PACKAGE_REPLACED";
    field public static final String ACTION_PACKAGE_RESTARTED = "android.intent.action.PACKAGE_RESTARTED";
    field public static final String ACTION_PACKAGE_STARTABLE = "android.intent.action.PACKAGE_STARTABLE";
    field public static final String ACTION_PACKAGE_UNSTARTABLE = "android.intent.action.PACKAGE_UNSTARTABLE";
    field public static final String ACTION_PACKAGE_VERIFIED = "android.intent.action.PACKAGE_VERIFIED";
    field public static final String ACTION_PASTE = "android.intent.action.PASTE";
    field public static final String ACTION_PICK = "android.intent.action.PICK";
@@ -12312,9 +12310,6 @@ package android.content.pm {
    field public static final int SYNCHRONOUS = 2; // 0x2
    field @Nullable public static final java.util.List<java.security.cert.Certificate> TRUST_ALL;
    field @NonNull public static final java.util.List<java.security.cert.Certificate> TRUST_NONE;
    field public static final int UNSTARTABLE_REASON_CONNECTION_ERROR = 1; // 0x1
    field public static final int UNSTARTABLE_REASON_INSUFFICIENT_STORAGE = 2; // 0x2
    field public static final int UNSTARTABLE_REASON_UNKNOWN = 0; // 0x0
    field public static final int VERIFICATION_ALLOW = 1; // 0x1
    field public static final int VERIFICATION_REJECT = -1; // 0xffffffff
    field public static final int VERSION_CODE_HIGHEST = -1; // 0xffffffff
+0 −5
Original line number Diff line number Diff line
@@ -10683,8 +10683,6 @@ package android.content {
    field public static final String ACTION_PACKAGE_REMOVED = "android.intent.action.PACKAGE_REMOVED";
    field public static final String ACTION_PACKAGE_REPLACED = "android.intent.action.PACKAGE_REPLACED";
    field public static final String ACTION_PACKAGE_RESTARTED = "android.intent.action.PACKAGE_RESTARTED";
    field public static final String ACTION_PACKAGE_STARTABLE = "android.intent.action.PACKAGE_STARTABLE";
    field public static final String ACTION_PACKAGE_UNSTARTABLE = "android.intent.action.PACKAGE_UNSTARTABLE";
    field public static final String ACTION_PACKAGE_VERIFIED = "android.intent.action.PACKAGE_VERIFIED";
    field public static final String ACTION_PASTE = "android.intent.action.PASTE";
    field public static final String ACTION_PICK = "android.intent.action.PICK";
@@ -12312,9 +12310,6 @@ package android.content.pm {
    field public static final int SYNCHRONOUS = 2; // 0x2
    field @Nullable public static final java.util.List<java.security.cert.Certificate> TRUST_ALL;
    field @NonNull public static final java.util.List<java.security.cert.Certificate> TRUST_NONE;
    field public static final int UNSTARTABLE_REASON_CONNECTION_ERROR = 1; // 0x1
    field public static final int UNSTARTABLE_REASON_INSUFFICIENT_STORAGE = 2; // 0x2
    field public static final int UNSTARTABLE_REASON_UNKNOWN = 0; // 0x0
    field public static final int VERIFICATION_ALLOW = 1; // 0x1
    field public static final int VERIFICATION_REJECT = -1; // 0xffffffff
    field public static final int VERSION_CODE_HIGHEST = -1; // 0xffffffff
+2 −0
Original line number Diff line number Diff line
@@ -2740,6 +2740,7 @@ public class Intent implements Parcelable, Cloneable {
     * </ul>
     *
     * <p class="note">This is a protected intent that can only be sent by the system.
     * @hide
     */
    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    public static final String ACTION_PACKAGE_STARTABLE = "android.intent.action.PACKAGE_STARTABLE";
@@ -2757,6 +2758,7 @@ public class Intent implements Parcelable, Cloneable {
     * </ul>
     *
     * <p class="note">This is a protected intent that can only be sent by the system.
     * @hide
     */
    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    public static final String ACTION_PACKAGE_UNSTARTABLE =
+3 −0
Original line number Diff line number Diff line
@@ -3824,18 +3824,21 @@ public abstract class PackageManager {
     * Unstartable state with no root cause specified. E.g., data loader seeing missing pages but
     * unclear about the cause. This corresponds to a generic alert window shown to the user when
     * the user attempts to launch the app.
     * @hide
     */
    public static final int UNSTARTABLE_REASON_UNKNOWN = 0;

    /**
     * Unstartable state due to connection issues that interrupt package loading.
     * This corresponds to an alert window shown to the user indicating connection errors.
     * @hide
     */
    public static final int UNSTARTABLE_REASON_CONNECTION_ERROR = 1;

    /**
     * Unstartable state after encountering storage limitations.
     * This corresponds to an alert window indicating limited storage.
     * @hide
     */
    public static final int UNSTARTABLE_REASON_INSUFFICIENT_STORAGE = 2;

+50 −33
Original line number Diff line number Diff line
@@ -101,21 +101,18 @@ public final class IncrementalStates {
        if (DEBUG) {
            Slog.i(TAG, "received package commit event");
        }
        final boolean startableStateChanged;
        synchronized (mLock) {
            if (!mStartableState.isStartable()) {
                mStartableState.adoptNewStartableStateLocked(true);
            }
            startableStateChanged = mStartableState.adoptNewStartableStateLocked(true);
            if (!isIncremental) {
                updateProgressLocked(1);
            }
        }
        mHandler.post(PooledLambda.obtainRunnable(
                IncrementalStates::reportStartableState,
                IncrementalStates.this).recycleOnUse());
        if (startableStateChanged) {
            onStartableStateChanged();
        }
        if (!isIncremental) {
            mHandler.post(PooledLambda.obtainRunnable(
                    IncrementalStates::reportFullyLoaded,
                    IncrementalStates.this).recycleOnUse());
            onLoadingStateChanged();
        }
    }

@@ -131,8 +128,7 @@ public final class IncrementalStates {
        synchronized (mLock) {
            if (mStartableState.isStartable() && mLoadingState.isLoading()) {
                // Changing from startable -> unstartable only if app is still loading.
                mStartableState.adoptNewStartableStateLocked(false);
                startableStateChanged = true;
                startableStateChanged = mStartableState.adoptNewStartableStateLocked(false);
            } else {
                // If the app is fully loaded, the crash or ANR is caused by the app itself, so
                // we do not change the startable state.
@@ -140,12 +136,15 @@ public final class IncrementalStates {
            }
        }
        if (startableStateChanged) {
            mHandler.post(PooledLambda.obtainRunnable(
                    IncrementalStates::reportStartableState,
                    IncrementalStates.this).recycleOnUse());
            onStartableStateChanged();
        }
    }

    private void onStartableStateChanged() {
        // Disable startable state broadcasts
        // TODO(b/171920377): completely remove unstartable state.
    }

    private void reportStartableState() {
        final Callback callback;
        final boolean startable;
@@ -165,6 +164,12 @@ public final class IncrementalStates {
        }
    }

    private void onLoadingStateChanged() {
        mHandler.post(PooledLambda.obtainRunnable(
                IncrementalStates::reportFullyLoaded,
                IncrementalStates.this).recycleOnUse());
    }

    private void reportFullyLoaded() {
        final Callback callback;
        synchronized (mLock) {
@@ -178,23 +183,20 @@ public final class IncrementalStates {
    private class StatusConsumer implements Consumer<Integer> {
        @Override
        public void accept(Integer storageStatus) {
            final boolean oldState, newState;
            final boolean startableStateChanged;
            synchronized (mLock) {
                if (!mLoadingState.isLoading()) {
                    // Do nothing if the package is already fully loaded
                    return;
                }
                oldState = mStartableState.isStartable();
                mStorageHealthStatus = storageStatus;
                updateStartableStateLocked();
                newState = mStartableState.isStartable();
                startableStateChanged = updateStartableStateLocked();
            }
            if (startableStateChanged) {
                onStartableStateChanged();
            }
            if (oldState != newState) {
                mHandler.post(PooledLambda.obtainRunnable(IncrementalStates::reportStartableState,
                        IncrementalStates.this).recycleOnUse());
        }
    }
    };

    /**
     * By calling this method, the caller indicates that there issues with the Incremental
@@ -239,14 +241,10 @@ public final class IncrementalStates {
            newStartableState = mStartableState.isStartable();
        }
        if (!newLoadingState) {
            mHandler.post(PooledLambda.obtainRunnable(
                    IncrementalStates::reportFullyLoaded,
                    IncrementalStates.this).recycleOnUse());
            onLoadingStateChanged();
        }
        if (newStartableState != oldStartableState) {
            mHandler.post(PooledLambda.obtainRunnable(
                    IncrementalStates::reportStartableState,
                    IncrementalStates.this).recycleOnUse());
            onStartableStateChanged();
        }
    }

@@ -284,8 +282,9 @@ public final class IncrementalStates {
     * health
     * status. If the next state is different from the current state, proceed with state
     * change.
     * @return True if the new startable state is different from the old one.
     */
    private void updateStartableStateLocked() {
    private boolean updateStartableStateLocked() {
        final boolean currentState = mStartableState.isStartable();
        boolean nextState = currentState;
        if (!currentState) {
@@ -302,9 +301,9 @@ public final class IncrementalStates {
            }
        }
        if (nextState == currentState) {
            return;
            return false;
        }
        mStartableState.adoptNewStartableStateLocked(nextState);
        return mStartableState.adoptNewStartableStateLocked(nextState);
    }

    private void updateProgressLocked(float progress) {
@@ -343,12 +342,30 @@ public final class IncrementalStates {
            return mUnstartableReason;
        }

        public void adoptNewStartableStateLocked(boolean nextState) {
        /**
         * Adopt new startable state if it is different from the current state.
         * @param nextState True if startable, false if unstartable.
         * @return True if the state has changed, false otherwise.
         */
        public boolean adoptNewStartableStateLocked(boolean nextState) {
            if (mIsStartable == nextState) {
                return false;
            }
            if (!nextState) {
                // Do nothing if the next state is "unstartable"; keep package always startable.
                // TODO(b/171920377): completely remove unstartable state.
                if (DEBUG) {
                Slog.i(TAG, "startable state changed from " + mIsStartable + " to " + nextState);
                    Slog.i(TAG, "Attempting to set startable state to false. Abort.");
                }
                return false;
            }
            if (DEBUG) {
                Slog.i(TAG,
                        "startable state changed from " + mIsStartable + " to " + nextState);
            }
            mIsStartable = nextState;
            mUnstartableReason = getUnstartableReasonLocked();
            return true;
        }

        private int getUnstartableReasonLocked() {
Loading