Android添加系统服务
基于android 12
添加服务
frameworks/base/services/java/com/android/server/SystemServer.java
在这两个函数中都可以添加:
startCoreServices()
startOtherServices()
比如说:
t.traceBegin("StartPowerStatsService");
// Tracks rail data to be used for power statistics.
mSystemServiceManager.startService(PowerStatsService.class);
t.traceEnd();
获取服务
frameworks/base/core/java/android/os/ServiceManager.java
比如说:
PackageManagerService pm = (PackageManagerService)ServiceManager.getService("package");
例子:
下面通过VibratorManagerService看一个完整的例子:
- 首先aidl定义接口:
frameworks/base/core/java/android/os/IVibratorManagerService.aidl
/** {@hide} */
interface IVibratorManagerService {
int[] getVibratorIds();
VibratorInfo getVibratorInfo(int vibratorId);
boolean isVibrating(int vibratorId);
boolean registerVibratorStateListener(int vibratorId, in IVibratorStateListener listener);
boolean unregisterVibratorStateListener(int vibratorId, in IVibratorStateListener listener);
boolean setAlwaysOnEffect(int uid, String opPkg, int alwaysOnId,
in CombinedVibration vibration, in VibrationAttributes attributes);
void vibrate(int uid, String opPkg, in CombinedVibration vibration,
in VibrationAttributes attributes, String reason, IBinder token);
void cancelVibrate(int usageFilter, IBinder token);
}
- VibratorManagerService 继承 IVibratorManagerService.Stub 实现aidl接口
frameworks/base/services/core/java/com/android/server/vibrator/VibratorManagerService.java
public class VibratorManagerService extends IVibratorManagerService.Stub {
...
@Override // Binder call
public int[] getVibratorIds() {
return Arrays.copyOf(mVibratorIds, mVibratorIds.length);
}
@Override // Binder call
@Nullable
public VibratorInfo getVibratorInfo(int vibratorId) {
VibratorController controller = mVibrators.get(vibratorId);
return controller == null ? null : controller.getVibratorInfo();
}
@Override // Binder call
public boolean isVibrating(int vibratorId) {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.ACCESS_VIBRATOR_STATE,
"isVibrating");
VibratorController controller = mVibrators.get(vibratorId);
return controller != null && controller.isVibrating();
}
...
}
- 客户端代理,App通过SystemVibratorManager调用, mService就是VibratorManagerService在客户端的实例
frameworks/base/core/java/android/os/SystemVibratorManager.java
public class SystemVibratorManager extends VibratorManager {
public SystemVibratorManager(Context context) {
super(context);
mContext = context;
mService = IVibratorManagerService.Stub.asInterface( // 通过aidl获取远程binder服务
ServiceManager.getService(Context.VIBRATOR_MANAGER_SERVICE));
}
@NonNull
@Override
public int[] getVibratorIds() {
synchronized (mLock) {
if (mVibratorIds != null) {
return mVibratorIds;
}
try {
if (mService == null) {
Log.w(TAG, "Failed to retrieve vibrator ids; no vibrator manager service.");
} else {
return mVibratorIds = mService.getVibratorIds();
}
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
return new int[0];
}
}
...
}
getSystemService流程:
context.getSystemService() -> contextImpl.getSystemService -> SystemServiceRegistry.getSystemService
从SYSTEM_SERVICE_FETCHERS获取的,put在registerService函数中.
registerService又封装了registerContextAwareService, registerStaticService,用于注册服务
frameworks/base/core/java/android/app/SystemServiceRegistry.java
public static Object getSystemService(ContextImpl ctx, String name) {
...
final ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
final Object ret = fetcher.getService(ctx);
...
}
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());
}
// 在静态代码块中通过registerService注册服务
static {
// 注册VIBRATOR_MANAGER_SERVICE,实际new的SystemVibratorManager,
// VibratorManager是个抽象类, 实现的是 SystemVibratorManager
registerService(Context.VIBRATOR_MANAGER_SERVICE, VibratorManager.class,
new CachedServiceFetcher<VibratorManager>() {
@Override
public VibratorManager createService(ContextImpl ctx) {
return new SystemVibratorManager(ctx); //
}});
...
}
回到VibratorManagerService上,再看看VibratorManagerService如何通过jni到hal实现控制硬件震动
vibrate() --> startVibrationLocked() -->
@Override // Binder call
public void vibrate(int uid, String opPkg, @NonNull CombinedVibration effect,
@Nullable VibrationAttributes attrs, String reason, IBinder token) {
...
Vibration vib = new Vibration(token, mNextVibrationId.getAndIncrement(), effect, attrs,
uid, opPkg, reason);
fillVibrationFallbacks(vib, effect); //effect 新的特征,不管他
...
final long ident = Binder.clearCallingIdentity();
try {
if (mCurrentVibration != null) {
mCurrentVibration.cancel();
}
// 主要是startVibrationLocked
Vibration.Status status = startVibrationLocked(vib);
if (status != Vibration.Status.RUNNING) {
endVibrationLocked(vib, status);
}
} finally {
Binder.restoreCallingIdentity(ident);
}
...
}
@GuardedBy("mLock")
private Vibration.Status startVibrationLocked(Vibration vib) {
...
VibrationThread vibThread = new VibrationThread(vib, mVibrationSettings,
mDeviceVibrationEffectAdapter, mVibrators, mWakeLock, mBatteryStatsService,
mVibrationCallbacks);
if (mCurrentVibration == null) {
return startVibrationThreadLocked(vibThread);
}
mNextVibration = vibThread;
return Vibration.Status.RUNNING;
}
@GuardedBy("mLock")
private Vibration.Status startVibrationThreadLocked(VibrationThread vibThread) {
Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "startVibrationThreadLocked");
try {
Vibration vib = vibThread.getVibration();
int mode = startAppOpModeLocked(vib.uid, vib.opPkg, vib.attrs);
switch (mode) {
case AppOpsManager.MODE_ALLOWED: // 正常走这
Trace.asyncTraceBegin(Trace.TRACE_TAG_VIBRATOR, "vibration", 0);
mCurrentVibration = vibThread;
mCurrentVibration.start(); //重点
return Vibration.Status.RUNNING;
case AppOpsManager.MODE_ERRORED:
Slog.w(TAG, "Start AppOpsManager operation errored for uid " + vib.uid);
return Vibration.Status.IGNORED_ERROR_APP_OPS;
default:
return Vibration.Status.IGNORED_APP_OPS;
}
} finally {
Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
}
}
VibrationThread.start() --> playVibration()
@Override
public void run() {
Process.setThreadPriority(Process.THREAD_PRIORITY_URGENT_DISPLAY);
mWakeLock.acquire();
try {
mVibration.token.linkToDeath(this, 0);
playVibration();
mCallbacks.onVibratorsReleased();
} catch (RemoteException e) {
Slog.e(TAG, "Error linking vibration to token death", e);
} finally {
mVibration.token.unlinkToDeath(this, 0);
mWakeLock.release();
}
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 凌晨三点救火实录:Java内存泄漏的七个神坑,你至少踩过三个!