接上一篇博客ActivityManagerService和ActivityTaskManagerService启动详解—Android 12(一),介绍了SystemServer.starBootstrapServices()中启动AMS和ATMS所做的工作,这一节介绍在SystemServer.startCoreServices()中关于AMS和ATMS设置UsageStateManagerInternal服务来跟踪application使用状态的业务。
目录
1. AMS和ATMS设置UsageStateManagerInternal服务
1.1 AMS.setUsageStatsManager()
1.2 ATMS.setUsageStatsManager()
1.4.1 UsageStatsService.onStart()
1.4.2 UsageStatsService的内部类BinderService
1.4.3 UsageStatsService的内部类LocalServicce
1. AMS和ATMS设置UsageStateManagerInternal服务
// /frameworks/base/services/java/com/android/server/SystemServer.java
public final class SystemServer implements Dumpable {
private void startCoreServices(@NonNull TimingsTraceAndSlog t) {
// Tracks application usage stats.
t.traceBegin("StartUsageService");
mSystemServiceManager.startService(UsageStatsService.class);
mActivityManagerService.setUsageStatsManager(
LocalServices.getService(UsageStatsManagerInternal.class));
t.traceEnd();
}
}
1.1 AMS.setUsageStatsManager()
// /frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public class ActivityManagerService extends IActivityManager.Stub
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback, ActivityManagerGlobalLock {
public void setUsageStatsManager(@NonNull UsageStatsManagerInternal usageStatsManager) {
mUsageStatsService = usageStatsManager;
mActivityTaskManager.setUsageStatsManager(usageStatsManager);
}
}
1.2 ATMS.setUsageStatsManager()
// /frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
synchronized (mGlobalLock) {
mUsageStatsInternal = usageStatsManager;
}
}
}
1.3 UsageStatsManagerInternal
它是UsageStatsService的本地系统服务接口,源码参考地址:UsageStatsManagerInternal.java - OpenGrok cross reference for /frameworks/base/services/core/java/android/app/usage/UsageStatsManagerInternal.java
// /frameworks/base/services/core/java/android/app/usage/UsageStatsManagerInternal.java
public abstract class UsageStatsManagerInternal {
public abstract void reportEvent(ComponentName component, @UserIdInt int userId, int eventType,
int instanceId, ComponentName taskRoot);
public abstract void reportEvent(String packageName, @UserIdInt int userId, int eventType);
public abstract void reportConfigurationChange(Configuration config, @UserIdInt int userId);
public abstract void reportContentProviderUsage(String name, String pkgName,
@UserIdInt int userId);
public abstract void reportLocusUpdate(@NonNull ComponentName activity, @UserIdInt int userId,
@Nullable LocusId locusId, @NonNull IBinder appToken);
/**
* Prepares the UsageStatsService for shutdown.
*/
public abstract void prepareShutdown();
/**
* When the device power button is long pressed for 3.5 seconds, prepareForPossibleShutdown()
* is called.
*/
public abstract void prepareForPossibleShutdown();
public abstract List<UsageStats> queryUsageStatsForUser(@UserIdInt int userId, int interval,
long beginTime, long endTime, boolean obfuscateInstantApps);
public abstract void reportAppJobState(String packageName, @UserIdInt int userId,
int numDeferredJobs, long timeSinceLastJobRun);
public abstract void reportSyncScheduled(String packageName, @UserIdInt int userId,
boolean exempted);
public abstract AppUsageLimitData getAppUsageLimit(String packageName, UserHandle user);
public interface UsageEventListener {
/** Callback to inform listeners of a new usage event. */
void onUsageEvent(@UserIdInt int userId, @NonNull UsageEvents.Event event);
}
public abstract void registerListener(@NonNull UsageEventListener listener);
public abstract void unregisterListener(@NonNull UsageEventListener listener);
}
该本地服务是SSM.startService()时在UsageStatsService.onStart()中注册到LocalServices中的。
1.4 UsageStatsService
该系统服务主要负责收集、聚合和持久化application使用数据。这些数据可以被AppOps授权的应用查询。它的持久化数据保存路径为data/system/usagestats。
1.4.1 UsageStatsService.onStart()
- 把UsageStatsManagerInternal服务和对应的实例注册LocalServices中;
- 把BinderServce以name=usagestats注册到servicemanager中。
// /frameworks/base/services/usage/java/com/android/server/usage/UsageStatsService.java
public class UsageStatsService extends SystemService implements
UserUsageStatsService.StatsUpdatedListener {
public UsageStatsService(Context context) {
this(context, new Injector());
}
@Override
public void onStart() {
mAppOps = (AppOpsManager) getContext().getSystemService(Context.APP_OPS_SERVICE);
mUserManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE);
mPackageManager = getContext().getPackageManager();
mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
mHandler = new H(BackgroundThread.get().getLooper());
...
//把UsageStasManagerInternal服务注册到LocalServices中
publishLocalService(UsageStatsManagerInternal.class, new LocalService());
publishLocalService(AppStandbyInternal.class, mAppStandby);
//把UsageStatsService以name=usagestats注册到servicemanager中
publishBinderServices();
}
void publishBinderServices() {
publishBinderService(Context.USAGE_STATS_SERVICE, new BinderService());
}
}
1.4.2 UsageStatsService的内部类BinderService
// /frameworks/base/services/usage/java/com/android/server/usage/UsageStatsService.java
public class UsageStatsService extends SystemService implements
UserUsageStatsService.StatsUpdatedListener {
@Override
public void onStart() {
...
//把UsageStatsService以name=usagestats注册到servicemanager中
publishBinderServices();
}
void publishBinderServices() {
publishBinderService(Context.USAGE_STATS_SERVICE, new BinderService());
}
//由于UsageStatsService继承了SystemService, 所以内部类BinderService extends
//IUsageStatsManager.Stub, 作为服务端,这样同样实现了使用AIDL与其他app交互。
private final class BinderService extends IUsageStatsManager.Stub {
private boolean hasPermissions(String callingPackage, String... permissions) {
final int callingUid = Binder.getCallingUid();
if (callingUid == Process.SYSTEM_UID) {
// Caller is the system, so proceed.
return true;
}
boolean hasPermissions = true;
final Context context = getContext();
for (int i = 0; i < permissions.length; i++) {
hasPermissions = hasPermissions && (context.checkCallingPermission(permissions[i])
== PackageManager.PERMISSION_GRANTED);
}
return hasPermissions;
}
@Override
public ParceledListSlice<UsageStats> queryUsageStats(int bucketType, long beginTime,
long endTime, String callingPackage, int userId) {
if (!hasPermission(callingPackage)) {
return null;
}
...
}
}
}
1.4.3 UsageStatsService的内部类LocalServicce
该LocalServicce继承了UsageStatsManagerInternal,该本地服务主要供AMS使用。AMS会持有am锁来调用LocalService中的方法,所以在这些方法中不应有IO操作或者其他耗时任务。
// /frameworks/base/services/usage/java/com/android/server/usage/UsageStatsService.java
public class UsageStatsService extends SystemService implements
UserUsageStatsService.StatsUpdatedListener {
@Override
public void onStart() {
...
//把UsageStasManagerInternal服务注册到LocalServices中
publishLocalService(UsageStatsManagerInternal.class, new LocalService());
}
//该LocalServicce继承了UsageStatsManagerInternal,该本地服务主要供AMS使用,
//AMS会持有am锁来调用LocalService中的方法,所以在这些方法中不应有IO操作或者其他耗时任务
private final class LocalService extends UsageStatsManagerInternal {
@Override
public void reportEvent(ComponentName component, int userId, int eventType,
int instanceId, ComponentName taskRoot) {
if (component == null) {
Slog.w(TAG, "Event reported without a component name");
return;
}
Event event = new Event(eventType, SystemClock.elapsedRealtime());
event.mPackage = component.getPackageName();
event.mClass = component.getClassName();
event.mInstanceId = instanceId;
if (taskRoot == null) {
event.mTaskRootPackage = null;
event.mTaskRootClass = null;
} else {
event.mTaskRootPackage = taskRoot.getPackageName();
event.mTaskRootClass = taskRoot.getClassName();
}
reportEventOrAddToQueue(userId, event);
}
@Override
public void reportEvent(String packageName, int userId, int eventType) {
if (packageName == null) {
Slog.w(TAG, "Event reported without a package name, eventType:" + eventType);
return;
}
Event event = new Event(eventType, SystemClock.elapsedRealtime());
event.mPackage = packageName;
reportEventOrAddToQueue(userId, event);
}
...
}
}
2. 创建系统服务的步骤
UsageStatsService的代码让我发现创建系统服务的另一种形式,创建需要和application等其他进程通过AIDL通信的步骤:
(1). 创建新的系统服务类直接继承SystemService,重写onStart()。
(2). 创建内部类,继承ICustomizeManager.stub
(3). 在onStart()中调用publishBinderService(String name, IBinder service)注册到servicemanager中。
//第一步
public CustomizeSystemService extends SystemService {
@Override
public void onStart() {
//第三步:把CustomizeBinderService注册到servicemanager中
publishBinderService(Context.CUSTOMIZE_SERVICE, new CustomizeBinderService());
}
//第二步
private final class CustomizeBinderService extends ICustomizeManager.Stub {
//重写AIDL文件中的方法
}
}
使用最多的形式参考 请参考Framework层添加SystemService和Manager的超详细步骤