SystemService 相关介绍

2021-10-31  本文已影响0人  fsdffdaga
  1. 在 SystemServer 中将 Service 添加到 ServiceManager 中:
VibratorService vibrator = null;

t.traceBegin("StartVibratorService");
vibrator = new VibratorService(context);
ServiceManager.addService("vibrator", vibrator);
t.traceEnd();

t.traceBegin("MakeVibratorServiceReady");
try {
    vibrator.systemReady();
} catch (Throwable e) {
    reportWtf("making Vibrator Service ready", e);
}
t.traceEnd();
  1. 在对应的 XxxManager (此处为 VibratorService.java) 中获取服务器端的代理
private final IVibratorService mService;
mService = IVibratorService.Stub.asInterface(ServiceManager.getService("vibrator"));

// 或下面,asInterface 的参数实际上市 IBinder 类型
// 有些地方还是采用的 ServiceManager.getServiceOrThrow 形式
// IBinder b = ServiceManager.getServiceOrThrow(Context.LOCATION_SERVICE);
IBinder b = ServiceManager.getService("vibrator");
mService = IVibratorService.Stub.asInterface(b);

一般在 XxxManager 的构造中获取的代理,fw 中相关的引用命名都为 mService, 可以通过正则 "mService = .+Stub" 搜索。或者 ServiceManager.getService 搜索

捕获.PNG
  1. 获取 XxxxManager(下文讲如何获取这个), 调用它的方法。因为在 XxxxManager 中已经有 mService 存在了,他就可以调用服务端的方法(这个方法就是aidl中声明的)。如:此处的 XxxxManager 为 Vibrator --> SystemVibrator
@Override
public boolean hasVibrator() {
    if (mService == null) {
        Log.w(TAG, "Failed to vibrate; no vibrator service.");
        return false;
    }
    try {
        return mService.hasVibrator(); // 此处 binder 跨进程调用服务端的方法
    } catch (RemoteException e) {
    }
    return false;
}
Vibrator mVibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);

从上看出是通过 Context(实际是 ContextImpl ) 的 getSystemService(Context.VIBRATOR_SERVICE) 获取

ContextImol.java

@Override
public Object getSystemService(String name) {
    if (vmIncorrectContextUseEnabled()) {
        // We may override this API from outer context.
        final boolean isUiContext = isUiContext() || isOuterUiContext();
        // Check incorrect Context usage.
        if (isUiComponent(name) && !isUiContext) {
            final String errorMessage = "Tried to access visual service "
                    + SystemServiceRegistry.getSystemServiceClassName(name)
                    + " from a non-visual Context:" + getOuterContext();
            final String message = "Visual services, such as WindowManager, WallpaperService "
                    + "or LayoutInflater should be accessed from Activity or other visual "
                    + "Context. Use an Activity or a Context created with "
                    + "Context#createWindowContext(int, Bundle), which are adjusted to "
                    + "the configuration and visual bounds of an area on screen.";
            final Exception exception = new IllegalAccessException(errorMessage);
            StrictMode.onIncorrectContextUsed(message, exception);
            Log.e(TAG, errorMessage + " " + message, exception);
        }
    }
    return SystemServiceRegistry.getSystemService(this, name); // 核心,具体实现
}

SystemServiceRegistry
可以看到是根据 Service 的 name, 通一个 map: SYSTEM_SERVICE_FETCHERS 中获取到 ServiceFetcher,并且在根据 context 获取到真正的 XxxManager (ret).

/**
 * Gets a system service from a given context.
 * @hide
 */
public static Object getSystemService(ContextImpl ctx, String name) {
    ...
    final ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name); 
    final Object ret = fetcher.getService(ctx);
    ...
    return ret;
}

再追溯源,看这个 map 是如何保存的:

private static final Map<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS =
            new ArrayMap<String, ServiceFetcher<?>>();

/**
 * Statically registers a system service with the context.
 * This method must be called during static initialization only.
 */
private static <T> void registerService(@NonNull String serviceName,
        @NonNull Class<T> serviceClass, @NonNull ServiceFetcher<T> serviceFetcher) {
    SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName);
    SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher); // 此处 put 的
    SYSTEM_SERVICE_CLASS_NAMES.put(serviceName, serviceClass.getSimpleName());
}

继续追 registerService 的调用,参数中传递了 Service 的 name:

static {
    registerService(Context.VIBRATOR_SERVICE, Vibrator.class,
            new CachedServiceFetcher<Vibrator>() {
        @Override
        public Vibrator createService(ContextImpl ctx) {
            return new SystemVibrator(ctx);
        }});A
}

同时在 SystemServiceRegistry 的 static 块中,发现了大量的 registerService,好多系统服务都通通过 registerService 在回调 createService 中 通过 new 对应的 XxxxManager 来获取客户端调用的 Manager 的,再如:

registerService(Context.KEYGUARD_SERVICE, KeyguardManager.class,
        new CachedServiceFetcher<KeyguardManager>() {
    @Override
    public KeyguardManager createService(ContextImpl ctx) throws ServiceNotFoundException {
        return new KeyguardManager(ctx);
    }});

提下其他大量的 registerService:


360软件小助手截图20211031192500.jpg

另外,为何有些 XxxManager 中没有 Service.Stub.asInterface
大多数 XxxxManager 可能如上面这样写,但是有些没有,但是并不影响其通过 Binder 引用调用 Service 的方法。
如:

registerService(Context.ACCOUNT_SERVICE, AccountManager.class,
        new CachedServiceFetcher<AccountManager>() {
    @Override
    public AccountManager createService(ContextImpl ctx) throws ServiceNotFoundException {
        IBinder b = ServiceManager.getServiceOrThrow(Context.ACCOUNT_SERVICE);
        IAccountManager service = IAccountManager.Stub.asInterface(b);
        return new AccountManager(ctx, service);  // 已经提前获取了,直接传递到了 AccountManager 中了
    }});
上一篇下一篇

猜你喜欢

热点阅读