Loading packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +58 −70 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ package com.android.providers.settings; import static android.os.Process.INVALID_UID; import static android.os.Process.ROOT_UID; import static android.os.Process.SHELL_UID; import static android.os.Process.SYSTEM_UID; Loading Loading @@ -364,6 +363,11 @@ public class SettingsProvider extends ContentProvider { mHandler = new Handler(mHandlerThread.getLooper()); mSettingsRegistry = new SettingsRegistry(); } SettingsState.cacheSystemPackageNamesAndSystemSignature(getContext()); synchronized (mLock) { mSettingsRegistry.migrateAllLegacySettingsIfNeededLocked(); mSettingsRegistry.syncSsaidTableOnStartLocked(); } mHandler.post(() -> { registerBroadcastReceivers(); startWatchingUserRestrictionChanges(); Loading Loading @@ -2499,8 +2503,6 @@ public class SettingsProvider extends ContentProvider { mHandler = new MyHandler(getContext().getMainLooper()); mGenerationRegistry = new GenerationRegistry(mLock); mBackupManager = new BackupManager(getContext()); migrateAllLegacySettingsIfNeeded(); syncSsaidTableOnStart(); } private void generateUserKeyLocked(int userId) { Loading Loading @@ -2587,8 +2589,7 @@ public class SettingsProvider extends ContentProvider { return getSettingLocked(SETTINGS_TYPE_SSAID, userId, uid); } public void syncSsaidTableOnStart() { synchronized (mLock) { private void syncSsaidTableOnStartLocked() { // Verify that each user's packages and ssaid's are in sync. for (UserInfo user : mUserManager.getAliveUsers()) { // Get all uids for the user's packages. Loading Loading @@ -2621,7 +2622,6 @@ public class SettingsProvider extends ContentProvider { } } } } public List<String> getSettingsNamesLocked(int type, int userId) { final int key = makeKey(type, userId); Loading Loading @@ -2911,7 +2911,7 @@ public class SettingsProvider extends ContentProvider { boolean someSettingChanged = false; Setting setting = settingsState.getSettingLocked(name); if (!SettingsState.isSystemPackage(getContext(), setting.getPackageName(), INVALID_UID, userId)) { setting.getPackageName())) { if (prefix != null && !setting.getName().startsWith(prefix)) { continue; } Loading @@ -2931,7 +2931,7 @@ public class SettingsProvider extends ContentProvider { boolean someSettingChanged = false; Setting setting = settingsState.getSettingLocked(name); if (!SettingsState.isSystemPackage(getContext(), setting.getPackageName(), INVALID_UID, userId)) { setting.getPackageName())) { if (prefix != null && !setting.getName().startsWith(prefix)) { continue; } Loading Loading @@ -3009,8 +3009,7 @@ public class SettingsProvider extends ContentProvider { return mSettingsStates.get(key); } private void migrateAllLegacySettingsIfNeeded() { synchronized (mLock) { private void migrateAllLegacySettingsIfNeededLocked() { final int key = makeKey(SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM); File globalFile = getSettingsFile(key); if (SettingsState.stateFileExists(globalFile)) { Loading Loading @@ -3044,7 +3043,6 @@ public class SettingsProvider extends ContentProvider { Binder.restoreCallingIdentity(identity); } } } private void migrateLegacySettingsForUserIfNeededLocked(int userId) { // Every user has secure settings and if no file we need to migrate. Loading Loading @@ -5036,19 +5034,9 @@ public class SettingsProvider extends ContentProvider { // In the upgrade case we pretend the call is made from the app // that made the last change to the setting to properly determine // whether the call has been made by a system component. int callingUid = -1; try { callingUid = mPackageManager.getPackageUid(setting.getPackageName(), 0, userId); } catch (RemoteException e) { /* ignore - handled below */ } if (callingUid < 0) { Slog.e(LOG_TAG, "Unknown package: " + setting.getPackageName()); continue; } try { final boolean systemSet = SettingsState.isSystemPackage(getContext(), setting.getPackageName(), callingUid, userId); final boolean systemSet = SettingsState.isSystemPackage( getContext(), setting.getPackageName()); if (systemSet) { settings.insertSettingOverrideableByRestoreLocked(name, setting.getValue(), setting.getTag(), true, setting.getPackageName()); Loading packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java +84 −96 Original line number Diff line number Diff line Loading @@ -17,14 +17,13 @@ package com.android.providers.settings; import static android.os.Process.FIRST_APPLICATION_UID; import static android.os.Process.INVALID_UID; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.Signature; import android.os.Binder; import android.os.Build; import android.os.FileUtils; Loading @@ -37,10 +36,10 @@ import android.provider.Settings; import android.providers.settings.SettingsOperationProto; import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; import android.util.AtomicFile; import android.util.Base64; import android.util.Slog; import android.util.SparseIntArray; import android.util.TimeUtils; import android.util.TypedXmlPullParser; import android.util.TypedXmlSerializer; Loading Loading @@ -149,13 +148,7 @@ final class SettingsState { private static final String NULL_VALUE = "null"; private static final Object sLock = new Object(); @GuardedBy("sLock") private static final SparseIntArray sSystemUids = new SparseIntArray(); @GuardedBy("sLock") private static Signature sSystemSignature; private static final ArraySet<String> sSystemPackages = new ArraySet<>(); private final Object mWriteLock = new Object(); Loading Loading @@ -1048,6 +1041,7 @@ final class SettingsState { /** * Uses AtomicFile to check if the file or its backup exists. * * @param file The file to check for existence * @return whether the original or backup exist */ Loading Loading @@ -1307,9 +1301,9 @@ final class SettingsState { if (NULL_VALUE.equals(value)) { value = null; } final boolean callerSystem = !forceNonSystemPackage && !isNull() && isSystemPackage(mContext, packageName); !isNull() && (isCalledFromSystem(packageName) || isSystemPackage(mContext, packageName)); // Settings set by the system are always defaults. if (callerSystem) { setDefault = true; Loading Loading @@ -1434,98 +1428,92 @@ final class SettingsState { return sb.toString(); } // Check if a specific package belonging to the caller is part of the system package. public static boolean isSystemPackage(Context context, String packageName) { final int callingUid = Binder.getCallingUid(); final int callingUserId = UserHandle.getUserId(callingUid); return isSystemPackage(context, packageName, callingUid, callingUserId); // Cache the list of names of system packages. This is only called once on system boot. public static void cacheSystemPackageNamesAndSystemSignature(@NonNull Context context) { final PackageManager packageManager = context.getPackageManager(); final long identity = Binder.clearCallingIdentity(); try { sSystemPackages.add(SYSTEM_PACKAGE_NAME); // Cache SetupWizard package name. final String setupWizPackageName = packageManager.getSetupWizardPackageName(); if (setupWizPackageName != null) { sSystemPackages.add(setupWizPackageName); } final List<PackageInfo> packageInfos = packageManager.getInstalledPackages(0); final int installedPackagesCount = packageInfos.size(); for (int i = 0; i < installedPackagesCount; i++) { if (shouldAddToSystemPackages(packageInfos.get(i))) { sSystemPackages.add(packageInfos.get(i).packageName); } } } finally { Binder.restoreCallingIdentity(identity); } // Check if a specific package, uid, and user ID are part of the system package. public static boolean isSystemPackage(Context context, String packageName, int uid, int userId) { synchronized (sLock) { if (SYSTEM_PACKAGE_NAME.equals(packageName)) { return true; } private static boolean shouldAddToSystemPackages(@NonNull PackageInfo packageInfo) { // Shell and Root are not considered a part of the system if (SHELL_PACKAGE_NAME.equals(packageName) || ROOT_PACKAGE_NAME.equals(packageName)) { if (isShellOrRoot(packageInfo.packageName)) { return false; } if (uid != INVALID_UID) { // Native services running as a special UID get a pass final int callingAppId = UserHandle.getAppId(uid); if (callingAppId < FIRST_APPLICATION_UID) { sSystemUids.put(callingAppId, callingAppId); return true; // Already added if (sSystemPackages.contains(packageInfo.packageName)) { return false; } return isSystemPackage(packageInfo.applicationInfo); } final long identity = Binder.clearCallingIdentity(); try { try { uid = context.getPackageManager().getPackageUidAsUser(packageName, 0, userId); } catch (PackageManager.NameNotFoundException e) { return false; private static boolean isShellOrRoot(@NonNull String packageName) { return (SHELL_PACKAGE_NAME.equals(packageName) || ROOT_PACKAGE_NAME.equals(packageName)); } // If the system or a special system UID (like telephony), done. if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) { sSystemUids.put(uid, uid); return true; private static boolean isCalledFromSystem(@NonNull String packageName) { // Shell and Root are not considered a part of the system if (isShellOrRoot(packageName)) { return false; } // If already known system component, done. if (sSystemUids.indexOfKey(uid) >= 0) { return true; final int callingUid = Binder.getCallingUid(); // Native services running as a special UID get a pass final int callingAppId = UserHandle.getAppId(callingUid); return (callingAppId < FIRST_APPLICATION_UID); } // If SetupWizard, done. String setupWizPackage = context.getPackageManager().getSetupWizardPackageName(); if (packageName.equals(setupWizPackage)) { sSystemUids.put(uid, uid); public static boolean isSystemPackage(@NonNull Context context, @NonNull String packageName) { // Check shell or root before trying to retrieve ApplicationInfo to fail fast if (isShellOrRoot(packageName)) { return false; } // If it's a known system package or known to be platform signed if (sSystemPackages.contains(packageName)) { return true; } // If a persistent system app, done. PackageInfo packageInfo; ApplicationInfo aInfo = null; try { packageInfo = context.getPackageManager().getPackageInfoAsUser( packageName, PackageManager.GET_SIGNATURES, userId); if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0 && (packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { sSystemUids.put(uid, uid); return true; // Notice that this makes a call to package manager inside the lock aInfo = context.getPackageManager().getApplicationInfo(packageName, 0); } catch (PackageManager.NameNotFoundException ignored) { } } catch (PackageManager.NameNotFoundException e) { return false; return isSystemPackage(aInfo); } // Last check if system signed. if (sSystemSignature == null) { try { sSystemSignature = context.getPackageManager().getPackageInfoAsUser( SYSTEM_PACKAGE_NAME, PackageManager.GET_SIGNATURES, UserHandle.USER_SYSTEM).signatures[0]; } catch (PackageManager.NameNotFoundException e) { /* impossible */ private static boolean isSystemPackage(@Nullable ApplicationInfo aInfo) { if (aInfo == null) { return false; } // If the system or a special system UID (like telephony), done. if (aInfo.uid < FIRST_APPLICATION_UID) { return true; } if (sSystemSignature.equals(packageInfo.signatures[0])) { sSystemUids.put(uid, uid); // If a persistent system app, done. if ((aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0 && (aInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { return true; } } finally { Binder.restoreCallingIdentity(identity); // Platform signed packages are considered to be from the system if (aInfo.isSignedWithPlatformKey()) { return true; } return false; } } } Loading
packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +58 −70 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ package com.android.providers.settings; import static android.os.Process.INVALID_UID; import static android.os.Process.ROOT_UID; import static android.os.Process.SHELL_UID; import static android.os.Process.SYSTEM_UID; Loading Loading @@ -364,6 +363,11 @@ public class SettingsProvider extends ContentProvider { mHandler = new Handler(mHandlerThread.getLooper()); mSettingsRegistry = new SettingsRegistry(); } SettingsState.cacheSystemPackageNamesAndSystemSignature(getContext()); synchronized (mLock) { mSettingsRegistry.migrateAllLegacySettingsIfNeededLocked(); mSettingsRegistry.syncSsaidTableOnStartLocked(); } mHandler.post(() -> { registerBroadcastReceivers(); startWatchingUserRestrictionChanges(); Loading Loading @@ -2499,8 +2503,6 @@ public class SettingsProvider extends ContentProvider { mHandler = new MyHandler(getContext().getMainLooper()); mGenerationRegistry = new GenerationRegistry(mLock); mBackupManager = new BackupManager(getContext()); migrateAllLegacySettingsIfNeeded(); syncSsaidTableOnStart(); } private void generateUserKeyLocked(int userId) { Loading Loading @@ -2587,8 +2589,7 @@ public class SettingsProvider extends ContentProvider { return getSettingLocked(SETTINGS_TYPE_SSAID, userId, uid); } public void syncSsaidTableOnStart() { synchronized (mLock) { private void syncSsaidTableOnStartLocked() { // Verify that each user's packages and ssaid's are in sync. for (UserInfo user : mUserManager.getAliveUsers()) { // Get all uids for the user's packages. Loading Loading @@ -2621,7 +2622,6 @@ public class SettingsProvider extends ContentProvider { } } } } public List<String> getSettingsNamesLocked(int type, int userId) { final int key = makeKey(type, userId); Loading Loading @@ -2911,7 +2911,7 @@ public class SettingsProvider extends ContentProvider { boolean someSettingChanged = false; Setting setting = settingsState.getSettingLocked(name); if (!SettingsState.isSystemPackage(getContext(), setting.getPackageName(), INVALID_UID, userId)) { setting.getPackageName())) { if (prefix != null && !setting.getName().startsWith(prefix)) { continue; } Loading @@ -2931,7 +2931,7 @@ public class SettingsProvider extends ContentProvider { boolean someSettingChanged = false; Setting setting = settingsState.getSettingLocked(name); if (!SettingsState.isSystemPackage(getContext(), setting.getPackageName(), INVALID_UID, userId)) { setting.getPackageName())) { if (prefix != null && !setting.getName().startsWith(prefix)) { continue; } Loading Loading @@ -3009,8 +3009,7 @@ public class SettingsProvider extends ContentProvider { return mSettingsStates.get(key); } private void migrateAllLegacySettingsIfNeeded() { synchronized (mLock) { private void migrateAllLegacySettingsIfNeededLocked() { final int key = makeKey(SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM); File globalFile = getSettingsFile(key); if (SettingsState.stateFileExists(globalFile)) { Loading Loading @@ -3044,7 +3043,6 @@ public class SettingsProvider extends ContentProvider { Binder.restoreCallingIdentity(identity); } } } private void migrateLegacySettingsForUserIfNeededLocked(int userId) { // Every user has secure settings and if no file we need to migrate. Loading Loading @@ -5036,19 +5034,9 @@ public class SettingsProvider extends ContentProvider { // In the upgrade case we pretend the call is made from the app // that made the last change to the setting to properly determine // whether the call has been made by a system component. int callingUid = -1; try { callingUid = mPackageManager.getPackageUid(setting.getPackageName(), 0, userId); } catch (RemoteException e) { /* ignore - handled below */ } if (callingUid < 0) { Slog.e(LOG_TAG, "Unknown package: " + setting.getPackageName()); continue; } try { final boolean systemSet = SettingsState.isSystemPackage(getContext(), setting.getPackageName(), callingUid, userId); final boolean systemSet = SettingsState.isSystemPackage( getContext(), setting.getPackageName()); if (systemSet) { settings.insertSettingOverrideableByRestoreLocked(name, setting.getValue(), setting.getTag(), true, setting.getPackageName()); Loading
packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java +84 −96 Original line number Diff line number Diff line Loading @@ -17,14 +17,13 @@ package com.android.providers.settings; import static android.os.Process.FIRST_APPLICATION_UID; import static android.os.Process.INVALID_UID; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.Signature; import android.os.Binder; import android.os.Build; import android.os.FileUtils; Loading @@ -37,10 +36,10 @@ import android.provider.Settings; import android.providers.settings.SettingsOperationProto; import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; import android.util.AtomicFile; import android.util.Base64; import android.util.Slog; import android.util.SparseIntArray; import android.util.TimeUtils; import android.util.TypedXmlPullParser; import android.util.TypedXmlSerializer; Loading Loading @@ -149,13 +148,7 @@ final class SettingsState { private static final String NULL_VALUE = "null"; private static final Object sLock = new Object(); @GuardedBy("sLock") private static final SparseIntArray sSystemUids = new SparseIntArray(); @GuardedBy("sLock") private static Signature sSystemSignature; private static final ArraySet<String> sSystemPackages = new ArraySet<>(); private final Object mWriteLock = new Object(); Loading Loading @@ -1048,6 +1041,7 @@ final class SettingsState { /** * Uses AtomicFile to check if the file or its backup exists. * * @param file The file to check for existence * @return whether the original or backup exist */ Loading Loading @@ -1307,9 +1301,9 @@ final class SettingsState { if (NULL_VALUE.equals(value)) { value = null; } final boolean callerSystem = !forceNonSystemPackage && !isNull() && isSystemPackage(mContext, packageName); !isNull() && (isCalledFromSystem(packageName) || isSystemPackage(mContext, packageName)); // Settings set by the system are always defaults. if (callerSystem) { setDefault = true; Loading Loading @@ -1434,98 +1428,92 @@ final class SettingsState { return sb.toString(); } // Check if a specific package belonging to the caller is part of the system package. public static boolean isSystemPackage(Context context, String packageName) { final int callingUid = Binder.getCallingUid(); final int callingUserId = UserHandle.getUserId(callingUid); return isSystemPackage(context, packageName, callingUid, callingUserId); // Cache the list of names of system packages. This is only called once on system boot. public static void cacheSystemPackageNamesAndSystemSignature(@NonNull Context context) { final PackageManager packageManager = context.getPackageManager(); final long identity = Binder.clearCallingIdentity(); try { sSystemPackages.add(SYSTEM_PACKAGE_NAME); // Cache SetupWizard package name. final String setupWizPackageName = packageManager.getSetupWizardPackageName(); if (setupWizPackageName != null) { sSystemPackages.add(setupWizPackageName); } final List<PackageInfo> packageInfos = packageManager.getInstalledPackages(0); final int installedPackagesCount = packageInfos.size(); for (int i = 0; i < installedPackagesCount; i++) { if (shouldAddToSystemPackages(packageInfos.get(i))) { sSystemPackages.add(packageInfos.get(i).packageName); } } } finally { Binder.restoreCallingIdentity(identity); } // Check if a specific package, uid, and user ID are part of the system package. public static boolean isSystemPackage(Context context, String packageName, int uid, int userId) { synchronized (sLock) { if (SYSTEM_PACKAGE_NAME.equals(packageName)) { return true; } private static boolean shouldAddToSystemPackages(@NonNull PackageInfo packageInfo) { // Shell and Root are not considered a part of the system if (SHELL_PACKAGE_NAME.equals(packageName) || ROOT_PACKAGE_NAME.equals(packageName)) { if (isShellOrRoot(packageInfo.packageName)) { return false; } if (uid != INVALID_UID) { // Native services running as a special UID get a pass final int callingAppId = UserHandle.getAppId(uid); if (callingAppId < FIRST_APPLICATION_UID) { sSystemUids.put(callingAppId, callingAppId); return true; // Already added if (sSystemPackages.contains(packageInfo.packageName)) { return false; } return isSystemPackage(packageInfo.applicationInfo); } final long identity = Binder.clearCallingIdentity(); try { try { uid = context.getPackageManager().getPackageUidAsUser(packageName, 0, userId); } catch (PackageManager.NameNotFoundException e) { return false; private static boolean isShellOrRoot(@NonNull String packageName) { return (SHELL_PACKAGE_NAME.equals(packageName) || ROOT_PACKAGE_NAME.equals(packageName)); } // If the system or a special system UID (like telephony), done. if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) { sSystemUids.put(uid, uid); return true; private static boolean isCalledFromSystem(@NonNull String packageName) { // Shell and Root are not considered a part of the system if (isShellOrRoot(packageName)) { return false; } // If already known system component, done. if (sSystemUids.indexOfKey(uid) >= 0) { return true; final int callingUid = Binder.getCallingUid(); // Native services running as a special UID get a pass final int callingAppId = UserHandle.getAppId(callingUid); return (callingAppId < FIRST_APPLICATION_UID); } // If SetupWizard, done. String setupWizPackage = context.getPackageManager().getSetupWizardPackageName(); if (packageName.equals(setupWizPackage)) { sSystemUids.put(uid, uid); public static boolean isSystemPackage(@NonNull Context context, @NonNull String packageName) { // Check shell or root before trying to retrieve ApplicationInfo to fail fast if (isShellOrRoot(packageName)) { return false; } // If it's a known system package or known to be platform signed if (sSystemPackages.contains(packageName)) { return true; } // If a persistent system app, done. PackageInfo packageInfo; ApplicationInfo aInfo = null; try { packageInfo = context.getPackageManager().getPackageInfoAsUser( packageName, PackageManager.GET_SIGNATURES, userId); if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0 && (packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { sSystemUids.put(uid, uid); return true; // Notice that this makes a call to package manager inside the lock aInfo = context.getPackageManager().getApplicationInfo(packageName, 0); } catch (PackageManager.NameNotFoundException ignored) { } } catch (PackageManager.NameNotFoundException e) { return false; return isSystemPackage(aInfo); } // Last check if system signed. if (sSystemSignature == null) { try { sSystemSignature = context.getPackageManager().getPackageInfoAsUser( SYSTEM_PACKAGE_NAME, PackageManager.GET_SIGNATURES, UserHandle.USER_SYSTEM).signatures[0]; } catch (PackageManager.NameNotFoundException e) { /* impossible */ private static boolean isSystemPackage(@Nullable ApplicationInfo aInfo) { if (aInfo == null) { return false; } // If the system or a special system UID (like telephony), done. if (aInfo.uid < FIRST_APPLICATION_UID) { return true; } if (sSystemSignature.equals(packageInfo.signatures[0])) { sSystemUids.put(uid, uid); // If a persistent system app, done. if ((aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0 && (aInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { return true; } } finally { Binder.restoreCallingIdentity(identity); // Platform signed packages are considered to be from the system if (aInfo.isSignedWithPlatformKey()) { return true; } return false; } } }