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

Commit b092825f authored by Rambo Wang's avatar Rambo Wang Committed by Cherrypicker Worker
Browse files

CarrierAppUtils: uninstall prebuild carrier app at most once

Pixels (and other OEM products) have feature to integrate
preloaded carrier apps (e.g. Tycho for Google Fi).
The carrier app will be uninstalled/hidden firstly if it does
not get the carrir privileges. When user insert SIM for the
carrier, the carrier app will be shown again, saving the user
effort/cost to download the carrier app from play store.

The issue scenario here is that after user has upgraded the
carrier app (e.g. through PlayStore) and then OTA upgrading a
new android release which integrated a new verion of carrier app,
the hiding logic is triggered again, causing the tycho
apk upgrading to the new prebuild version but with
the previous activation data cleared.

The CL makes sure the uninstalling logic is only triggered
at most once. This means, on OTA upgrading to newer
carrier app, the newer carrier app does get installed
but the hiding logic will not trigger and previous
activation data is kept.

Bug: 158028151
Test: atest CarrierAppUtilsTest
Test: Regression test (go/hide_carrier_app_test_plan)
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:38a4f7e32bb2ba608ceb2df0d33413bd4d060ed9)
Merged-In: I59ef6170484e08b4558a8918d02bbb801005f175
Change-Id: I59ef6170484e08b4558a8918d02bbb801005f175
parent dc577846
Loading
Loading
Loading
Loading
+23 −12
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import android.util.ArrayMap;
import android.util.Log;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.flags.Flags;
import com.android.internal.telephony.util.TelephonyUtils;

import java.util.ArrayList;
@@ -41,7 +42,7 @@ import java.util.Map;
import java.util.Set;

/**
 * Utilities for handling carrier applications.
 * Utilities to control the states of the system bundled (preinstalled) carrier applications.
 * @hide
 */
public final class CarrierAppUtils {
@@ -246,8 +247,16 @@ public final class CarrierAppUtils {
                    // Always re-grant default permissions to carrier apps w/ privileges.
                    enabledCarrierPackages.add(ai.packageName);
                } else {  // No carrier privileges
                    // Only update enabled state for the app on /system. Once it has been
                    // updated we shouldn't touch it.
                    // Only uninstall system carrier apps that fulfill ALL conditions below:
                    // 1. It has no carrier privileges
                    // 2. It has never been uninstalled before (i.e. we uninstall at most once)
                    // 3. It has not been installed as an update from its system built-in version
                    // 4. It is in default state (not explicitly DISABLED/DISABLED_BY_USER/ENABLED)
                    // 5. It is currently installed for the calling user
                    // TODO(b/329739019):
                    // 1. Merge the nested if conditions below during flag cleaning up phase
                    // 2. Support user case that NEW carrier app is added during OTA, when emerge.
                    if (!Flags.hidePreinstalledCarrierAppAtMostOnce() || !hasRunEver) {
                        if (!isUpdatedSystemApp(ai) && enabledSetting
                                == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
                                && (ai.flags & ApplicationInfo.FLAG_INSTALLED) != 0) {
@@ -256,7 +265,9 @@ public final class CarrierAppUtils {
                            context.createContextAsUser(UserHandle.of(userId), 0)
                                    .getPackageManager()
                                    .setSystemAppState(
                                        packageName, PackageManager.SYSTEM_APP_STATE_UNINSTALLED);
                                            packageName,
                                            PackageManager.SYSTEM_APP_STATE_UNINSTALLED);
                        }
                    }

                    // Associated apps are more brittle, because we can't rely on the distinction