Android Java 系统服务框架
我们在 Android 开发过程中经常会用到各种各样的系统管理服务,如进行窗口相关的操作会用到窗口管理服务 WindowManager,进行电源相关的操作会用到电源管理服务 PowerManager,还有很多其他的系统管理服务,如通知管理服务 NotifacationManager、振动管理服务 Vibrator、电池管理服务 BatteryManager......
这些 Manager 提供了很多对系统层的控制接口。对于 App 开发者,只需要了解这些接口的使用方式就可以方便的进行系统控制,获得系统各个服务的信息,而不需要了解这些接口的具体实现方式。而对于 Framework 开发者,则需要了解这些 Manager 服务的常用实现模式,维护这些 Manager 的接口,扩展这些接口,或者实现新的Manager。
我们从一个简单的系统服务 Vibrator 服务来看一下一个系统服务是怎样建立的。
Vibrator服务提供的控制手机振动的接口,应用可以调用 Vibrator 的接口来让手机产生振动,达到提醒用户的目的。 从源码(frameworks/base/core/java/android/os/Vibrator.java)中可以看到 Vibrator 是一个抽象类,常用的接口如下:
java
/*
* 是否有振动功能
*/
public abstract boolean hasVibrator();
/*
* 持续振动,但是已经 Deprecated 了
*/
@Deprecated
@RequiresPermission(android.Manifest.permission.VIBRATE)
public void vibrate(long milliseconds) {
vibrate(milliseconds, null);
}
/*
* 按节奏重复振动,但是已经 Deprecated 了
*/
@Deprecated
@RequiresPermission(android.Manifest.permission.VIBRATE)
public void vibrate(long[] pattern, int repeat) {
vibrate(pattern, repeat, null);
}
/*
* 用于代替上面两个接口
*/
@RequiresPermission(android.Manifest.permission.VIBRATE)
public void vibrate(VibrationEffect vibe) {
vibrate(vibe, null);
}
应用中使用振动服务的方法也很简单,如让手机持续振动500毫秒:
java
Vibrator mVibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
mVibrator.vibrate(500);
接着我们看下 Vibrator 的获取过程:
getSystemService 方法定义在 frameworks/base/core/java/android/app/ContextImpl.java
中:
java
@Override
public Object getSystemService(String name) {
return SystemServiceRegistry.getSystemService(this, name);
}
SystemServiceRegistry.getSystemService
定义在 frameworks/base/core/java/android/app/SystemServiceRegistry.java
中:
java
public static Object getSystemService(ContextImpl ctx, String name) {
ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
return fetcher != null ? fetcher.getService(ctx) : null;
}
上述代码使用了 SYSTEM_SERVICE_FETCHERS,SYSTEM_SERVICE_FETCHERS 是一个 Map 类型:
java
private static final Map<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS =
new ArrayMap<String, ServiceFetcher<?>>();
其数据通过 registerService
方法插入:
java
private static <T> void registerService(String serviceName, Class<T> serviceClass,
ServiceFetcher<T> serviceFetcher) {
SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName);
SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher);
}
在 SystemServiceRegistry 的静态块中调用了 registerService 插入 Vibrator 对象:
java
static {
registerService(Context.VIBRATOR_SERVICE, Vibrator.class,
new CachedServiceFetcher<Vibrator>() {
@Override
public Vibrator createService(ContextImpl ctx) {
return new SystemVibrator(ctx);
}});
}
这里传入了一个匿名对象,内部方法返回了一个 new 出来的 SystemVibrator,其具体实现如下:
java
// frameworks/base/core/java/android/os/SystemVibrator.java
// 客户端代理类的马甲
public class SystemVibrator extends Vibrator {
private static final String TAG = "Vibrator";
private final IVibratorService mService;
private final Binder mToken = new Binder();
@UnsupportedAppUsage
public SystemVibrator() {
mService = IVibratorService.Stub.asInterface(ServiceManager.getService("vibrator"));
}
@UnsupportedAppUsage
public SystemVibrator(Context context) {
super(context);
mService = IVibratorService.Stub.asInterface(ServiceManager.getService("vibrator"));
}
@Override
public boolean hasVibrator() {
if (mService == null) {
Log.w(TAG, "Failed to vibrate; no vibrator service.");
return false;
}
try {
return mService.hasVibrator();
} catch (RemoteException e) {
}
return false;
}
@Override
public boolean hasAmplitudeControl() {
if (mService == null) {
Log.w(TAG, "Failed to check amplitude control; no vibrator service.");
return false;
}
try {
return mService.hasAmplitudeControl();
} catch (RemoteException e) {
}
return false;
}
@Override
public void vibrate(int uid, String opPkg, VibrationEffect effect,
String reason, AudioAttributes attributes) {
if (mService == null) {
Log.w(TAG, "Failed to vibrate; no vibrator service.");
return;
}
try {
mService.vibrate(uid, opPkg, effect, attributes, reason, mToken);
} catch (RemoteException e) {
Log.w(TAG, "Failed to vibrate.", e);
}
}
@Override
public void cancel() {
if (mService == null) {
return;
}
try {
mService.cancelVibrate(mToken);
} catch (RemoteException e) {
Log.w(TAG, "Failed to cancel vibration.", e);
}
}
}
在构造函数中有我们熟悉的 AIDL 生成代码,通过 IVibratorService.Stub.asInterface
构建了一个 IVibratorService
代理类。SystemVibrator 通过 IVibratorService
代理类实现了 Vibrator 抽象类的对外接口。
IVibratorService 通过 AIDL 生成:
java
// frameworks/base/core/java/android/os/IVibratorService.aidl
package android.os;
import android.media.AudioAttributes;
import android.os.VibrationEffect;
/** {@hide} */
interface IVibratorService
{
boolean hasVibrator();
boolean hasAmplitudeControl();
void vibrate(int uid, String opPkg, in VibrationEffect effect, in AudioAttributes attributes,
String reason, IBinder token);
void cancelVibrate(IBinder token);
}
除了 AIDL 生成的代理端,还需要对应的服务端类,这个类是 VibratorService,需要自己实现:
java
// frameworks/base/services/core/java/com/android/server/VibratorService.java
public class VibratorService extends IVibratorService.Stub {
//......
}
振动器的实际操作都是通过 VibratorService 中的 native 函数实现,在 native 层中再调用到 hal 层,hal 层操作驱动,驱动操作实际硬件来完成。
接着我们再来看看,该系统服务是如何启动的:
java
// frameworks/base/services/java/com/android/server/SystemServer.java
private void startOtherServices() {
// ......
VibratorService vibrator = null;
// ......
traceBeginAndSlog("StartVibratorService");
vibrator = new VibratorService(context);
ServiceManager.addService("vibrator", vibrator);
traceEnd();
}
从上面的分析,我们可以总结出 Vibrator 服务的整个实现流程:
服务端
-
实现一个 AIDL 接口文件 IVibratorService(
frameworks/base/core/java/android/os/IVibratorService.aidl
),定义系统服务接口 -
定义 Binder 服务端实现类 VibratorService,实现 IVibratorService 定义的接口
frameworks/base/services/java/com/android/server/VibratorService.java
javapublic class VibratorService extends IVibratorService.Stub { //...... }
-
VibratorService 开机启动 frameworks/base/services/java/com/android/server/SystemServer.java
客户端
- 在
frameworks/base/core/java/android/content/Context.java
中添加服务注册名称, 添加该服务名称, 用于快捷注册和快捷引用 - 实现一个抽象类 Vibrator (
frameworks/base/core/java/android/os/Vibrator.java
),定义了应用中可以访问的一些抽象方法 - 定义 SystemVibrator 类 (
frameworks/base/core/java/android/os/SystemVibrator.java
),继承 Vibrator,实现抽象方法,实际就是 Vibrator Binder 服务端代理类马甲,所有的接口功能都是通过 Binder 服务端代理类实现。 - 在 SystemServiceRegistry 的静态块中调用了 registerService 插入 SystemVibrator 对象
第三方 App 使用自定义 Java 系统服务
在添加 Java 系统服务 中我们添加了一个 Java 系统服务,不过这个服务并没有按照 Android Java 系统服务框架
的要求编写,导致我们只能在系统 App 中使用我们自定义的 Java 系统服务,接下来我们根据上文的分析来改造它,使得我们能在第三方 App 中使用我们自定义的 Java 系统服务。
服务端不用改动,主要是客户端:
Context.java
中添加服务注册名称, 添加该服务名称, 用于快捷注册和快捷引用:
java
// frameworks/base/core/java/android/content/Context.java
public static final String JAVA_HELLO_SERVICE = "java_hello_service";
/** @hide */
@StringDef(suffix = { "_SERVICE" }, value = {
JAVA_HELLO_SERVICE,
POWER_SERVICE,
WINDOW_SERVICE,
//......
}
实现一个抽象类 JavaHello:
java
// frameworks/base/core/java/com/yuandaima/JavaHello.java
package com.yuandaima;
public abstract class JavaHello {
abstract void sayhello();
abstract int sayhello_to(String name);
}
定义 SystemJavaHello 类 ,继承 JavaHello,实现抽象方法:
java
package com.yuandaima;
import android.os.ServiceManager;
import android.os.RemoteException;
public class SystemJavaHello extends JavaHello {
private final IJavaHelloService mService;
public SystemJavaHello() {
mService = IJavaHelloService.Stub.asInterface(ServiceManager.getService("JavaHelloService"));
}
public void sayhello() {
if(mService != null) {
try {
mService.sayhello();
} catch (RemoteException e) {
}
}
}
public int sayhello_to(String name) {
if(mService != null) {
try {
return mService.sayhello_to(name);
} catch (RemoteException e) {
}
}
return 0;
}
}
接着在 frameworks/base/core/java/android/app/SystemServiceRegistry.java
的静态块中调用了 registerService 插入 SystemJavaHello 对象:
java
import com.yuandaima.SystemJavaHello;
import com.yuandaima.JavaHello;
static {
registerService(Context.JAVA_HELLO_SERVICE, JavaHello.class,
new CachedServiceFetcher<JavaHello>() {
@Override
public Vibrator createService(ContextImpl ctx) {
return new SystemJavaHello();
}});
}
在 Android 10 中,针对非 SDK 接口进行了限制,默认是 blacklist 的,为了让我们的 App 能使用我们自定义的 Java 服务,需要在 frameworks/base/config/hiddenapi-greylist-packages.txt
中最后一行增加:
bash
com.yuandaima
接着编译系统启动模拟器:
bash
source build/envsetup.sh
lunch rice14-eng
make update-api
make -j32
emulator
然后编译 App 使用的 Jar 包:
bash
source build/envsetup.sh
lunch rice14-eng
# Android10 及以前
make framework
# Android11 及以后
#make framework-minus-apex
编译完成后,我们在 out/target/common/obj/JAVA_LIBRARIES/framework_intermediates 目录下找到 classes.jar 文件,为方便识别,我们将该文件拷贝到其他地方,并将文件名修改为 framework.jar
使用 Android Studio(推荐版本 3.6.3) 创建一个 Empty Activity 空项目。接着把之前准备好的 framework.jar 拷贝到项目的 app/framework 文件夹中。
接着修改项目根目录下的 build.gradle,添加如下内容:
groovy
allprojects {
gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
//相对位置,根据存放的位置修改路径
options.compilerArgs.add('-Xbootclasspath/p:app/framework/framework.jar')
}
}
repositories {
google()
jcenter()
}
}
接着修改 app/build.gradle:
groovy
dependencies {
compileOnly files('framework/framework.jar')
//.......
}
最后在 MainActivity 中加入使用自定义服务的代码:
java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
JavaHello javaHello = (JavaHello) getSystemService(Context.JAVA_HELLO_SERVICE);
javaHello.sayhello_to("test");
}
}
接着添加 selinux 配置:
同时修改 system/sepolicy/private 和 system/sepolicy/prebuilts/api/29.0/private 目录下的:
untrusted_app.te
arduino
allow untrusted_app JavaHelloServiceType:service_manager find;
接着运行启动 App,就可以在看到我们调用成功的 Log 了: