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

Commit a47c4a98 authored by Jing Ji's avatar Jing Ji
Browse files

Exempt carrier priviledged apps in background app restrictions.

Bug: 200326767
Bug: 203105544
Test: atest FrameworksMockingServicesTests:BackgroundRestrictionTest
Change-Id: I9470a7e9483721e0faf19c95b2e7c6129fd1edc7
parent f7e29a40
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -364,6 +364,11 @@ public class PowerExemptionManager {
     * @hide
     */
    public static final int REASON_SYSTEM_MODULE = 320;
    /**
     * Carrier privileged app.
     * @hide
     */
    public static final int REASON_CARRIER_PRIVILEGED_APP = 321;

    /** @hide The app requests out-out. */
    public static final int REASON_OPT_OUT_REQUESTED = 1000;
@@ -440,6 +445,7 @@ public class PowerExemptionManager {
            REASON_ROLE_DIALER,
            REASON_ROLE_EMERGENCY,
            REASON_SYSTEM_MODULE,
            REASON_CARRIER_PRIVILEGED_APP,
            REASON_OPT_OUT_REQUESTED,
    })
    @Retention(RetentionPolicy.SOURCE)
@@ -749,6 +755,8 @@ public class PowerExemptionManager {
                return "ROLE_EMERGENCY";
            case REASON_SYSTEM_MODULE:
                return "SYSTEM_MODULE";
            case REASON_CARRIER_PRIVILEGED_APP:
                return "CARRIER_PRIVILEGED_APP";
            case REASON_OPT_OUT_REQUESTED:
                return "REASON_OPT_OUT_REQUESTED";
            default:
+70 −0
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
import static android.content.pm.PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS;
import static android.os.PowerExemptionManager.REASON_ALLOWLISTED_PACKAGE;
import static android.os.PowerExemptionManager.REASON_CARRIER_PRIVILEGED_APP;
import static android.os.PowerExemptionManager.REASON_COMPANION_DEVICE_MANAGER;
import static android.os.PowerExemptionManager.REASON_DENIED;
import static android.os.PowerExemptionManager.REASON_DEVICE_DEMO_MODE;
@@ -125,6 +126,7 @@ import android.provider.DeviceConfig.OnPropertiesChangedListener;
import android.provider.DeviceConfig.Properties;
import android.provider.Settings;
import android.provider.Settings.Global;
import android.telephony.TelephonyManager;
import android.util.ArraySet;
import android.util.Slog;
import android.util.SparseArray;
@@ -229,6 +231,19 @@ public final class AppRestrictionController {
    @GuardedBy("mLock")
    private final HashMap<String, Boolean> mSystemModulesCache = new HashMap<>();

    /**
     * Lock specifically for bookkeeping around the carrier-privileged app set.
     * Do not acquire any other locks while holding this one. Methods that
     * require this lock to be held are named with a "CPL" suffix.
     */
    private final Object mCarrierPrivilegedLock = new Object();

    /**
     * List of carrier-privileged apps that should be excluded from standby.
     */
    @GuardedBy("mCarrierPrivilegedLock")
    private List<String> mCarrierPrivilegedApps;

    final ActivityManagerService mActivityManagerService;

    /**
@@ -1604,6 +1619,8 @@ public final class AppRestrictionController {
                    return REASON_OP_ACTIVATE_PLATFORM_VPN;
                } else if (isSystemModule(pkg)) {
                    return REASON_SYSTEM_MODULE;
                } else if (isCarrierApp(pkg)) {
                    return REASON_CARRIER_PRIVILEGED_APP;
                }
            }
        }
@@ -1616,6 +1633,37 @@ public final class AppRestrictionController {
        return REASON_DENIED;
    }

    private boolean isCarrierApp(String packageName) {
        synchronized (mCarrierPrivilegedLock) {
            if (mCarrierPrivilegedApps == null) {
                fetchCarrierPrivilegedAppsCPL();
            }
            if (mCarrierPrivilegedApps != null) {
                return mCarrierPrivilegedApps.contains(packageName);
            }
            return false;
        }
    }

    private void clearCarrierPrivilegedApps() {
        if (DEBUG_BG_RESTRICTION_CONTROLLER) {
            Slog.i(TAG, "Clearing carrier privileged apps list");
        }
        synchronized (mCarrierPrivilegedLock) {
            mCarrierPrivilegedApps = null; // Need to be refetched.
        }
    }

    @GuardedBy("mCarrierPrivilegedLock")
    private void fetchCarrierPrivilegedAppsCPL() {
        final TelephonyManager telephonyManager = mInjector.getTelephonyManager();
        mCarrierPrivilegedApps =
                telephonyManager.getCarrierPrivilegedPackagesForAllActiveSubscriptions();
        if (DEBUG_BG_RESTRICTION_CONTROLLER) {
            Slog.d(TAG, "apps with carrier privilege " + mCarrierPrivilegedApps);
        }
    }

    private boolean isRoleHeldByUid(@NonNull String roleName, int uid) {
        synchronized (mLock) {
            final ArrayList<String> roles = mUidRolesMapping.get(uid);
@@ -1791,6 +1839,7 @@ public final class AppRestrictionController {
        private AppBatteryExemptionTracker mAppBatteryExemptionTracker;
        private AppFGSTracker mAppFGSTracker;
        private AppMediaSessionTracker mAppMediaSessionTracker;
        private TelephonyManager mTelephonyManager;

        Injector(Context context) {
            mContext = context;
@@ -1890,6 +1939,13 @@ public final class AppRestrictionController {
            return mRoleManager;
        }

        TelephonyManager getTelephonyManager() {
            if (mTelephonyManager == null) {
                mTelephonyManager = getContext().getSystemService(TelephonyManager.class);
            }
            return mTelephonyManager;
        }

        AppFGSTracker getAppFGSTracker() {
            return mAppFGSTracker;
        }
@@ -1939,6 +1995,19 @@ public final class AppRestrictionController {
                                onUidAdded(uid);
                            }
                        }
                    }
                    // fall through.
                    case Intent.ACTION_PACKAGE_CHANGED: {
                        final String pkgName = intent.getData().getSchemeSpecificPart();
                        final String[] cmpList = intent.getStringArrayExtra(
                                Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST);
                        // If this is PACKAGE_ADDED (cmpList == null), or if it's a whole-package
                        // enable/disable event (cmpList is just the package name itself), drop
                        // our carrier privileged app & system-app caches and let them refresh
                        if (cmpList == null
                                || (cmpList.length == 1 && pkgName.equals(cmpList[0]))) {
                            clearCarrierPrivilegedApps();
                        }
                    } break;
                    case Intent.ACTION_PACKAGE_FULLY_REMOVED: {
                        final int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
@@ -1986,6 +2055,7 @@ public final class AppRestrictionController {
        };
        final IntentFilter packageFilter = new IntentFilter();
        packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
        packageFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
        packageFilter.addAction(Intent.ACTION_PACKAGE_FULLY_REMOVED);
        packageFilter.addDataScheme("package");
        mContext.registerReceiverForAllUsers(broadcastReceiver, packageFilter, null, mBgHandler);
+7 −0
Original line number Diff line number Diff line
@@ -101,6 +101,7 @@ import android.os.SystemClock;
import android.os.UidBatteryConsumer;
import android.os.UserHandle;
import android.provider.DeviceConfig;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.util.Pair;

@@ -211,6 +212,7 @@ public final class BackgroundRestrictionTest {
    @Mock private PermissionManagerServiceInternal mPermissionManagerServiceInternal;
    @Mock private MediaSessionManager mMediaSessionManager;
    @Mock private RoleManager mRoleManager;
    @Mock private TelephonyManager mTelephonyManager;

    private long mCurrentTimeMillis;

@@ -2308,6 +2310,11 @@ public final class BackgroundRestrictionTest {
            return mRoleManager;
        }

        @Override
        TelephonyManager getTelephonyManager() {
            return mTelephonyManager;
        }

        @Override
        AppFGSTracker getAppFGSTracker() {
            return mAppFGSTracker;