Merge "Allow package verifier to hide specific fgs notifications." into rvc-qpr-dev am: 1706f9c22f

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/12378562

Change-Id: I49a977a18f40504b7bea8e0280d975cccb18c897
This commit is contained in:
Kweku Adams
2020-08-19 17:25:05 +00:00
committed by Automerger Merge Worker
6 changed files with 58 additions and 13 deletions

View File

@@ -186,6 +186,16 @@ class ContextImpl extends Context {
private static final String XATTR_INODE_CACHE = "user.inode_cache";
private static final String XATTR_INODE_CODE_CACHE = "user.inode_code_cache";
/**
* Special intent extra that critical system apps can use to hide the notification for a
* foreground service. This extra should be placed in the intent passed into {@link
* #startForegroundService(Intent)}.
*
* @hide
*/
private static final String EXTRA_HIDDEN_FOREGROUND_SERVICE =
"android.intent.extra.HIDDEN_FOREGROUND_SERVICE";
/**
* Map from package name, to preference name, to cached preferences.
*/
@@ -1697,9 +1707,12 @@ class ContextImpl extends Context {
try {
validateServiceIntent(service);
service.prepareToLeaveProcess(this);
final boolean hideForegroundNotification = requireForeground
&& service.getBooleanExtra(EXTRA_HIDDEN_FOREGROUND_SERVICE, false);
ComponentName cn = ActivityManager.getService().startService(
mMainThread.getApplicationThread(), service,
service.resolveTypeIfNeeded(getContentResolver()), requireForeground,
hideForegroundNotification,
getOpPackageName(), getAttributionTag(), user.getIdentifier());
if (cn != null) {
if (cn.getPackageName().equals("!")) {

View File

@@ -155,7 +155,8 @@ interface IActivityManager {
boolean refContentProvider(in IBinder connection, int stableDelta, int unstableDelta);
PendingIntent getRunningServiceControlPanel(in ComponentName service);
ComponentName startService(in IApplicationThread caller, in Intent service,
in String resolvedType, boolean requireForeground, in String callingPackage,
in String resolvedType, boolean requireForeground,
boolean hideForegroundNotification, in String callingPackage,
in String callingFeatureId, int userId);
@UnsupportedAppUsage
int stopService(in IApplicationThread caller, in Intent service,

View File

@@ -453,16 +453,16 @@ public final class ActiveServices {
}
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
int callingPid, int callingUid, boolean fgRequired, String callingPackage,
@Nullable String callingFeatureId, final int userId)
int callingPid, int callingUid, boolean fgRequired, boolean hideFgNotification,
String callingPackage, @Nullable String callingFeatureId, final int userId)
throws TransactionTooLargeException {
return startServiceLocked(caller, service, resolvedType, callingPid, callingUid, fgRequired,
callingPackage, callingFeatureId, userId, false);
hideFgNotification, callingPackage, callingFeatureId, userId, false);
}
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
int callingPid, int callingUid, boolean fgRequired, String callingPackage,
@Nullable String callingFeatureId, final int userId,
int callingPid, int callingUid, boolean fgRequired, boolean hideFgNotification,
String callingPackage, @Nullable String callingFeatureId, final int userId,
boolean allowBackgroundActivityStarts) throws TransactionTooLargeException {
if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "startService: " + service
+ " type=" + resolvedType + " args=" + service.getExtras());
@@ -609,6 +609,7 @@ public final class ActiveServices {
r.startRequested = true;
r.delayedStop = false;
r.fgRequired = fgRequired;
r.hideFgNotification = hideFgNotification;
r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
service, neededGrants, callingUid));

View File

@@ -1438,6 +1438,10 @@ public class ActivityManagerService extends IActivityManager.Stub
final Injector mInjector;
/** The package verifier app. */
private String mPackageVerifier;
private int mPackageVerifierUid = UserHandle.USER_NULL;
static final class ProcessChangeItem {
static final int CHANGE_ACTIVITIES = 1<<0;
static final int CHANGE_FOREGROUND_SERVICES = 1<<1;
@@ -2362,6 +2366,18 @@ public class ActivityManagerService extends IActivityManager.Stub
if (phase == PHASE_SYSTEM_SERVICES_READY) {
mService.mBatteryStatsService.systemServicesReady();
mService.mServices.systemServicesReady();
mService.mPackageVerifier = ArrayUtils.firstOrNull(
LocalServices.getService(PackageManagerInternal.class).getKnownPackageNames(
PackageManagerInternal.PACKAGE_VERIFIER, UserHandle.USER_SYSTEM));
if (mService.mPackageVerifier != null) {
try {
mService.mPackageVerifierUid =
getContext().getPackageManager().getPackageUid(
mService.mPackageVerifier, UserHandle.USER_SYSTEM);
} catch (NameNotFoundException e) {
Slog.wtf(TAG, "Package manager couldn't get package verifier uid", e);
}
}
} else if (phase == PHASE_ACTIVITY_MANAGER_READY) {
mService.startBroadcastObservers();
} else if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
@@ -15007,8 +15023,8 @@ public class ActivityManagerService extends IActivityManager.Stub
@Override
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, boolean requireForeground, String callingPackage,
String callingFeatureId, int userId)
String resolvedType, boolean requireForeground, boolean hideForegroundNotification,
String callingPackage, String callingFeatureId, int userId)
throws TransactionTooLargeException {
enforceNotIsolatedCaller("startService");
// Refuse possible leaked file descriptors
@@ -15020,17 +15036,27 @@ public class ActivityManagerService extends IActivityManager.Stub
throw new IllegalArgumentException("callingPackage cannot be null");
}
final int callingUid = Binder.getCallingUid();
if (requireForeground && hideForegroundNotification) {
if (!UserHandle.isSameApp(callingUid, mPackageVerifierUid)
|| !callingPackage.equals(mPackageVerifier)) {
throw new IllegalArgumentException(
"Only the package verifier can hide its foreground service notification");
}
Slog.i(TAG, "Foreground service notification hiding requested by " + callingPackage);
}
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
"*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
synchronized(this) {
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
ComponentName res;
try {
res = mServices.startServiceLocked(caller, service,
resolvedType, callingPid, callingUid,
requireForeground, callingPackage, callingFeatureId, userId);
requireForeground, hideForegroundNotification,
callingPackage, callingFeatureId, userId);
} finally {
Binder.restoreCallingIdentity(origId);
}
@@ -19470,7 +19496,7 @@ public class ActivityManagerService extends IActivityManager.Stub
ComponentName res;
try {
res = mServices.startServiceLocked(null, service,
resolvedType, -1, uid, fgRequired, callingPackage,
resolvedType, -1, uid, fgRequired, false, callingPackage,
callingFeatureId, userId, allowBackgroundActivityStarts);
} finally {
Binder.restoreCallingIdentity(origId);

View File

@@ -654,7 +654,7 @@ final class ActivityManagerShellCommand extends ShellCommand {
pw.println("Starting service: " + intent);
pw.flush();
ComponentName cn = mInterface.startService(null, intent, intent.getType(),
asForeground, SHELL_PACKAGE_NAME, null, mUserId);
asForeground, false, SHELL_PACKAGE_NAME, null, mUserId);
if (cn == null) {
err.println("Error: Not found; no service started.");
return -1;

View File

@@ -104,6 +104,7 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
boolean whitelistManager; // any bindings to this service have BIND_ALLOW_WHITELIST_MANAGEMENT?
boolean delayed; // are we waiting to start this service in the background?
boolean fgRequired; // is the service required to go foreground after starting?
boolean hideFgNotification; // Hide the fg service notification
boolean fgWaiting; // is a timeout for going foreground already scheduled?
boolean isForeground; // is service currently in foreground mode?
int foregroundId; // Notification ID of last foreground req.
@@ -823,6 +824,9 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
}
public void postNotification() {
if (hideFgNotification) {
return;
}
final int appUid = appInfo.uid;
final int appPid = app.pid;
if (foregroundId != 0 && foregroundNoti != null) {
@@ -915,7 +919,7 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
}
if (localForegroundNoti.getSmallIcon() == null) {
// Notifications whose icon is 0 are defined to not show
// a notification, silently ignoring it. We don't want to
// a notification. We don't want to
// just ignore it, we want to prevent the service from
// being foreground.
throw new RuntimeException("invalid service notification: "