diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java index 2a23d60d8af6b..c9a1843589255 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java +++ b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java @@ -273,10 +273,12 @@ public final class JobServiceContext implements ServiceConnection { // another binding flag for that. bindFlags = Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND | Context.BIND_ALMOST_PERCEPTIBLE - | Context.BIND_ALLOW_NETWORK_ACCESS; + | Context.BIND_ALLOW_NETWORK_ACCESS + | Context.BIND_NOT_APP_COMPONENT_USAGE; } else { bindFlags = Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND - | Context.BIND_NOT_PERCEPTIBLE; + | Context.BIND_NOT_PERCEPTIBLE + | Context.BIND_NOT_APP_COMPONENT_USAGE; } binding = mContext.bindServiceAsUser(intent, this, bindFlags, UserHandle.of(job.getUserId())); diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index f3a4e1f799552..02e86cd4a863f 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -369,6 +369,15 @@ public abstract class Context { /*********** Public flags above this line ***********/ /*********** Hidden flags below this line ***********/ + /** + * Flag for {@link #bindService}: This flag is only intended to be used by the system to + * indicate that a service binding is not considered as real package component usage and should + * not generate a {@link android.app.usage.UsageEvents.Event#APP_COMPONENT_USED} event in usage + * stats. + * @hide + */ + public static final int BIND_NOT_APP_COMPONENT_USAGE = 0x00008000; + /** * Flag for {@link #bindService}: allow the process hosting the target service to be treated * as if it's as important as a perceptible app to the user and avoid the oom killer killing diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index d998ebbf4aff9..277cb8c877ddd 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -86,6 +86,7 @@ import android.app.Service; import android.app.ServiceStartArgs; import android.app.admin.DevicePolicyEventLogger; import android.app.compat.CompatChanges; +import android.app.usage.UsageEvents; import android.appwidget.AppWidgetManagerInternal; import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledSince; @@ -2464,6 +2465,10 @@ public final class ActiveServices { s.setAllowedBgFgsStartsByBinding(true); } + if ((flags & Context.BIND_NOT_APP_COMPONENT_USAGE) != 0) { + s.isNotAppComponentUsage = true; + } + if (s.app != null) { updateServiceClientActivitiesLocked(s.app.mServices, c, true); } @@ -3332,6 +3337,14 @@ public final class ActiveServices { return msg; } + // Report usage if binding is from a different package except for explicitly exempted + // bindings + if (!r.appInfo.packageName.equals(r.mRecentCallingPackage) + && !r.isNotAppComponentUsage) { + mAm.mUsageStatsService.reportEvent( + r.packageName, r.userId, UsageEvents.Event.APP_COMPONENT_USED); + } + // Service is now being launched, its package can't be stopped. try { AppGlobals.getPackageManager().setPackageStoppedState( diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java index 3ab95d131fadd..9cd9902f4995f 100644 --- a/services/core/java/com/android/server/am/ServiceRecord.java +++ b/services/core/java/com/android/server/am/ServiceRecord.java @@ -107,6 +107,7 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN boolean delayed; // are we waiting to start this service in the background? boolean fgRequired; // is the service required to go foreground after starting? boolean fgWaiting; // is a timeout for going foreground already scheduled? + boolean isNotAppComponentUsage; // is service binding not considered component/package usage? boolean isForeground; // is service currently in foreground mode? int foregroundId; // Notification ID of last foreground req. Notification foregroundNoti; // Notification record of foreground state.