Ahao's Technical Blog Ahao's Technical Blog
首页
  • 001.基础篇
  • 002.玩转AOSP篇
  • 003.学穿Binder篇
  • 004.基础组件篇
  • 005.系统启动过程分析
  • 006.Hal开发入门与实践
  • 007.显示系统
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

阿豪讲Framework

不积跬步无以至千里
首页
  • 001.基础篇
  • 002.玩转AOSP篇
  • 003.学穿Binder篇
  • 004.基础组件篇
  • 005.系统启动过程分析
  • 006.Hal开发入门与实践
  • 007.显示系统
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 基础篇

  • 玩转AOSP篇

  • 学穿Binder篇

    • 000.Binder 专题导学 —— 如何深入掌握 Binder
    • 001.学习 Binder 的预备知识
    • 002.Binder 基本原理
    • 003.Binder 程序示例之 C 语言篇
    • 004.Binder 服务注册过程情景分析之 C 语言篇
    • 005.Binder 服务获取与使用过程情景分析之C语言篇
    • 006.Android Binder 驱动框架设计与分析
    • 007.Binder 驱动情景分析之 ServiceManager 启动过程
    • 008.Binder 驱动情景分析之服务注册过程
    • 009.Binder 驱动情景分析之服务获取与使用过程
    • 010.Binder 程序示例之 C++ 篇
    • 011.Binder C++ 程序分析之主要类解析
    • 012.Binder 服务注册过程情景分析之 C++ 篇
    • 013.Binder 服务获取与使用过程情景分析之C++篇
    • 014.Binder 程序示例之 aidl-cpp 篇
    • 015.添加 Android Native 系统服务
    • 016.添加 Native 系统服务回调
    • 017.Binder 程序示例之 Java 篇
    • 018.Binder Java 层初始化
    • 019.Binder Java 层服务注册过程分析
    • 020.Binder Java 层服务获取与使用过程分析
    • 021.添加 Java 系统服务
    • 022.Android Java 系统服务框架与第三方 App 使用自定义 Java 系统服务
      • Android Java 系统服务框架
      • 第三方 App 使用自定义 Java 系统服务
      • 参考资料
    • 023.添加 Java 系统服务回调
    • 024.AIDL 数据类型详解之 Java 篇
    • 025.AIDL 数据类型详解之 C++ 篇
    • 026.Java 调用 Native 服务
    • 027.Native 调用 Java Binder 服务
    • 028.AIDL 关键字 in out inout oneway 解析
    • 029.Binder 驱动 Debug 入门指南
    • 030.Binder 匿名服务源码分析
    • 031.Binder 中的 Parcel 数据结构分析(C++)
    • 032.Binder 中的 Parcel 数据结构分析(Java)
    • 033.Binder 多线程情景分析
    • 034.Binder 线程池溢出问题
    • 035.Binder 代理对象泄露问题分析
    • 036.Binder 死亡通知情景分析
    • 037.Binder 异常处理机制
    • 038.Binder 系统源码演进
    • 039.Binder 面试题汇总
    • 补充——LocalService
  • 基础组件篇

  • 系统启动过程分析

  • Hal开发入门与实践

  • 显示系统

  • Framework
  • 学穿Binder篇
阿豪
2023-08-03
目录

022.Android Java 系统服务框架与第三方 App 使用自定义 Java 系统服务

# Android Java 系统服务框架

我们在 Android 开发过程中经常会用到各种各样的系统管理服务,如进行窗口相关的操作会用到窗口管理服务 WindowManager,进行电源相关的操作会用到电源管理服务 PowerManager,还有很多其他的系统管理服务,如通知管理服务 NotifacationManager、振动管理服务 Vibrator、电池管理服务 BatteryManager……

这些 Manager 提供了很多对系统层的控制接口。对于 App 开发者,只需要了解这些接口的使用方式就可以方便的进行系统控制,获得系统各个服务的信息,而不需要了解这些接口的具体实现方式。而对于 Framework 开发者,则需要了解这些 Manager 服务的常用实现模式,维护这些 Manager 的接口,扩展这些接口,或者实现新的Manager。

我们从一个简单的系统服务 Vibrator 服务来看一下一个系统服务是怎样建立的。

Vibrator 服务提供了控制手机振动器的接口,应用可以调用 Vibrator 的接口,让手机产生振动,达到提醒用户的目的。

从源码中可以看到 Vibrator 是一个抽象类,常用的接口如下:

    // frameworks/base/core/java/android/os/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);
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

应用中使用振动服务的方法也很简单,如让手机持续振动500毫秒:

Vibrator mVibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
mVibrator.vibrate(500);
1
2

接着我们看下 Vibrator 的获取过程:

getSystemService 方法定义在 frameworks/base/core/java/android/app/ContextImpl.java 中:

@Override
public Object getSystemService(String name) {
    return SystemServiceRegistry.getSystemService(this, name);
}
1
2
3
4

SystemServiceRegistry.getSystemService 定义在 frameworks/base/core/java/android/app/SystemServiceRegistry.java 中:

public static Object getSystemService(ContextImpl ctx, String name) {
    ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
    return fetcher != null ? fetcher.getService(ctx) : null;
}
1
2
3
4

上述代码使用了 SYSTEM_SERVICE_FETCHERS,SYSTEM_SERVICE_FETCHERS 是一个 Map 类型:

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

在 SystemServiceRegistry 的静态块中调用了 registerService 插入 Vibrator 对象:

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

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);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

这里传入了一个匿名对象,内部方法返回了一个 new 出来的 SystemVibrator,其具体实现如下:

// 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);
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71

在构造函数中有我们熟悉的 AIDL 生成代码,通过 IVibratorService.Stub.asInterface 构建了一个 IVibratorService 代理类。SystemVibrator 通过 IVibratorService 代理类实现了 Vibrator 抽象类的对外接口。

IVibratorService 通过 AIDL 生成:

// 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);
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

代理端类又 AIDL 生成,服务端类 VibratorService,需要自己实现:

// frameworks/base/services/core/java/com/android/server/VibratorService.java

public class VibratorService extends IVibratorService.Stub {
    //......

}
1
2
3
4
5
6

振动器的实际操作都是通过 VibratorService 中的 native 函数实现,在 native 层中再调用到 hal 层,hal 层操作驱动,驱动操作实际硬件来完成。

接着我们再来看看,VibratorService 系统服务是如何启动的:

// 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();
}
1
2
3
4
5
6
7
8
9
10

从上面的分析,我们可以总结出 Vibrator 服务的整个实现流程:

服务端

  1. 实现一个 AIDL 接口文件 IVibratorService(frameworks/base/core/java/android/os/IVibratorService.aidl),定义系统服务接口
  2. 定义 Binder 服务端实现类 VibratorService,实现 IVibratorService 定义的接口 frameworks/base/services/java/com/android/server/VibratorService.java
    public class VibratorService extends IVibratorService.Stub {
     //......
    }
    
    1
    2
    3
  3. VibratorService 开机启动 frameworks/base/services/java/com/android/server/SystemServer.java

客户端

  1. 在 frameworks/base/core/java/android/content/Context.java 中添加服务注册名称, 添加该服务名称, 用于快捷注册和快捷引用
  2. 实现一个抽象类 Vibrator (frameworks/base/core/java/android/os/Vibrator.java),定义了应用中可以访问的一些抽象方法
  3. 定义 SystemVibrator 类 (frameworks/base/core/java/android/os/SystemVibrator.java),继承 Vibrator,实现抽象方法,实际就是 Vibrator Binder 服务端代理类马甲,所有的接口功能都是通过 Binder 服务端代理类实现。
  4. 在 SystemServiceRegistry 的静态块中调用了 registerService 插入 SystemVibrator 对象

# 第三方 App 使用自定义 Java 系统服务

在添加 Java 系统服务 (opens new window) 中我们添加了一个 Java 系统服务,不过这个服务并没有按照 Android Java 系统服务框架 的要求编写,导致我们只能在系统 App 中使用我们自定义的 Java 系统服务,接下来我们根据上文的分析来改造它,使得我们能在第三方 App 中使用我们自定义的 Java 系统服务。

服务端不用改动,主要是客户端:

Context.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,
            //......
    }    
1
2
3
4
5
6
7
8
9
10

实现一个抽象类 JavaHello,用于定义服务对外的接口:

// frameworks/base/core/java/com/yuandaima/JavaHello.java
package com.yuandaima;

public abstract class JavaHello {
    public abstract void sayhello();
	public abstract int sayhello_to(String name);
}
1
2
3
4
5
6
7

定义 SystemJavaHello 类 ,继承 JavaHello,实现抽象方法:

// frameworks/base/core/java/com/yuandaima/SystemJavaHello.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;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

接着在 frameworks/base/core/java/android/app/SystemServiceRegistry.java 的静态块中调用了 registerService 插入 SystemJavaHello 对象:

import com.yuandaima.SystemJavaHello;
import com.yuandaima.JavaHello;

static {
        registerService(Context.JAVA_HELLO_SERVICE, JavaHello.class,
            new CachedServiceFetcher<JavaHello>() {
        @Override
        public JavaHello createService(ContextImpl ctx) {
            return new SystemJavaHello();
        }});
}
1
2
3
4
5
6
7
8
9
10
11

在 Android 10 中,针对非 SDK 接口进行了限制,默认是 blacklist 的,为了让我们的 App 能使用我们自定义的 Java 服务,需要在 frameworks/base/config/hiddenapi-greylist-packages.txt 中最后一行增加:

com.yuandaima
1

接着编译系统启动模拟器:

source build/envsetup.sh
lunch  rice14-eng
#make update-api
make -j32
emulator
1
2
3
4
5

然后编译 App 使用的 Jar 包:

source build/envsetup.sh
lunch rice14-eng
# Android10 及以前
make framework
# Android11 及以后
#make framework-minus-apex
1
2
3
4
5
6

编译完成后,我们在 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,添加如下内容:

allprojects {

    gradle.projectsEvaluated {
        tasks.withType(JavaCompile) {
            //相对位置,根据存放的位置修改路径
            options.compilerArgs.add('-Xbootclasspath/p:app/framework/framework.jar')
        }
    }

    repositories {
        google()
        jcenter()
        
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

接着修改 app/build.gradle:

dependencies {
    compileOnly files('framework/framework.jar')
    //.......
}
1
2
3
4

最后在 MainActivity 中加入使用自定义服务的代码:

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");
    }
}
1
2
3
4
5
6
7
8
9
10
11

接着添加 selinux 配置:

同时修改 system/sepolicy/private 和 system/sepolicy/prebuilts/api/29.0/private 目录下的:

untrusted_app.te

allow untrusted_app JavaHelloServiceType:service_manager find;
1

接着运行启动 App,就可以在看到我们调用成功的 Log 了:

# 参考资料

  • Android系统服务(SystemService)简介 (opens new window)
021.添加 Java 系统服务
023.添加 Java 系统服务回调

← 021.添加 Java 系统服务 023.添加 Java 系统服务回调→

最近更新
01
如何调试 SurfaceFlinger
10-05
02
SurfaceFlinger 概述
10-05
03
HWC 接口分析
10-05
更多文章>
Theme by Vdoing | Copyright © 2020-2025 AHao Framework | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式