summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java128
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java180
2 files changed, 142 insertions, 166 deletions
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 081f3f673702..6fefbf980dc5 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -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;
@@ -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();
@@ -2496,8 +2500,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) {
@@ -2584,38 +2586,36 @@ public class SettingsProvider extends ContentProvider {
return getSettingLocked(SETTINGS_TYPE_SSAID, userId, uid);
}
- public void syncSsaidTableOnStart() {
- synchronized (mLock) {
- // 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.
- final List<PackageInfo> packages;
- try {
- packages = mPackageManager.getInstalledPackages(
+ 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.
+ final List<PackageInfo> packages;
+ try {
+ packages = mPackageManager.getInstalledPackages(
PackageManager.MATCH_UNINSTALLED_PACKAGES,
user.id).getList();
- } catch (RemoteException e) {
- throw new IllegalStateException("Package manager not available");
- }
- final Set<String> appUids = new HashSet<>();
- for (PackageInfo info : packages) {
- appUids.add(Integer.toString(info.applicationInfo.uid));
- }
+ } catch (RemoteException e) {
+ throw new IllegalStateException("Package manager not available");
+ }
+ final Set<String> appUids = new HashSet<>();
+ for (PackageInfo info : packages) {
+ appUids.add(Integer.toString(info.applicationInfo.uid));
+ }
- // Get all uids currently stored in the user's ssaid table.
- final Set<String> ssaidUids = new HashSet<>(
- getSettingsNamesLocked(SETTINGS_TYPE_SSAID, user.id));
- ssaidUids.remove(SSAID_USER_KEY);
+ // Get all uids currently stored in the user's ssaid table.
+ final Set<String> ssaidUids = new HashSet<>(
+ getSettingsNamesLocked(SETTINGS_TYPE_SSAID, user.id));
+ ssaidUids.remove(SSAID_USER_KEY);
- // Perform a set difference for the appUids and ssaidUids.
- ssaidUids.removeAll(appUids);
+ // Perform a set difference for the appUids and ssaidUids.
+ ssaidUids.removeAll(appUids);
- // If there are ssaidUids left over they need to be removed from the table.
- final SettingsState ssaidSettings = getSettingsLocked(SETTINGS_TYPE_SSAID,
- user.id);
- for (String uid : ssaidUids) {
- ssaidSettings.deleteSettingLocked(uid);
- }
+ // If there are ssaidUids left over they need to be removed from the table.
+ final SettingsState ssaidSettings = getSettingsLocked(SETTINGS_TYPE_SSAID,
+ user.id);
+ for (String uid : ssaidUids) {
+ ssaidSettings.deleteSettingLocked(uid);
}
}
}
@@ -2908,7 +2908,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;
}
@@ -2928,7 +2928,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;
}
@@ -3006,40 +3006,38 @@ public class SettingsProvider extends ContentProvider {
return mSettingsStates.get(key);
}
- private void migrateAllLegacySettingsIfNeeded() {
- synchronized (mLock) {
- final int key = makeKey(SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM);
- File globalFile = getSettingsFile(key);
- if (SettingsState.stateFileExists(globalFile)) {
- return;
- }
+ private void migrateAllLegacySettingsIfNeededLocked() {
+ final int key = makeKey(SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM);
+ File globalFile = getSettingsFile(key);
+ if (SettingsState.stateFileExists(globalFile)) {
+ return;
+ }
- mSettingsCreationBuildId = Build.ID;
+ mSettingsCreationBuildId = Build.ID;
- final long identity = Binder.clearCallingIdentity();
- try {
- List<UserInfo> users = mUserManager.getAliveUsers();
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ List<UserInfo> users = mUserManager.getAliveUsers();
- final int userCount = users.size();
- for (int i = 0; i < userCount; i++) {
- final int userId = users.get(i).id;
+ final int userCount = users.size();
+ for (int i = 0; i < userCount; i++) {
+ final int userId = users.get(i).id;
- DatabaseHelper dbHelper = new DatabaseHelper(getContext(), userId);
- SQLiteDatabase database = dbHelper.getWritableDatabase();
- migrateLegacySettingsForUserLocked(dbHelper, database, userId);
+ DatabaseHelper dbHelper = new DatabaseHelper(getContext(), userId);
+ SQLiteDatabase database = dbHelper.getWritableDatabase();
+ migrateLegacySettingsForUserLocked(dbHelper, database, userId);
- // Upgrade to the latest version.
- UpgradeController upgrader = new UpgradeController(userId);
- upgrader.upgradeIfNeededLocked();
+ // Upgrade to the latest version.
+ UpgradeController upgrader = new UpgradeController(userId);
+ upgrader.upgradeIfNeededLocked();
- // Drop from memory if not a running user.
- if (!mUserManager.isUserRunning(new UserHandle(userId))) {
- removeUserStateLocked(userId, false);
- }
+ // Drop from memory if not a running user.
+ if (!mUserManager.isUserRunning(new UserHandle(userId))) {
+ removeUserStateLocked(userId, false);
}
- } finally {
- Binder.restoreCallingIdentity(identity);
}
+ } finally {
+ Binder.restoreCallingIdentity(identity);
}
}
@@ -5033,19 +5031,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());
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
index 53d868ac0050..911ff9916d6c 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
@@ -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;
@@ -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;
@@ -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();
@@ -641,7 +634,7 @@ final class SettingsState {
/**
* Dump historical operations as a proto buf.
*
- * @param proto The proto buf stream to dump to
+ * @param proto The proto buf stream to dump to
* @param fieldId The repeated field ID to use to save an operation to.
*/
void dumpHistoricalOperations(@NonNull ProtoOutputStream proto, long fieldId) {
@@ -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
*/
@@ -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;
@@ -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);
- }
-
- // 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;
- }
-
- // Shell and Root are not considered a part of the system
- if (SHELL_PACKAGE_NAME.equals(packageName)
- || ROOT_PACKAGE_NAME.equals(packageName)) {
- return false;
+ // 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);
}
-
- 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;
+ 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);
+ }
+ }
- final long identity = Binder.clearCallingIdentity();
- try {
- try {
- uid = context.getPackageManager().getPackageUidAsUser(packageName, 0, userId);
- } catch (PackageManager.NameNotFoundException e) {
- return false;
- }
-
- // If the system or a special system UID (like telephony), done.
- if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
- sSystemUids.put(uid, uid);
- return true;
- }
-
- // If already known system component, done.
- if (sSystemUids.indexOfKey(uid) >= 0) {
- return true;
- }
+ private static boolean shouldAddToSystemPackages(@NonNull PackageInfo packageInfo) {
+ // Shell and Root are not considered a part of the system
+ if (isShellOrRoot(packageInfo.packageName)) {
+ return false;
+ }
+ // Already added
+ if (sSystemPackages.contains(packageInfo.packageName)) {
+ return false;
+ }
+ return isSystemPackage(packageInfo.applicationInfo);
+ }
- // If SetupWizard, done.
- String setupWizPackage = context.getPackageManager().getSetupWizardPackageName();
- if (packageName.equals(setupWizPackage)) {
- sSystemUids.put(uid, uid);
- return true;
- }
+ private static boolean isShellOrRoot(@NonNull String packageName) {
+ return (SHELL_PACKAGE_NAME.equals(packageName)
+ || ROOT_PACKAGE_NAME.equals(packageName));
+ }
- // If a persistent system app, done.
- PackageInfo packageInfo;
- 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;
- }
- } catch (PackageManager.NameNotFoundException e) {
- return false;
- }
+ private static boolean isCalledFromSystem(@NonNull String packageName) {
+ // Shell and Root are not considered a part of the system
+ if (isShellOrRoot(packageName)) {
+ return false;
+ }
+ 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);
+ }
- // 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 */
- return false;
- }
- }
- if (sSystemSignature.equals(packageInfo.signatures[0])) {
- sSystemUids.put(uid, uid);
- return true;
- }
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
+ 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;
+ }
+ ApplicationInfo aInfo = null;
+ try {
+ // Notice that this makes a call to package manager inside the lock
+ aInfo = context.getPackageManager().getApplicationInfo(packageName, 0);
+ } catch (PackageManager.NameNotFoundException ignored) {
+ }
+ return isSystemPackage(aInfo);
+ }
+ 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 a persistent system app, done.
+ if ((aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0
+ && (aInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+ return true;
+ }
+ // Platform signed packages are considered to be from the system
+ if (aInfo.isSignedWithPlatformKey()) {
+ return true;
+ }
+ return false;
}
}