System Service 是如何写的?
应用调用
DisplayManager dm = getSystemService(DisplayManager.class);
dm.setTemporaryBrightness(0.0f);
Settings.System.putInt(getContentResolver(), Settings.System.SCREEN_BRIGHTNESS, 0);
看下 getSystemService 方法,在 Context 类里。
Context#getSystemService
public final @Nullable <T> T getSystemService(@NonNull Class<T> serviceClass) {
// Because subclasses may override getSystemService(String) we cannot
// perform a lookup by class alone. We must first map the class to its
// service name then invoke the string-based method.
String serviceName = getSystemServiceName(serviceClass);
return serviceName != null ? (T)getSystemService(serviceName) : null;
}
public abstract @Nullable String getSystemServiceName(@NonNull Class<?> serviceClass);
ContextImpl#getSystemService
@Override
public String getSystemServiceName(Class<?> serviceClass) {
return SystemServiceRegistry.getSystemServiceName(serviceClass);
}
继续跟 SystemServiceRegistry.getSystemServiceName。
SystemServiceRegistry#getSystemServiceName
public static String getSystemServiceName(Class<?> serviceClass) {
if (serviceClass == null) {
return null;
}
final String serviceName = SYSTEM_SERVICE_NAMES.get(serviceClass);
if (sEnableServiceNotFoundWtf && serviceName == null) {
// This should be a caller bug.
Slog.wtf(TAG, "Unknown manager requested: " + serviceClass.getCanonicalName());
}
return serviceName;
}
什么时候 registerService 的?
public final class SystemServiceRegistry {
static {
registerService(Context.DISPLAY_SERVICE, DisplayManager.class,
new CachedServiceFetcher<DisplayManager>() {
@Override
public DisplayManager createService(ContextImpl ctx) {
return new DisplayManager(ctx.getOuterContext());
}
});
}
}
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);
SYSTEM_SERVICE_CLASS_NAMES.put(serviceName, serviceClass.getSimpleName());
}
结合上面的分析代码可以知道 getSystemService(DisplayManager.class)得到的是一个 DisplayManager 的实例。
接下来看 dm.setTemporaryBrightness 方法。
DisplayManager#setTemporaryBrightness
public void setTemporaryBrightness(float brightness) {
mGlobal.setTemporaryBrightness(brightness);
}
mGlobal 是 DisplayManagerGlobal 对象。
DisplayManagerGlobal#setTemporaryBrightness
private final IDisplayManager mDm;
private DisplayManagerGlobal(IDisplayManager dm) {
mDm = dm;
}
public static DisplayManagerGlobal getInstance() {
synchronized (DisplayManagerGlobal.class) {
if (sInstance == null) {
IBinder b = ServiceManager.getService(Context.DISPLAY_SERVICE);
if (b != null) {
sInstance = new DisplayManagerGlobal(IDisplayManager.Stub.asInterface(b));
}
}
return sInstance;
}
}
public void setTemporaryBrightness(float brightness) {
try {
mDm.setTemporaryBrightness