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篇

  • 基础组件篇

  • 系统启动过程分析

  • Hal开发入门与实践

    • 001.Android HAL 层概览
    • 002.传统 Hal 开发指南1 —— 开发环境准备
    • 003.传统 Hal 开发指南2 —— 传统 HAL 整体架构
    • 004.传统 Hal 开发指南3 —— 驱动开发
    • 005.传统 Hal 开发指南4 —— 实现一个简单的 Hal 模块
    • 006.传统 Hal 开发指南5 —— 添加硬件访问服务
    • 007.传统 Hal 开发指南6 —— 开发一个 App 访问硬件服务
    • 008.HIDL HAL 开发指南1 —— 开发环境准备
    • 009.HIDL Hal 开发指南2 —— Android 8 HAL 变迁
    • 010.HIDL Hal 开发指南3 —— HIDL HAL 实例程序
    • 011.HIDL Hal 开发指南4 —— Binderized HALs 实例分析
    • 012.HIDL Hal 开发指南5 —— Passthrough HALs 实例分析
    • 013.HIDL Hal 开发指南6 —— Same-Process HALs 实例分析
    • 014.HIDL Hal 开发指南7 —— 驱动开发
    • 015.HIDL Hal 开发指南8 —— 简单 HIDL HAL 实现
    • 016.HIDL Hal 开发指南9 —— 添加硬件访问服务
    • 017.HIDL Hal 开发指南10 —— 开发一个 App 访问硬件服务
    • 018.AIDL Hal 开发指南1—— 开发环境准备
    • 019.AIDL Hal 开发指南2 —— AIDL HAL 整体架构
    • 020.AIDL Hal 开发指南 3 ———— AIDL HAL 实例分析1
    • 021.AIDL Hal 开发指南 4 ———— AIDL HAL 实例分析2
    • 022.AIDL Hal 开发指南5 —— stable-c HAL 实例分析
    • 023.AIDL Hal 开发指南6 —— 驱动开发
    • 024.AIDL Hal 开发指南7 —— 实现一个简单的 AIDL HAL
    • 025.AIDL Hal 开发指南8 —— 添加硬件访问服务
      • 定义 AIDL
      • 硬件服务 Server 端实现
      • 硬件服务客户端辅助代码实现
      • App 访问硬件服务
      • Selinux 配置
      • 编译运行
      • 参考资料
    • 026.AIDL Hal 开发指南10 —— AIDL HAL 的升级
  • 显示系统

  • Framework
  • Hal开发入门与实践
阿豪
2024-04-16
目录

025.AIDL Hal 开发指南8 —— 添加硬件访问服务

# 定义 AIDL

创建 aidl 文件 frameworks/base/core/java/android/hardware/hello/IHelloHalManager.aidl:

package android.hardware.hello;

/**
 * {@hide}
 */
interface IHelloHalManager {
    void hellohal_write(String str);
    String hellohal_read();
}
1
2
3
4
5
6
7
8
9

下面的 Android.bp 已经包含了该目录下几乎所有 aidl 文件和 java 文件的编译,所以我们不需要再将自定义的 IHelloHalManager.aidl 添加到编译环境

// frameworks/base/core/java/Android.bp
filegroup {
    name: "framework-core-sources",
    srcs: [                                                                                                                                                                                                            
        "**/*.java",
        "**/*.aidl",
    ],  
    exclude_srcs: [
        // Remove election toolbar code from build time
        "android/service/selectiontoolbar/*.aidl",
        "android/service/selectiontoolbar/*.java",
        "android/view/selectiontoolbar/*.aidl",
        "android/view/selectiontoolbar/*.java",
        "com/android/internal/widget/floatingtoolbar/RemoteFloatingToolbarPopup.java",
    ],
    visibility: ["//frameworks/base"],
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

接着编译:

source build/envsetup.sh
lunch aosp_cf_x86_64_phone-eng
make update-api
make framework-minus-apex -j32
1
2
3
4

然后再 out 目录下搜索:

cd out
find . -name "IHelloManager*"
./soong/.intermediates/frameworks/base/framework-minus-apex/android_common/gen/aidl/frameworks/base/core/java/android/hardware/hello/IHelloManager.aidl.d
./soong/.intermediates/frameworks/base/framework-minus-apex/android_common/javac/shard38/classes/android/hardware/hello/IHelloManager.class
./soong/.intermediates/frameworks/base/framework-minus-apex/android_common/javac/shard38/classes/android/hardware/hello/IHelloManager$Stub$Proxy.class
./soong/.intermediates/frameworks/base/framework-minus-apex/android_common/javac/shard38/classes/android/hardware/hello/IHelloManager$Stub.class
./soong/.intermediates/frameworks/base/framework-minus-apex/android_common/javac/shard38/classes/android/hardware/hello/IHelloManager$Default.class
./soong/.intermediates/frameworks/base/api/system-api-stubs-docs-non-updatable/android_common/gen/aidl/frameworks/base/core/java/android/hardware/hello/IHelloManager.aidl.d
./soong/.intermediates/frameworks/base/api/test-api-stubs-docs-non-updatable/android_common/gen/aidl/frameworks/base/core/java/android/hardware/hello/IHelloManager.aidl.d
./soong/.intermediates/frameworks/base/api/module-lib-api-stubs-docs-non-updatable/android_common/gen/aidl/frameworks/base/core/java/android/hardware/hello/IHelloManager.aidl.d
./soong/.intermediates/frameworks/base/api/api-stubs-docs-non-updatable/android_common/gen/aidl/frameworks/base/core/java/android/hardware/hello/IHelloManager.aidl.d
1
2
3
4
5
6
7
8
9
10
11

不同于之前的版本生成 java 源文件,这里生成的都是 class 文件,可以用你喜欢的反编译工具来查看具体的源码(我使用的是 vscode 的插件 Decompiler for Java):

接口的定义:

package .home.zzh0838.Project.aosp.android-14.0.0_r15.out.soong..intermediates.frameworks.base.framework-minus-apex.android_common.javac.shard38.classes.android.hardware.hello;

import android.os.IInterface;
import android.os.RemoteException;

public interface IHelloManager extends IInterface {
  public static final String DESCRIPTOR = "android.hardware.hello.IHelloManager";
  
  void hellohal_write(String paramString) throws RemoteException;
  
  String hellohal_read() throws RemoteException;
}
1
2
3
4
5
6
7
8
9
10
11
12

接口默认空实现:

package .home.zzh0838.Project.aosp.android-14.0.0_r15.out.soong..intermediates.frameworks.base.framework-minus-apex.android_common.javac.shard38.classes.android.hardware.hello;

import android.hardware.hello.IHelloManager;
import android.os.IBinder;
import android.os.RemoteException;

public class Default implements IHelloManager {
  public void hellohal_write(String str) throws RemoteException {}
  
  public String hellohal_read() throws RemoteException {
    return null;
  }
  
  public IBinder asBinder() {
    return null;
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

服务端 Stub 类的实现:

package .home.zzh0838.Project.aosp.android-14.0.0_r15.out.soong..intermediates.frameworks.base.framework-minus-apex.android_common.javac.shard38.classes.android.hardware.hello;

import android.hardware.hello.IHelloManager;
import android.os.Binder;
import android.os.IBinder;
import android.os.IInterface;
import android.os.Parcel;
import android.os.RemoteException;

public abstract class Stub extends Binder implements IHelloManager {
  static final int TRANSACTION_hellohal_write = 1;
  
  static final int TRANSACTION_hellohal_read = 2;
  
  public Stub() {
    attachInterface((IInterface)this, "android.hardware.hello.IHelloManager");
  }
  
  public static IHelloManager asInterface(IBinder obj) {
    if (obj == null)
      return null; 
    IInterface iin = obj.queryLocalInterface("android.hardware.hello.IHelloManager");
    if (iin != null && iin instanceof IHelloManager)
      return (IHelloManager)iin; 
    return (IHelloManager)new Proxy(obj);
  }
  
  public IBinder asBinder() {
    return (IBinder)this;
  }
  
  public static String getDefaultTransactionName(int transactionCode) {
    switch (transactionCode) {
      case 1:
        return "hellohal_write";
      case 2:
        return "hellohal_read";
    } 
    return null;
  }
  
  public String getTransactionName(int transactionCode) {
    this;
    return getDefaultTransactionName(transactionCode);
  }
  
  public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
    String _arg0, _result, descriptor = "android.hardware.hello.IHelloManager";
    if (code >= 1 && code <= 16777215)
      data.enforceInterface(descriptor); 
    switch (code) {
      case 1598968902:
        reply.writeString(descriptor);
        return true;
    } 
    switch (code) {
      case 1:
        _arg0 = data.readString();
        data.enforceNoDataAvail();
        hellohal_write(_arg0);
        reply.writeNoException();
        return true;
      case 2:
        _result = hellohal_read();
        reply.writeNoException();
        reply.writeString(_result);
        return true;
    } 
    return super.onTransact(code, data, reply, flags);
  }
  
  public int getMaxTransactionId() {
    return 1;
  }
}
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
72
73
74
75

代理类 Proxy 的实现:

package .home.zzh0838.Project.aosp.android-14.0.0_r15.out.soong..intermediates.frameworks.base.framework-minus-apex.android_common.javac.shard38.classes.android.hardware.hello;

import android.hardware.hello.IHelloManager;
import android.os.IBinder;
import android.os.Parcel;
import android.os.RemoteException;

class Proxy implements IHelloManager {
  private IBinder mRemote;
  
  Proxy(IBinder remote) {
    this.mRemote = remote;
  }
  
  public IBinder asBinder() {
    return this.mRemote;
  }
  
  public String getInterfaceDescriptor() {
    return "android.hardware.hello.IHelloManager";
  }
  
  public void hellohal_write(String str) throws RemoteException {
    Parcel _data = Parcel.obtain(asBinder());
    Parcel _reply = Parcel.obtain();
    try {
      _data.writeInterfaceToken("android.hardware.hello.IHelloManager");
      _data.writeString(str);
      boolean _status = this.mRemote.transact(1, _data, _reply, 0);
      _reply.readException();
    } finally {
      _reply.recycle();
      _data.recycle();
    } 
  }
  
  public String hellohal_read() throws RemoteException {
    String _result;
    Parcel _data = Parcel.obtain(asBinder());
    Parcel _reply = Parcel.obtain();
    try {
      _data.writeInterfaceToken("android.hardware.hello.IHelloManager");
      boolean _status = this.mRemote.transact(2, _data, _reply, 0);
      _reply.readException();
      _result = _reply.readString();
    } finally {
      _reply.recycle();
      _data.recycle();
    } 
    return _result;
  }
}
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

基本就是 java binder 那一套东西,没什么特别要说的

# 硬件服务 Server 端实现

在 frameworks/base/services/core/java/com/android/server 目录下添加:

hello/
└── HelloService.java
1
2

其中 HelloService.java 的内容如下:

package com.android.server.hello;

import android.Manifest;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.content.Context;
import android.hardware.hello.*;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.Trace;
import android.provider.Settings;
import android.util.Slog;
import android.util.SparseArray;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.display.BrightnessSynchronizer;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.Preconditions;
import com.android.server.SystemService;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.annotation.NonNull;
import android.hardware.hello.IHelloManager;
import android.hardware.hello.IHelloHal;


public class HelloService extends SystemService {

    // aidl hal 服务
    private IHelloHal mVintfHelloHal = null;
    // SystemServer 中的硬件服务
    private IHelloManager mHelloManager = null;

    private final class HelloManagerService extends IHelloManager.Stub { 
        
        @Override
        public void hellohal_write( @NonNull String str) throws android.os.RemoteException {
            try {
                if(mVintfHelloHal != null) {
                    mVintfHelloHal.hello_write(str);
                }
                
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }
        
        @Override
        public String hellohal_read() throws android.os.RemoteException {

            try {
                if(mVintfHelloHal != null) {
                    return mVintfHelloHal.hello_read();
                }
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }

            return "";
           
        }
    }

    public HelloService( Context context ) {
        super(context);
        IBinder binder = Binder.allowBlocking(
                        ServiceManager.waitForDeclaredService(IHelloHal.DESCRIPTOR + "/default"));
        if (binder != null) {
            mVintfHelloHal = IHelloHal.Stub.asInterface(binder);
        }

        mHelloManager = new HelloManagerService();

    }

    @Override
    public void onStart() {
        publishBinderService(Context.HELLO_SERVICE, (IBinder)mHelloManager);
    }

    @Override
    public void onBootPhase(int phase) {
    }
}
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95

接着在 SystemServer 中添加启动服务的代码:

    // 不要忘了导包
    import com.android.server.hello.HelloService;

    private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {
        // ......
        t.traceBegin("StartHelloHalService");
        mSystemServiceManager.startService(HelloService.class);
        t.traceEnd();
        //......
    }
1
2
3
4
5
6
7
8
9
10

# 硬件服务客户端辅助代码实现

接着创建客户端的接口:

// frameworks/base/core/java/android/hardware/hello/HelloServiceManager.java
package android.hardware.hello;

import android.annotation.SystemService;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Singleton;
import android.os.ServiceManager;
import android.annotation.Nullable;

/**
 * { @hide }
 */
public final class HelloServiceManager {

    final Context mContext;

    /*
     * @hide
     */
    public HelloServiceManager (Context systemContext) {
        mContext = systemContext;
    }

    /**
     * @hide 只能系统调用
     */
    public static IHelloManager getServerice(){
        return I_HELLOHAL_MANAGER_SINGLETON.get();
    }

    //限制framework中的定义无法被外部应用访问
    @UnsupportedAppUsage
    private static final Singleton<IHelloManager> I_HELLOHAL_MANAGER_SINGLETON =
            new Singleton<IHelloManager>() {
                @Override
                protected IHelloManager create() {
                    final IBinder b= ServiceManager.getService(Context.HELLO_SERVICE);
                    final IHelloManager m = IHelloManager.Stub.asInterface(b);
                    return m;
                }
    };
    
    
    public void hellohal_write( @Nullable String str){
        try{
            getServerice().hellohal_write(str);
            return;
        }catch (RemoteException e){
            throw e.rethrowFromSystemServer();
        }
    }

    @Nullable
    public String hellohal_read() {
        try{
            return getServerice().hellohal_read();
        }catch (RemoteException e){
            throw e.rethrowFromSystemServer();
        }
    }
}
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

接着修改 frameworks/base/core/java/android/app/SystemServiceRegistry.java:

// 不要忘了 import 包
import android.hardware.hello.HelloHalManager;
import android.hardware.hello.SystemHelloHalManager;
static {
    //......
        registerService(Context.HELLO_SERVICE, HelloServiceManager.class,
            new CachedServiceFetcher<HelloServiceManager>() {
                @Override
                public HelloServiceManager createService(ContextImpl ctx)
                    throws ServiceNotFoundException {
                    return new HelloServiceManager();
                }});
    //......
    
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

接着编译:

source build/envsetup.sh
lunch aosp_cf_x86_64_phone-eng
make update-api
make framework-minus-apex -j32
1
2
3
4

# App 访问硬件服务

简单起见,这里我们直接在 Launcher 中加访问硬件服务的代码。

// packages/apps/Launcher3/src/com/android/launcher3/Launcher.java

// 不要忘了导包
import android.hardware.hello.HelloServiceManager;
import android.content.Context;

    protected void onCreate(Bundle savedInstanceState) {

        HelloServiceManager manager = (HelloServiceManager) getSystemService(Context.HELLO_SERVICE);
        manager.hellohal_write("nihao");
    }
1
2
3
4
5
6
7
8
9
10
11

# Selinux 配置

在 system/sepolicy/prebuilts/api/34.0/private/service.te 和 system/sepolicy/private/service.te 中添加:

type hello_service, app_api_service, ephemeral_app_api_service, system_server_service, service_manager_type;
1

在 system/sepolicy/prebuilts/api/34.0/private/service_contexts 和 system/sepolicy/private/service_contexts 中添加:

hello                                     u:object_r:hello_service:s0
1

在 system/sepolicy/prebuilts/api/34.0/private/system_app.te 和 system/sepolicy/private/system_app.te:

allow system_app hello_service:service_manager find;
1

# 编译运行

接着编译运行:

# 编译
source build/envsetup.sh
lunch aosp_cf_x86_64_phone-eng
make update-api
m
cvd start  -kernel_path=/home/zzh0838/Project/aosp/kernel/out/virtual_device_x86_64/dist/bzImage  -initramfs_path=/home/zzh0838/Project/aosp/kernel/out/virtual_device_x86_64/dist/initramfs.img
1
2
3
4
5
6

接着看 log:

adb logcat | grep hello

04-16 19:41:52.108     0     0 W         : drivers/char/hello_driver.c hello_init line 69
04-16 19:41:53.579     0     0 I init    : Parsing file /vendor/etc/init/android.hardware.hello.rc...
04-16 19:41:58.342     0     0 I init    : starting service 'vendor.hellohal-default'...
04-16 19:41:58.371     0     0 I init    : ... started service 'vendor.hellohal-default' has pid 339
04-16 19:41:58.440     0     0 I servicemanager: Found android.hardware.hello.IHelloHal/default in device VINTF manifest.
04-16 19:42:05.028   564   564 I SystemServiceManager: Starting com.android.server.hello.HelloService
04-16 19:42:05.075     0     0 I servicemanager: Found android.hardware.hello.IHelloHal/default in device VINTF manifest.
04-16 19:42:05.037   564   564 D SystemServerTiming: OnBootPhase_100_com.android.server.hello.HelloService
04-16 19:42:05.037   564   564 V SystemServerTiming: OnBootPhase_100_com.android.server.hello.HelloService took to complete: 0ms
04-16 19:42:07.167   564   564 D SystemServerTiming: OnBootPhase_200_com.android.server.hello.HelloService
04-16 19:42:07.167   564   564 V SystemServerTiming: OnBootPhase_200_com.android.server.hello.HelloService took to complete: 0ms
04-16 19:42:20.697   564   564 D SystemServerTiming: OnBootPhase_480_com.android.server.hello.HelloService
04-16 19:42:20.697   564   564 V SystemServerTiming: OnBootPhase_480_com.android.server.hello.HelloService took to complete: 0ms
04-16 19:42:20.748   564   564 D SystemServerTiming: OnBootPhase_500_com.android.server.hello.HelloService
04-16 19:42:20.748   564   564 V SystemServerTiming: OnBootPhase_500_com.android.server.hello.HelloService took to complete: 0ms
04-16 19:42:21.129   564   564 D SystemServerTiming: OnBootPhase_520_com.android.server.hello.HelloService
04-16 19:42:21.129   564   564 V SystemServerTiming: OnBootPhase_520_com.android.server.hello.HelloService took to complete: 0ms
04-16 19:42:21.211   564   564 D SystemServerTiming: OnBootPhase_550_com.android.server.hello.HelloService
04-16 19:42:21.211   564   564 V SystemServerTiming: OnBootPhase_550_com.android.server.hello.HelloService took to complete: 0ms
04-16 19:42:23.136   564   564 D SystemServerTiming: OnBootPhase_600_com.android.server.hello.HelloService
04-16 19:42:23.136   564   564 V SystemServerTiming: OnBootPhase_600_com.android.server.hello.HelloService took to complete: 0ms
04-16 19:42:23.255   564   564 D SystemServerTimingAsync: ssm.onStartUser-0_com.android.server.hello.HelloService
04-16 19:42:23.255   564   564 V SystemServerTimingAsync: ssm.onStartUser-0_com.android.server.hello.HelloService took to complete: 0ms
04-16 19:42:28.180   564   590 D ActivityManagerTiming: OnBootPhase_1000_com.android.server.hello.HelloService
04-16 19:42:28.180   564   590 V ActivityManagerTiming: OnBootPhase_1000_com.android.server.hello.HelloService took to complete: 0ms
04-16 19:42:28.473   564   597 D SystemServerTimingAsync: ssm.onUnlockingUser-0_com.android.server.hello.HelloService
04-16 19:42:28.473   564   597 V SystemServerTimingAsync: ssm.onUnlockingUser-0_com.android.server.hello.HelloService took to complete: 0ms
04-16 19:42:30.339     0     0 W         : drivers/char/hello_driver.c hello_drv_open line 44
04-16 19:42:30.339     0     0 W         : drivers/char/hello_driver.c hello_drv_write line 37
04-16 19:42:30.339     0     0 W         : drivers/char/hello_driver.c hello_drv_close line 50
04-16 19:42:31.222   564   597 D SystemServerTimingAsync: ssm.onUnlockedUser-0_com.android.server.hello.HelloService
04-16 19:42:31.222   564   597 V SystemServerTimingAsync: ssm.onUnlockedUser-0_com.android.server.hello.HelloService took to complete: 0ms
04-16 19:42:36.249   564  2605 D SystemServerTimingAsync: ssm.onCompletedEventUser-0_{|Unlocked|}_com.android.server.hello.HelloService
04-16 19:42:36.249   564  2605 V SystemServerTimingAsync: ssm.onCompletedEventUser-0_{|Unlocked|}_com.android.server.hello.HelloService took to complete: 0ms
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

从 Log 来看,成功调用到了 hello 驱动程序。

# 参考资料

  • AOSP学习(四)Android13自定义系统服务 (opens new window)
  • Android 13添加自定义Java系统服务(一) (opens new window)
024.AIDL Hal 开发指南7 —— 实现一个简单的 AIDL HAL
026.AIDL Hal 开发指南10 —— AIDL HAL 的升级

← 024.AIDL Hal 开发指南7 —— 实现一个简单的 AIDL HAL 026.AIDL Hal 开发指南10 —— AIDL HAL 的升级→

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