Merge "Revert "Revert "[SettingsProvider] remove in-lock calls to PackageManager.getPackageUid()""" into sc-dev
This commit is contained in:
@@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package com.android.providers.settings;
|
package com.android.providers.settings;
|
||||||
|
|
||||||
import static android.os.Process.INVALID_UID;
|
|
||||||
import static android.os.Process.ROOT_UID;
|
import static android.os.Process.ROOT_UID;
|
||||||
import static android.os.Process.SHELL_UID;
|
import static android.os.Process.SHELL_UID;
|
||||||
import static android.os.Process.SYSTEM_UID;
|
import static android.os.Process.SYSTEM_UID;
|
||||||
@@ -364,6 +363,11 @@ public class SettingsProvider extends ContentProvider {
|
|||||||
mHandler = new Handler(mHandlerThread.getLooper());
|
mHandler = new Handler(mHandlerThread.getLooper());
|
||||||
mSettingsRegistry = new SettingsRegistry();
|
mSettingsRegistry = new SettingsRegistry();
|
||||||
}
|
}
|
||||||
|
SettingsState.cacheSystemPackageNamesAndSystemSignature(getContext());
|
||||||
|
synchronized (mLock) {
|
||||||
|
mSettingsRegistry.migrateAllLegacySettingsIfNeededLocked();
|
||||||
|
mSettingsRegistry.syncSsaidTableOnStartLocked();
|
||||||
|
}
|
||||||
mHandler.post(() -> {
|
mHandler.post(() -> {
|
||||||
registerBroadcastReceivers();
|
registerBroadcastReceivers();
|
||||||
startWatchingUserRestrictionChanges();
|
startWatchingUserRestrictionChanges();
|
||||||
@@ -2499,8 +2503,6 @@ public class SettingsProvider extends ContentProvider {
|
|||||||
mHandler = new MyHandler(getContext().getMainLooper());
|
mHandler = new MyHandler(getContext().getMainLooper());
|
||||||
mGenerationRegistry = new GenerationRegistry(mLock);
|
mGenerationRegistry = new GenerationRegistry(mLock);
|
||||||
mBackupManager = new BackupManager(getContext());
|
mBackupManager = new BackupManager(getContext());
|
||||||
migrateAllLegacySettingsIfNeeded();
|
|
||||||
syncSsaidTableOnStart();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateUserKeyLocked(int userId) {
|
private void generateUserKeyLocked(int userId) {
|
||||||
@@ -2587,38 +2589,36 @@ public class SettingsProvider extends ContentProvider {
|
|||||||
return getSettingLocked(SETTINGS_TYPE_SSAID, userId, uid);
|
return getSettingLocked(SETTINGS_TYPE_SSAID, userId, uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void syncSsaidTableOnStart() {
|
private void syncSsaidTableOnStartLocked() {
|
||||||
synchronized (mLock) {
|
// Verify that each user's packages and ssaid's are in sync.
|
||||||
// Verify that each user's packages and ssaid's are in sync.
|
for (UserInfo user : mUserManager.getAliveUsers()) {
|
||||||
for (UserInfo user : mUserManager.getAliveUsers()) {
|
// Get all uids for the user's packages.
|
||||||
// Get all uids for the user's packages.
|
final List<PackageInfo> packages;
|
||||||
final List<PackageInfo> packages;
|
try {
|
||||||
try {
|
packages = mPackageManager.getInstalledPackages(
|
||||||
packages = mPackageManager.getInstalledPackages(
|
|
||||||
PackageManager.MATCH_UNINSTALLED_PACKAGES,
|
PackageManager.MATCH_UNINSTALLED_PACKAGES,
|
||||||
user.id).getList();
|
user.id).getList();
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
throw new IllegalStateException("Package manager not available");
|
throw new IllegalStateException("Package manager not available");
|
||||||
}
|
}
|
||||||
final Set<String> appUids = new HashSet<>();
|
final Set<String> appUids = new HashSet<>();
|
||||||
for (PackageInfo info : packages) {
|
for (PackageInfo info : packages) {
|
||||||
appUids.add(Integer.toString(info.applicationInfo.uid));
|
appUids.add(Integer.toString(info.applicationInfo.uid));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get all uids currently stored in the user's ssaid table.
|
// Get all uids currently stored in the user's ssaid table.
|
||||||
final Set<String> ssaidUids = new HashSet<>(
|
final Set<String> ssaidUids = new HashSet<>(
|
||||||
getSettingsNamesLocked(SETTINGS_TYPE_SSAID, user.id));
|
getSettingsNamesLocked(SETTINGS_TYPE_SSAID, user.id));
|
||||||
ssaidUids.remove(SSAID_USER_KEY);
|
ssaidUids.remove(SSAID_USER_KEY);
|
||||||
|
|
||||||
// Perform a set difference for the appUids and ssaidUids.
|
// Perform a set difference for the appUids and ssaidUids.
|
||||||
ssaidUids.removeAll(appUids);
|
ssaidUids.removeAll(appUids);
|
||||||
|
|
||||||
// If there are ssaidUids left over they need to be removed from the table.
|
// If there are ssaidUids left over they need to be removed from the table.
|
||||||
final SettingsState ssaidSettings = getSettingsLocked(SETTINGS_TYPE_SSAID,
|
final SettingsState ssaidSettings = getSettingsLocked(SETTINGS_TYPE_SSAID,
|
||||||
user.id);
|
user.id);
|
||||||
for (String uid : ssaidUids) {
|
for (String uid : ssaidUids) {
|
||||||
ssaidSettings.deleteSettingLocked(uid);
|
ssaidSettings.deleteSettingLocked(uid);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2911,7 +2911,7 @@ public class SettingsProvider extends ContentProvider {
|
|||||||
boolean someSettingChanged = false;
|
boolean someSettingChanged = false;
|
||||||
Setting setting = settingsState.getSettingLocked(name);
|
Setting setting = settingsState.getSettingLocked(name);
|
||||||
if (!SettingsState.isSystemPackage(getContext(),
|
if (!SettingsState.isSystemPackage(getContext(),
|
||||||
setting.getPackageName(), INVALID_UID, userId)) {
|
setting.getPackageName())) {
|
||||||
if (prefix != null && !setting.getName().startsWith(prefix)) {
|
if (prefix != null && !setting.getName().startsWith(prefix)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -2931,7 +2931,7 @@ public class SettingsProvider extends ContentProvider {
|
|||||||
boolean someSettingChanged = false;
|
boolean someSettingChanged = false;
|
||||||
Setting setting = settingsState.getSettingLocked(name);
|
Setting setting = settingsState.getSettingLocked(name);
|
||||||
if (!SettingsState.isSystemPackage(getContext(),
|
if (!SettingsState.isSystemPackage(getContext(),
|
||||||
setting.getPackageName(), INVALID_UID, userId)) {
|
setting.getPackageName())) {
|
||||||
if (prefix != null && !setting.getName().startsWith(prefix)) {
|
if (prefix != null && !setting.getName().startsWith(prefix)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -3009,40 +3009,38 @@ public class SettingsProvider extends ContentProvider {
|
|||||||
return mSettingsStates.get(key);
|
return mSettingsStates.get(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void migrateAllLegacySettingsIfNeeded() {
|
private void migrateAllLegacySettingsIfNeededLocked() {
|
||||||
synchronized (mLock) {
|
final int key = makeKey(SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM);
|
||||||
final int key = makeKey(SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM);
|
File globalFile = getSettingsFile(key);
|
||||||
File globalFile = getSettingsFile(key);
|
if (SettingsState.stateFileExists(globalFile)) {
|
||||||
if (SettingsState.stateFileExists(globalFile)) {
|
return;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
mSettingsCreationBuildId = Build.ID;
|
mSettingsCreationBuildId = Build.ID;
|
||||||
|
|
||||||
final long identity = Binder.clearCallingIdentity();
|
final long identity = Binder.clearCallingIdentity();
|
||||||
try {
|
try {
|
||||||
List<UserInfo> users = mUserManager.getAliveUsers();
|
List<UserInfo> users = mUserManager.getAliveUsers();
|
||||||
|
|
||||||
final int userCount = users.size();
|
final int userCount = users.size();
|
||||||
for (int i = 0; i < userCount; i++) {
|
for (int i = 0; i < userCount; i++) {
|
||||||
final int userId = users.get(i).id;
|
final int userId = users.get(i).id;
|
||||||
|
|
||||||
DatabaseHelper dbHelper = new DatabaseHelper(getContext(), userId);
|
DatabaseHelper dbHelper = new DatabaseHelper(getContext(), userId);
|
||||||
SQLiteDatabase database = dbHelper.getWritableDatabase();
|
SQLiteDatabase database = dbHelper.getWritableDatabase();
|
||||||
migrateLegacySettingsForUserLocked(dbHelper, database, userId);
|
migrateLegacySettingsForUserLocked(dbHelper, database, userId);
|
||||||
|
|
||||||
// Upgrade to the latest version.
|
// Upgrade to the latest version.
|
||||||
UpgradeController upgrader = new UpgradeController(userId);
|
UpgradeController upgrader = new UpgradeController(userId);
|
||||||
upgrader.upgradeIfNeededLocked();
|
upgrader.upgradeIfNeededLocked();
|
||||||
|
|
||||||
// Drop from memory if not a running user.
|
// Drop from memory if not a running user.
|
||||||
if (!mUserManager.isUserRunning(new UserHandle(userId))) {
|
if (!mUserManager.isUserRunning(new UserHandle(userId))) {
|
||||||
removeUserStateLocked(userId, false);
|
removeUserStateLocked(userId, false);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} finally {
|
|
||||||
Binder.restoreCallingIdentity(identity);
|
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
Binder.restoreCallingIdentity(identity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5036,19 +5034,9 @@ public class SettingsProvider extends ContentProvider {
|
|||||||
// In the upgrade case we pretend the call is made from the app
|
// In the upgrade case we pretend the call is made from the app
|
||||||
// that made the last change to the setting to properly determine
|
// that made the last change to the setting to properly determine
|
||||||
// whether the call has been made by a system component.
|
// whether the call has been made by a system component.
|
||||||
int callingUid = -1;
|
|
||||||
try {
|
try {
|
||||||
callingUid = mPackageManager.getPackageUid(setting.getPackageName(), 0, userId);
|
final boolean systemSet = SettingsState.isSystemPackage(
|
||||||
} catch (RemoteException e) {
|
getContext(), setting.getPackageName());
|
||||||
/* 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);
|
|
||||||
if (systemSet) {
|
if (systemSet) {
|
||||||
settings.insertSettingOverrideableByRestoreLocked(name, setting.getValue(),
|
settings.insertSettingOverrideableByRestoreLocked(name, setting.getValue(),
|
||||||
setting.getTag(), true, setting.getPackageName());
|
setting.getTag(), true, setting.getPackageName());
|
||||||
|
|||||||
@@ -17,14 +17,13 @@
|
|||||||
package com.android.providers.settings;
|
package com.android.providers.settings;
|
||||||
|
|
||||||
import static android.os.Process.FIRST_APPLICATION_UID;
|
import static android.os.Process.FIRST_APPLICATION_UID;
|
||||||
import static android.os.Process.INVALID_UID;
|
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
|
import android.annotation.Nullable;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.content.pm.PackageInfo;
|
import android.content.pm.PackageInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.Signature;
|
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.FileUtils;
|
import android.os.FileUtils;
|
||||||
@@ -37,10 +36,10 @@ import android.provider.Settings;
|
|||||||
import android.providers.settings.SettingsOperationProto;
|
import android.providers.settings.SettingsOperationProto;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
|
import android.util.ArraySet;
|
||||||
import android.util.AtomicFile;
|
import android.util.AtomicFile;
|
||||||
import android.util.Base64;
|
import android.util.Base64;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
import android.util.SparseIntArray;
|
|
||||||
import android.util.TimeUtils;
|
import android.util.TimeUtils;
|
||||||
import android.util.TypedXmlPullParser;
|
import android.util.TypedXmlPullParser;
|
||||||
import android.util.TypedXmlSerializer;
|
import android.util.TypedXmlSerializer;
|
||||||
@@ -149,13 +148,7 @@ final class SettingsState {
|
|||||||
|
|
||||||
private static final String NULL_VALUE = "null";
|
private static final String NULL_VALUE = "null";
|
||||||
|
|
||||||
private static final Object sLock = new Object();
|
private static final ArraySet<String> sSystemPackages = new ArraySet<>();
|
||||||
|
|
||||||
@GuardedBy("sLock")
|
|
||||||
private static final SparseIntArray sSystemUids = new SparseIntArray();
|
|
||||||
|
|
||||||
@GuardedBy("sLock")
|
|
||||||
private static Signature sSystemSignature;
|
|
||||||
|
|
||||||
private final Object mWriteLock = new Object();
|
private final Object mWriteLock = new Object();
|
||||||
|
|
||||||
@@ -641,7 +634,7 @@ final class SettingsState {
|
|||||||
/**
|
/**
|
||||||
* Dump historical operations as a proto buf.
|
* 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.
|
* @param fieldId The repeated field ID to use to save an operation to.
|
||||||
*/
|
*/
|
||||||
void dumpHistoricalOperations(@NonNull ProtoOutputStream proto, long fieldId) {
|
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.
|
* Uses AtomicFile to check if the file or its backup exists.
|
||||||
|
*
|
||||||
* @param file The file to check for existence
|
* @param file The file to check for existence
|
||||||
* @return whether the original or backup exist
|
* @return whether the original or backup exist
|
||||||
*/
|
*/
|
||||||
@@ -1307,9 +1301,9 @@ final class SettingsState {
|
|||||||
if (NULL_VALUE.equals(value)) {
|
if (NULL_VALUE.equals(value)) {
|
||||||
value = null;
|
value = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean callerSystem = !forceNonSystemPackage &&
|
final boolean callerSystem = !forceNonSystemPackage &&
|
||||||
!isNull() && isSystemPackage(mContext, packageName);
|
!isNull() && (isCalledFromSystem(packageName)
|
||||||
|
|| isSystemPackage(mContext, packageName));
|
||||||
// Settings set by the system are always defaults.
|
// Settings set by the system are always defaults.
|
||||||
if (callerSystem) {
|
if (callerSystem) {
|
||||||
setDefault = true;
|
setDefault = true;
|
||||||
@@ -1434,98 +1428,98 @@ final class SettingsState {
|
|||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if a specific package belonging to the caller is part of the system package.
|
// Cache the list of names of system packages. This is only called once on system boot.
|
||||||
public static boolean isSystemPackage(Context context, String packageName) {
|
public static void cacheSystemPackageNamesAndSystemSignature(@NonNull Context context) {
|
||||||
final int callingUid = Binder.getCallingUid();
|
final PackageManager packageManager = context.getPackageManager();
|
||||||
final int callingUserId = UserHandle.getUserId(callingUid);
|
final long identity = Binder.clearCallingIdentity();
|
||||||
return isSystemPackage(context, packageName, callingUid, callingUserId);
|
try {
|
||||||
}
|
sSystemPackages.add(SYSTEM_PACKAGE_NAME);
|
||||||
|
// Cache SetupWizard package name.
|
||||||
// Check if a specific package, uid, and user ID are part of the system package.
|
final String setupWizPackageName = packageManager.getSetupWizardPackageName();
|
||||||
public static boolean isSystemPackage(Context context, String packageName, int uid,
|
if (setupWizPackageName != null) {
|
||||||
int userId) {
|
sSystemPackages.add(setupWizPackageName);
|
||||||
synchronized (sLock) {
|
|
||||||
if (SYSTEM_PACKAGE_NAME.equals(packageName)) {
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
final List<PackageInfo> packageInfos = packageManager.getInstalledPackages(0);
|
||||||
// Shell and Root are not considered a part of the system
|
final int installedPackagesCount = packageInfos.size();
|
||||||
if (SHELL_PACKAGE_NAME.equals(packageName)
|
for (int i = 0; i < installedPackagesCount; i++) {
|
||||||
|| ROOT_PACKAGE_NAME.equals(packageName)) {
|
if (shouldAddToSystemPackages(packageInfos.get(i))) {
|
||||||
return false;
|
sSystemPackages.add(packageInfos.get(i).packageName);
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
final long identity = Binder.clearCallingIdentity();
|
Binder.restoreCallingIdentity(identity);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If SetupWizard, done.
|
|
||||||
String setupWizPackage = context.getPackageManager().getSetupWizardPackageName();
|
|
||||||
if (packageName.equals(setupWizPackage)) {
|
|
||||||
sSystemUids.put(uid, uid);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isShellOrRoot(@NonNull String packageName) {
|
||||||
|
return (SHELL_PACKAGE_NAME.equals(packageName)
|
||||||
|
|| ROOT_PACKAGE_NAME.equals(packageName));
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
final long identity = Binder.clearCallingIdentity();
|
||||||
|
try {
|
||||||
|
try {
|
||||||
|
// Notice that this makes a call to package manager inside the lock
|
||||||
|
aInfo = context.getPackageManager().getApplicationInfo(packageName, 0);
|
||||||
|
} catch (PackageManager.NameNotFoundException ignored) {
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
Binder.restoreCallingIdentity(identity);
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user