下面列出了android.os.Process#SYSTEM_UID 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
public int checkPermission(String permission, int pid, int uid) {
if (permission == null) {
throw new IllegalArgumentException("permission is null");
}
final IActivityManager am = ActivityManager.getService();
if (am == null) {
// Well this is super awkward; we somehow don't have an active
// ActivityManager instance. If we're testing a root or system
// UID, then they totally have whatever permission this is.
final int appId = UserHandle.getAppId(uid);
if (appId == Process.ROOT_UID || appId == Process.SYSTEM_UID) {
Slog.w(TAG, "Missing ActivityManager; assuming " + uid + " holds " + permission);
return PackageManager.PERMISSION_GRANTED;
}
}
try {
return am.checkPermission(permission, pid, uid);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
public int getState() {
if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!checkIfCallerIsForegroundUser())) {
Slog.w(TAG, "getState(): report OFF for non-active and non system user");
return BluetoothAdapter.STATE_OFF;
}
try {
mBluetoothLock.readLock().lock();
if (mBluetooth != null) {
return mBluetooth.getState();
}
} catch (RemoteException e) {
Slog.e(TAG, "getState()", e);
} finally {
mBluetoothLock.readLock().unlock();
}
return BluetoothAdapter.STATE_OFF;
}
private boolean isThrottlingExemptLocked(Identity identity) {
if (identity.mUid == Process.SYSTEM_UID) {
return true;
}
if (mBackgroundThrottlePackageWhitelist.contains(identity.mPackageName)) {
return true;
}
for (LocationProviderProxy provider : mProxyProviders) {
if (identity.mPackageName.equals(provider.getConnectedPackageName())) {
return true;
}
}
return false;
}
@Override
public IBinder getAppThread() {
Binder appThread = ActivityThread.getApplicationThread.call(VirtualCore.mainThread());
return new FakeIdentityBinder(appThread) {
@Override
protected int getFakeUid() {
return Process.SYSTEM_UID;
}
};
}
/**
* Logs a warning if the system process directly called a method such as
* {@link #startService(Intent)} instead of {@link #startServiceAsUser(Intent, UserHandle)}.
* The "AsUser" variants allow us to properly enforce the user's restrictions.
*/
private void warnIfCallingFromSystemProcess() {
if (Process.myUid() == Process.SYSTEM_UID) {
Slog.w(TAG, "Calling a method in the system process without a qualified user: "
+ Debug.getCallers(5));
}
}
/**
* Logs a warning if the system process directly called a method such as
* {@link #startService(Intent)} instead of {@link #startServiceAsUser(Intent, UserHandle)}.
* The "AsUser" variants allow us to properly enforce the user's restrictions.
*/
private void warnIfCallingFromSystemProcess() {
if (Process.myUid() == Process.SYSTEM_UID) {
Slog.w(TAG, "Calling a method in the system process without a qualified user: "
+ Debug.getCallers(5));
}
}
/**
* uid 1000 (Process.SYSTEM_UID) may specify any uid > 1000 in normal
* operation. It may also specify any gid and setgroups() list it chooses.
* In factory test mode, it may specify any UID.
*
* @param args non-null; zygote spawner arguments
* @param peer non-null; peer credentials
* @throws ZygoteSecurityException
*/
private static void applyUidSecurityPolicy(Arguments args, Credentials peer)
throws ZygoteSecurityException {
if (peer.getUid() == Process.SYSTEM_UID) {
/* In normal operation, SYSTEM_UID can only specify a restricted
* set of UIDs. In factory test mode, SYSTEM_UID may specify any uid.
*/
boolean uidRestricted = FactoryTest.getMode() == FactoryTest.FACTORY_TEST_OFF;
if (uidRestricted && args.uidSpecified && (args.uid < Process.SYSTEM_UID)) {
throw new ZygoteSecurityException(
"System UID may not launch process with UID < "
+ Process.SYSTEM_UID);
}
}
// If not otherwise specified, uid and gid are inherited from peer
if (!args.uidSpecified) {
args.uid = peer.getUid();
args.uidSpecified = true;
}
if (!args.gidSpecified) {
args.gid = peer.getGid();
args.gidSpecified = true;
}
}
@Override
public int checkPermission(String permission, int pid, int uid) {
if (permission == null) {
throw new IllegalArgumentException("permission is null");
}
final IActivityManager am = ActivityManager.getService();
if (am == null) {
// Well this is super awkward; we somehow don't have an active
// ActivityManager instance. If we're testing a root or system
// UID, then they totally have whatever permission this is.
final int appId = UserHandle.getAppId(uid);
if (appId == Process.ROOT_UID || appId == Process.SYSTEM_UID) {
Slog.w(TAG, "Missing ActivityManager; assuming " + uid + " holds " + permission);
return PackageManager.PERMISSION_GRANTED;
}
Slog.w(TAG, "Missing ActivityManager; assuming " + uid + " does not hold "
+ permission);
return PackageManager.PERMISSION_DENIED;
}
try {
return am.checkPermission(permission, pid, uid);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Logs a warning if the system process directly called a method such as
* {@link #startService(Intent)} instead of {@link #startServiceAsUser(Intent, UserHandle)}.
* The "AsUser" variants allow us to properly enforce the user's restrictions.
*/
private void warnIfCallingFromSystemProcess() {
if (Process.myUid() == Process.SYSTEM_UID) {
Slog.w(TAG, "Calling a method in the system process without a qualified user: "
+ Debug.getCallers(5));
}
}
/**
* Called when a wake lock is changing.
*/
public void onWakeLockChanging(int flags, String tag, String packageName,
int ownerUid, int ownerPid, WorkSource workSource, String historyTag,
int newFlags, String newTag, String newPackageName, int newOwnerUid,
int newOwnerPid, WorkSource newWorkSource, String newHistoryTag) {
final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
final int newMonitorType = getBatteryStatsWakeLockMonitorType(newFlags);
if (workSource != null && newWorkSource != null
&& monitorType >= 0 && newMonitorType >= 0) {
if (DEBUG) {
Slog.d(TAG, "onWakeLockChanging: flags=" + newFlags + ", tag=\"" + newTag
+ "\", packageName=" + newPackageName
+ ", ownerUid=" + newOwnerUid + ", ownerPid=" + newOwnerPid
+ ", workSource=" + newWorkSource);
}
final boolean unimportantForLogging = newOwnerUid == Process.SYSTEM_UID
&& (newFlags & PowerManager.UNIMPORTANT_FOR_LOGGING) != 0;
try {
mBatteryStats.noteChangeWakelockFromSource(workSource, ownerPid, tag, historyTag,
monitorType, newWorkSource, newOwnerPid, newTag, newHistoryTag,
newMonitorType, unimportantForLogging);
} catch (RemoteException ex) {
// Ignore
}
} else {
onWakeLockReleased(flags, tag, packageName, ownerUid, ownerPid, workSource, historyTag);
onWakeLockAcquired(newFlags, newTag, newPackageName, newOwnerUid, newOwnerPid,
newWorkSource, newHistoryTag);
}
}
@Override
public BrowserRoot onGetRoot(String clientPackageName, int clientUid, Bundle rootHints) {
if (clientPackageName == null || Process.SYSTEM_UID != clientUid && Process.myUid() != clientUid && !clientPackageName.equals("com.google.android.mediasimulator") && !clientPackageName.equals("com.google.android.projection.gearhead")) {
return null;
}
return new BrowserRoot(MEDIA_ID_ROOT, null);
}
public static int onGetCallingUid(int originUid) {
int callingPid = Binder.getCallingPid();
if (callingPid == Process.myPid()) {
return VClientImpl.get().getBaseVUid();
}
if (callingPid == VirtualCore.get().getSystemPid()) {
return Process.SYSTEM_UID;
}
int vuid = VActivityManager.get().getUidByPid(callingPid);
if (vuid != -1) {
return VUserHandle.getAppId(vuid);
}
VLog.d(TAG, "Unknown uid: " + callingPid);
return VClientImpl.get().getBaseVUid();
}
private void unsupportedStartingFrom(int version) {
if (Process.myUid() == Process.SYSTEM_UID) {
// The getApplicationInfo() call we make below is not supported in system context, and
// we want to allow the system to use these APIs anyway.
return;
}
if (mContext.getApplicationInfo().targetSdkVersion >= version) {
throw new UnsupportedOperationException(
"This method is not supported in target SDK version " + version + " and above");
}
}
private ContextImpl(@Nullable ContextImpl container, @NonNull ActivityThread mainThread,
@NonNull LoadedApk packageInfo, @Nullable String splitName,
@Nullable IBinder activityToken, @Nullable UserHandle user, int flags,
@Nullable ClassLoader classLoader) {
mOuterContext = this;
// If creator didn't specify which storage to use, use the default
// location for application.
if ((flags & (Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE
| Context.CONTEXT_DEVICE_PROTECTED_STORAGE)) == 0) {
final File dataDir = packageInfo.getDataDirFile();
if (Objects.equals(dataDir, packageInfo.getCredentialProtectedDataDirFile())) {
flags |= Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE;
} else if (Objects.equals(dataDir, packageInfo.getDeviceProtectedDataDirFile())) {
flags |= Context.CONTEXT_DEVICE_PROTECTED_STORAGE;
}
}
mMainThread = mainThread;
mActivityToken = activityToken;
mFlags = flags;
if (user == null) {
user = Process.myUserHandle();
}
mUser = user;
mPackageInfo = packageInfo;
mSplitName = splitName;
mClassLoader = classLoader;
mResourcesManager = ResourcesManager.getInstance();
if (container != null) {
mBasePackageName = container.mBasePackageName;
mOpPackageName = container.mOpPackageName;
setResources(container.mResources);
mDisplay = container.mDisplay;
} else {
mBasePackageName = packageInfo.mPackageName;
ApplicationInfo ainfo = packageInfo.getApplicationInfo();
if (ainfo.uid == Process.SYSTEM_UID && ainfo.uid != Process.myUid()) {
// Special case: system components allow themselves to be loaded in to other
// processes. For purposes of app ops, we must then consider the context as
// belonging to the package of this process, not the system itself, otherwise
// the package+uid verifications in app ops will fail.
mOpPackageName = ActivityThread.currentPackageName();
} else {
mOpPackageName = mBasePackageName;
}
}
mContentResolver = new ApplicationContentResolver(this, mainThread, user);
}
private void revokeRuntimePermission(String permName, String packageName,
boolean overridePolicy, int callingUid, int userId, PermissionCallback callback) {
if (!mUserManagerInt.exists(userId)) {
Log.e(TAG, "No such user:" + userId);
return;
}
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
"revokeRuntimePermission");
enforceCrossUserPermission(Binder.getCallingUid(), userId,
true, // requireFullPermission
true, // checkShell
false, // requirePermissionWhenSameUser
"revokeRuntimePermission");
final int appId;
final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
if (pkg == null || pkg.mExtras == null) {
throw new IllegalArgumentException("Unknown package: " + packageName);
}
if (mPackageManagerInt.filterAppAccess(pkg, Binder.getCallingUid(), userId)) {
throw new IllegalArgumentException("Unknown package: " + packageName);
}
final BasePermission bp = mSettings.getPermissionLocked(permName);
if (bp == null) {
throw new IllegalArgumentException("Unknown permission: " + permName);
}
bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg);
// If a permission review is required for legacy apps we represent
// their permissions as always granted runtime ones since we need
// to keep the review required permission flag per user while an
// install permission's state is shared across all users.
if (mSettings.mPermissionReviewRequired
&& pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
&& bp.isRuntime()) {
return;
}
final PackageSetting ps = (PackageSetting) pkg.mExtras;
final PermissionsState permissionsState = ps.getPermissionsState();
final int flags = permissionsState.getPermissionFlags(permName, userId);
// Only the system may revoke SYSTEM_FIXED permissions.
if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0
&& UserHandle.getCallingAppId() != Process.SYSTEM_UID) {
throw new SecurityException("Non-System UID cannot revoke system fixed permission "
+ permName + " for package " + packageName);
}
if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
throw new SecurityException("Cannot revoke policy fixed permission "
+ permName + " for package " + packageName);
}
if (bp.isDevelopment()) {
// Development permissions must be handled specially, since they are not
// normal runtime permissions. For now they apply to all users.
if (permissionsState.revokeInstallPermission(bp) !=
PermissionsState.PERMISSION_OPERATION_FAILURE) {
if (callback != null) {
callback.onInstallPermissionRevoked();
}
}
return;
}
if (permissionsState.revokeRuntimePermission(bp, userId) ==
PermissionsState.PERMISSION_OPERATION_FAILURE) {
return;
}
if (bp.isRuntime()) {
logPermission(MetricsEvent.ACTION_PERMISSION_REVOKED, permName, packageName);
}
if (callback != null) {
final int uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
callback.onPermissionRevoked(pkg.applicationInfo.uid, userId);
}
}
/**
* @return false if the caller is not authorized to get data from this MediaBrowserService
*/
@SuppressLint("BinaryOperationInTimber")
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
public boolean isCallerAllowed(Context context, String callingPackage, int callingUid) {
// Always allow calls from the framework, self app or development environment.
if (Process.SYSTEM_UID == callingUid || Process.myUid() == callingUid) {
return true;
}
if (isPlatformSigned(context, callingPackage)) {
return true;
}
PackageInfo packageInfo = getPackageInfo(context, callingPackage);
if (packageInfo == null) {
return false;
}
if (packageInfo.signatures.length != 1) {
Timber.w("Caller does not have exactly one signature certificate!");
return false;
}
String signature = Base64.encodeToString(
packageInfo.signatures[0].toByteArray(), Base64.NO_WRAP);
// Test for known signatures:
ArrayList<CallerInfo> validCallers = mValidCertificates.get(signature);
if (validCallers == null) {
Timber.v("Signature for caller %s is not valid: \n%s", callingPackage, signature);
if (mValidCertificates.isEmpty()) {
Timber.w("The list of valid certificates is empty. Either your file "
+ "res/xml/allowed_media_browser_callers.xml is empty or there was an error "
+ "while reading it. Check previous log messages.");
}
return false;
}
// Check if the package name is valid for the certificate:
StringBuilder expectedPackages = new StringBuilder();
for (CallerInfo info: validCallers) {
if (callingPackage.equals(info.packageName)) {
Timber.v("Valid caller: %s package= %s release=%s",
info.name, info.packageName, info.release);
return true;
}
expectedPackages.append(info.packageName).append(' ');
}
Timber.i("Caller has a valid certificate, but its package doesn't match any "
+ "expected package for the given certificate. Caller's package is " + callingPackage
+ ". Expected packages as defined in res/xml/allowed_media_browser_callers.xml are ("
+ expectedPackages + "). This caller's certificate is: \n" + signature);
return false;
}
private static void enforceSystemUid() {
final int uid = Binder.getCallingUid();
if (uid != Process.SYSTEM_UID) {
throw new SecurityException("Only available to AID_SYSTEM");
}
}
/**
* @return false if the caller is not authorized to get data from this MediaBrowserService
*/
@SuppressLint("PackageManagerGetSignatures")
boolean isCallerAllowed(Context context, String callingPackage, int callingUid) {
// Always allow calls from the framework, self app or development environment.
if (Process.SYSTEM_UID == callingUid || Process.myUid() == callingUid) {
return true;
}
final PackageManager packageManager = context.getPackageManager();
final PackageInfo packageInfo;
try {
packageInfo = packageManager
.getPackageInfo(callingPackage, PackageManager.GET_SIGNATURES);
} catch (PackageManager.NameNotFoundException e) {
Log.w(TAG, "Package manager can't find package: " + callingPackage, e);
return false;
}
if (packageInfo.signatures.length != 1) {
Log.w(TAG, "Caller has more than one signature certificate!");
return false;
}
final String signature = Base64.encodeToString(
packageInfo.signatures[0].toByteArray(), Base64.NO_WRAP);
// Test for known signatures:
final List<CallerInfo> validCallers = mValidCertificates.get(signature);
if (validCallers == null) {
if (Log.logVEnabled()) {
Log.v(TAG, "Signature for caller " + callingPackage + " is not valid: \n"
+ signature);
}
if (mValidCertificates.isEmpty()) {
Log.w(TAG, "The list of valid certificates is empty. Either your file " +
"res/xml/allowed_media_browser_callers.xml is empty or there was an error "
+ "while reading it. Check previous log messages.");
}
return false;
}
// Check if the package name is valid for the certificate:
final StringBuilder expectedPackages = new StringBuilder();
for (final CallerInfo info : validCallers) {
if (callingPackage.equals(info.packageName)) {
if (Log.logVEnabled()) {
Log.v(TAG, "Valid caller: " + info.name + " package=" + info.packageName
+ " release=" + info.release);
}
return true;
}
expectedPackages.append(info.packageName).append(' ');
}
if (Log.logIEnabled()) {
Log.i(TAG, "Caller has a valid certificate, but its package doesn't match any "
+ "expected package for the given certificate. Caller's package is "
+ callingPackage
+ ". Expected packages as defined in res/xml/allowed_media_browser_callers.xml are ("
+ expectedPackages + "). This caller's certificate is: \n" + signature);
}
return false;
}
private ContextImpl(@Nullable ContextImpl container, @NonNull ActivityThread mainThread,
@NonNull LoadedApk packageInfo, @Nullable String splitName,
@Nullable IBinder activityToken, @Nullable UserHandle user, int flags,
@Nullable ClassLoader classLoader) {
mOuterContext = this;
// If creator didn't specify which storage to use, use the default
// location for application.
if ((flags & (Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE
| Context.CONTEXT_DEVICE_PROTECTED_STORAGE)) == 0) {
final File dataDir = packageInfo.getDataDirFile();
if (Objects.equals(dataDir, packageInfo.getCredentialProtectedDataDirFile())) {
flags |= Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE;
} else if (Objects.equals(dataDir, packageInfo.getDeviceProtectedDataDirFile())) {
flags |= Context.CONTEXT_DEVICE_PROTECTED_STORAGE;
}
}
mMainThread = mainThread;
mActivityToken = activityToken;
mFlags = flags;
if (user == null) {
user = Process.myUserHandle();
}
mUser = user;
mPackageInfo = packageInfo;
mSplitName = splitName;
mClassLoader = classLoader;
mResourcesManager = ResourcesManager.getInstance();
if (container != null) {
mBasePackageName = container.mBasePackageName;
mOpPackageName = container.mOpPackageName;
setResources(container.mResources);
mDisplay = container.mDisplay;
} else {
mBasePackageName = packageInfo.mPackageName;
ApplicationInfo ainfo = packageInfo.getApplicationInfo();
if (ainfo.uid == Process.SYSTEM_UID && ainfo.uid != Process.myUid()) {
// Special case: system components allow themselves to be loaded in to other
// processes. For purposes of app ops, we must then consider the context as
// belonging to the package of this process, not the system itself, otherwise
// the package+uid verifications in app ops will fail.
mOpPackageName = ActivityThread.currentPackageName();
} else {
mOpPackageName = mBasePackageName;
}
}
mContentResolver = new ApplicationContentResolver(this, mainThread);
}
private void updatePermissionFlags(String permName, String packageName, int flagMask,
int flagValues, int callingUid, int userId, PermissionCallback callback) {
if (!mUserManagerInt.exists(userId)) {
return;
}
enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
enforceCrossUserPermission(callingUid, userId,
true, // requireFullPermission
true, // checkShell
false, // requirePermissionWhenSameUser
"updatePermissionFlags");
// Only the system can change these flags and nothing else.
if (callingUid != Process.SYSTEM_UID) {
flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
}
final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
if (pkg == null || pkg.mExtras == null) {
throw new IllegalArgumentException("Unknown package: " + packageName);
}
if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
throw new IllegalArgumentException("Unknown package: " + packageName);
}
final BasePermission bp;
synchronized (mLock) {
bp = mSettings.getPermissionLocked(permName);
}
if (bp == null) {
throw new IllegalArgumentException("Unknown permission: " + permName);
}
final PackageSetting ps = (PackageSetting) pkg.mExtras;
final PermissionsState permissionsState = ps.getPermissionsState();
final boolean hadState =
permissionsState.getRuntimePermissionState(permName, userId) != null;
final boolean permissionUpdated =
permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues);
if (permissionUpdated && callback != null) {
// Install and runtime permissions are stored in different places,
// so figure out what permission changed and persist the change.
if (permissionsState.getInstallPermissionState(permName) != null) {
callback.onInstallPermissionUpdated();
} else if (permissionsState.getRuntimePermissionState(permName, userId) != null
|| hadState) {
callback.onPermissionUpdated(new int[] { userId }, false);
}
}
}