以下内容根据Android12 源码进行收拾

下面内容是根据Camera升降机服务增加过程收拾

1.在Context.java 中增加服务名称

Context.java 在源码中方位:frameworks/base/core/java/android/content/Context.java

/**
 * Use with {@link #getSystemService(String)} to retrieve a
 * {@link com.android.server.cameralift.CameraLiftManagerService}
 *
 * @see #getSystemService(String)
 * @see android.app.cameralift.CameraLiftManager
 */
public static final String CAMERA_LIFT_SERVICE = "camera_lift";
/** @hide */
@StringDef(suffix = { "_SERVICE" }, value = {
        POWER_SERVICE,
        .... // 省掉部分代码 
        CAMERA_LIFT_SERVICE,
})  

2.创立AIDL文件

frameworks/base/core/java/android/app 增加cameralift/aidl目录, 在aidl目录中增加aidl 文件:
path: frameworks/base/core/java/android/app/cameralift/aidl
File name : CameraLiftEvent.aidl

package android.app.cameralift.aidl;
import android.app.cameralift.aidl.CameraLiftCallback;
interface CameraLiftEvent {
    void registerCallback(CameraLiftCallback callback);
    void unregisterCallback(CameraLiftCallback callback);
    void sendEvent(int type, String value);
}

File name: CameraLiftCallback.aidl

package android.app.cameralift.aidl;
interface CameraLiftCallback {
    oneway void onStatusChange(int type, String msg);
}

小技巧:

当完结上面的aidl文件后希望能够在完成Service时能够正常提示aidl生成的class文件。

  1. 先运用命令make -j16 framework-minus-apex编译一下framework,编译的时分会报如下过错:
    注:运用make update-api 也会出现这个过错
out/srcjars/android/app/cameralift/aidl/CameraLiftCallback.java:129: error: Methods calling system APIs should rethrow `RemoteException` as `R
untimeException` (but do not list it in the throws clause) [RethrowRemoteException]
out/srcjars/android/app/cameralift/aidl/CameraLiftCallback.java:129: error: Missing nullability on parameter `msg` in method `onStatusChange` 
[MissingNullability]
out/srcjars/android/app/cameralift/aidl/CameraLiftCallback.java:10: error: Methods calling system APIs should rethrow `RemoteException` as `Ru
ntimeException` (but do not list it in the throws clause) [RethrowRemoteException]
out/srcjars/android/app/cameralift/aidl/CameraLiftCallback.java:10: error: Missing nullability on parameter `msg` in method `onStatusChange` [
MissingNullability]
out/srcjars/android/app/cameralift/aidl/CameraLiftCallback.java:13: error: Missing nullability on method `asBinder` return [MissingNullability
]

解决办法:
将文件:out/soong/.intermediates/frameworks/base/api-stubs-docs-non-updatable/android_common/metalava/api-stubs-docs-non-updatable_api.txt拷贝frameworks/base/core/api/current.txt 替换current.txt 内容

current.txt中增加了如下内容:

package android.app.cameralift.aidl {
  public interface CameraLiftCallback extends android.os.IInterface {
    method public void onStatusChange(int, String) throws android.os.RemoteException;
    field public static final String DESCRIPTOR = "android.app.cameralift.aidl.CameraLiftCallback";
  }
  public static class CameraLiftCallback.Default implements android.app.cameralift.aidl.CameraLiftCallback {
    ctor public CameraLiftCallback.Default();
    method public android.os.IBinder asBinder();
    method public void onStatusChange(int, String) throws android.os.RemoteException;
  }
  public abstract static class CameraLiftCallback.Stub extends android.os.Binder implements android.app.cameralift.aidl.CameraLiftCallback {
    ctor public CameraLiftCallback.Stub();
    method public android.os.IBinder asBinder();
    method public static android.app.cameralift.aidl.CameraLiftCallback asInterface(android.os.IBinder);
    method public static android.app.cameralift.aidl.CameraLiftCallback getDefaultImpl();
    method public boolean onTransact(int, android.os.Parcel, android.os.Parcel, int) throws android.os.RemoteException;
    method public static boolean setDefaultImpl(android.app.cameralift.aidl.CameraLiftCallback);
  }
  public interface CameraLiftEvent extends android.os.IInterface {
    method public void registerCallback(android.app.cameralift.aidl.CameraLiftCallback) throws android.os.RemoteException;
    method public void sendEvent(int, String) throws android.os.RemoteException;
    method public void unregisterCallback(android.app.cameralift.aidl.CameraLiftCallback) throws android.os.RemoteException;
    field public static final String DESCRIPTOR = "android.app.cameralift.aidl.CameraLiftEvent";
  }
  public static class CameraLiftEvent.Default implements android.app.cameralift.aidl.CameraLiftEvent {
    ctor public CameraLiftEvent.Default();
    method public android.os.IBinder asBinder();
    method public void registerCallback(android.app.cameralift.aidl.CameraLiftCallback) throws android.os.RemoteException;
    method public void sendEvent(int, String) throws android.os.RemoteException;
    method public void unregisterCallback(android.app.cameralift.aidl.CameraLiftCallback) throws android.os.RemoteException;
  }
  public abstract static class CameraLiftEvent.Stub extends android.os.Binder implements android.app.cameralift.aidl.CameraLiftEvent {
    ctor public CameraLiftEvent.Stub();
    method public android.os.IBinder asBinder();
    method public static android.app.cameralift.aidl.CameraLiftEvent asInterface(android.os.IBinder);
    method public static android.app.cameralift.aidl.CameraLiftEvent getDefaultImpl();
    method public boolean onTransact(int, android.os.Parcel, android.os.Parcel, int) throws android.os.RemoteException;
    method public static boolean setDefaultImpl(android.app.cameralift.aidl.CameraLiftEvent);
  }
}

然后将上面current.txt文件中新增的内容需求增加到 :prebuilts/sdk/32/public/api/android.txt 文件中

上面内容装备完结后,再次运用命令make -j16 framework-minus-apex编译一下framework代码

  1. 找到编译aidl生成.class文件途径,上面代码编译出来的途径为:
    out/soong/.intermediates/frameworks/base/android-non-updatable.stubs.module_lib/android_common/javac/classes/android/app/cameralift/aidl/

  2. 点击File -> Project Structure 打项目结构设置窗口, 选中 Global Libraries 后点击上面 + 号选择Java 装备上一步copy的途径,装备后等待装备信息同步完结即可完成提示跳转

说明: 上面的装备是增加了aidl 后编译装备办法,如果持续增加新的类还会出现编译过错,后面会持续介绍

3.创立服务

frameworks/base/services/core/java/com/android/server目录增加cameralift目录,完成service
path:frameworks/base/services/core/java/com/android/server/cameralift
File name: CameraLiftManagerService.java

package com.android.server.cameralift;
import android.app.cameralift.aidl.CameraLiftCallback;
import android.app.cameralift.aidl.CameraLiftEvent;
import android.content.Context;
import android.os.Binder;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.util.Slog;
/**
 * @hide
 */
public class CameraLiftManagerService extends CameraLiftEvent.Stub {
    private static final String TAG = "CameraLiftManagerService";
    private final RemoteCallbackList<CameraLiftCallback> mCallbackList = new RemoteCallbackList<>();
    private Context mContext;
    public CameraLiftManagerService(Context context) {
        this.mContext = context;
    }
    @Override
    public void registerCallback(CameraLiftCallback cameraLiftCallback) throws RemoteException {
        boolean result = mCallbackList.register(cameraLiftCallback);
        Slog.i(TAG, "register  pid:" + Binder.getCallingPid() + "  uid:" + Binder.getCallingUid()  + "  result:" + result  + " size:");
    }
    @Override
    public void unregisterCallback(CameraLiftCallback cameraLiftCallback) throws RemoteException {
        boolean result = mCallbackList.unregister(cameraLiftCallback);
        Slog.i(TAG, "unregister  pid:" + Binder.getCallingPid() + "  uid:" + Binder.getCallingUid()  + "  result:" + result);
    }
    @Override
    public void sendEvent(int type, String msg) throws RemoteException {
        Slog.i(TAG, "sendEvent: type:" + type  + "   msg:" + msg);
        int count = mCallbackList.getRegisteredCallbackCount();
        Slog.i(TAG, "callback size:" + count);
        if (count > 0) {
            int size = mCallbackList.beginBroadcast();
            for (int i = 0; i < size; i++) {
                CameraLiftCallback callback = mCallbackList.getBroadcastItem(i);
                try {
                    callback.onStatusChange(type, "server:" + msg);
                } catch (RemoteException e) {
                    e.printStackTrace();
                    Slog.i(TAG, "remote exception :" + e.getMessage());
                }
            }
            mCallbackList.finishBroadcast();
        }
    }
}

4.创立服务Manager

在目录frameworks/base/core/java/android/app/cameralift 目录下增加service 的 Manager 类

package android.app.cameralift;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemService;
import android.app.cameralift.aidl.CameraLiftCallback;
import android.app.cameralift.aidl.CameraLiftEvent;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Slog;
@SystemService(Context.CAMERA_LIFT_SERVICE)
public class CameraLiftManager {
    private static final String TAG = "CameraLiftManager";
    private static CameraLiftManager mInstance;
    private CameraLiftEvent mService;
    /**
     * @hide
     */
    public CameraLiftManager(CameraLiftEvent service) {
        Slog.i(TAG, "CameraLiftManager");
        this.mService = service;
    }
    /**
     * @hide
     */
    @NonNull
    @UnsupportedAppUsage
    public static CameraLiftManager getInstance() {
        synchronized (CameraLiftManager.class) {
            if (mInstance == null) {
                try {
                    IBinder b = ServiceManager.getServiceOrThrow(Context.CAMERA_LIFT_SERVICE);
                    mInstance = new CameraLiftManager(CameraLiftEvent.Stub.asInterface(b));
                } catch (ServiceManager.ServiceNotFoundException e) {
                    throw new IllegalStateException(e);
                }
            }
        }
        return mInstance;
    }
    public void registerCallback(@Nullable CameraLiftCallback cameraLiftCallback)  {
        try {
            mService.registerCallback(cameraLiftCallback);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
    public void unregisterCallback(@Nullable CameraLiftCallback cameraLiftCallback)  {
        try {
            mService.unregisterCallback(cameraLiftCallback);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
    public void sendEvent(int type , @Nullable String value)  {
        try {
            mService.sendEvent(type, value);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
}

5.注册新服务到ServiceManager中

首先需求在SystemServer.java 中增加 CameraLiftManagerService.java
SystemServer.java文件方位:frameworks/base/services/java/com/android/server/SystemServer.java

/**
 * Starts a miscellaneous grab bag of stuff that has yet to be refactored and organized.
 */
private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
    t.traceBegin("startOtherServices");
    .... // 省掉部分代码
    CameraLiftManagerService cameraLiftManagerService = null;
     .... // 省掉部分代码
    t.traceBegin("CameraLiftManagerService");
    try {
        cameraLiftManagerService = new CameraLiftManagerService(context);
        ServiceManager.addService(Context.CAMERA_LIFT_SERVICE, cameraLiftManagerService);
    } catch (Throwable e) {
        Slog.e(TAG, "Failure starting CameraLiftManagerService  ", e);
    }
    t.traceEnd();
     .... // 省掉部分代码
}

然后在SystemServiceRegistry.java 静态代码块中通过CameraLiftManager.javaCameraLiftManagerSerice.java 注册到SystemServer.java
SystemServiceRegistry.java 文件方位:frameworks/base/core/java/android/app/SystemServiceRegistry.java

static {
    //CHECKSTYLE:OFF IndentationCheck
    registerService(Context.CAMERA_LIFT_SERVICE, CameraLiftManager.class,
        new CachedServiceFetcher<CameraLiftManager>() {
            @Override
            public CameraLiftManager createService(ContextImpl ctx) throws ServiceNotFoundException {
                return CameraLiftManager.getInstance();
            }
        });
}

增加好Service 和 Manager 后再次发动编译,会报下面的过错:

frameworks/base/core/java/android/app/cameralift/CameraLiftManager.java:49: error: Registration methods should have overload that accepts deli
very Executor: `registerCallback` [ExecutorRegistration]Error: metalava detected the following problems:
frameworks/base/core/java/android/app/cameralift/CameraLiftManager.java:49: error: Registration methods should have overload that accepts deli
very Executor: `registerCallback` [ExecutorRegistration]

两种解决办法:

  1. 将aidl 编译过错解决办法从头操作一遍
  2. 让lint查看忽略掉自己的模块 在framework/base 下的Android.bp忽略掉代码查看
metalava_framework_docs_args = "
"--api-lint-ignore-prefix android.app.cameralift." //其中 android.app.cameralift.是包名的前缀。

装备完之后再次发动编译

6.增加SELinux权限

  1. 装备service_contexts
    service_contexts文件修正需求留意一下,需求修正两个文件的方位,并且修正的内容和下面 service.te中内容要对应

service_contexts 文件修正方位为:
方位1:system/sepolicy/prebuilts/api/32.0/private/service_contexts
方位2:system/sepolicy/private/service_contexts
两个文件中修正内容相同,办法如下:
找到文件中的audio,仿照audio 的增加办法增加,增加内容如下:

// 这是体系服务audio 
audio                                     u:object_r:audio_service:s0
// 新增加服务 camera_lift
camera_lift                               u:object_r:camera_lift_service:s0
  1. 装备service.te
    service.te文件修正需求留意一下,需求修正两个文件的方位。文件修正方位为:
    方位1:system/sepolicy/prebuilts/api/32.0/public/service.te
    方位2:system/sepolicy/public/service.te
    两个文件中修正内容相同,办法如下:
    找到文件中的audio,仿照audio 的增加办法增加,增加内容如下:
    找到文件方位:system/sepolicy/prebuilts/api/32.0/public/service.te
// 体系服务audio 的装备
type audio_service, app_api_service, ephemeral_app_api_service, system_server_service, service_manager_type;
// 新增加的服务camera_file,留意一下,这儿的camera_lift_service 和service_contexts 中对应
type camera_lift_service, app_api_service,system_api_service, system_server_service, service_manager_type;
  1. 装备31.0.ignore.cil
    装备目录:system/sepolicy/private/compat/31.0/31.0.ignore.cil
    typeattributeset new_objects 方位增加装备camera_lift_service,如下:
(typeattributeset new_objects
  ( new_objects
    hypervisor_prop
    camera_lift_service
  ))

这儿修正的是 31, 修正那个文件要根据实际版别决议

7.装备prebuilts

要在这个目录中把新的服务姓名装备上,这样app才干在Context 中找到这个服务
文件途径:prebuilts/sdk/32/public/api/android.txt

public abstract class Context {
    ... // 省掉部分代码 
    field public static final String CAMERA_LIFT_SERVICE = "camera_lift";
    ... // 省掉部分代码
}  

从上面的姓名也能够看出这个是设置Context 的

留意一下,修正这个目录后需求全编译一下源码才干收效,现在还没有找到其他收效的办法。

8. 生成应用调用的jar

服务已经增加完毕,下面需求在体系源码中根据之前修正,生成一个供应用运用的jar , 这儿不具体介绍,直接贴代码:

  1. Android.bp 文件
java_library_static {
    name: "camera_lift_lib",
    srcs:[
        "com/sgf/cameralift/CameraLiftCallbackProxy.java",
        "com/sgf/cameralift/CameraLiftCallbackWrapper.java",
        "com/sgf/cameralift/CameraLiftManagerProxy.java",
    ],
}
  1. Java 代码完成
package com.sgf.cameralift;
public interface CameraLiftCallbackProxy {
    void onStatusChange(int type, String msg);
}

package com.sgf.cameralift;
import android.app.cameralift.aidl.CameraLiftCallback;
import android.os.RemoteException;
import com.sgf.cameralift.*;
class CameraLiftCallbackWrapper extends CameraLiftCallback.Stub {
    private CameraLiftCallbackProxy mCallbackProxy;
    CameraLiftCallbackWrapper(CameraLiftCallbackProxy callbackProxy) {
        this.mCallbackProxy = callbackProxy;
    }
    @Override
    public void onStatusChange(int type, String msg) throws RemoteException {
        if (mCallbackProxy != null) {
            mCallbackProxy.onStatusChange(type, msg);
        }
    }
}

package com.sgf.cameralift;
import android.annotation.Nullable;
import android.app.cameralift.CameraLiftManager;
import android.content.Context;
import android.util.Log;
import java.util.HashMap;
import java.util.Map;
public class CameraLiftManagerProxy {
    private static final String TAG = "CameraLiftManagerProxy";
    private final CameraLiftManager mCameraLiftManager;
    private final HashMap<CameraLiftCallbackProxy, CameraLiftCallbackWrapper> mCallbackMap = new HashMap<>();
    public CameraLiftManagerProxy(Context context) {
        this.mCameraLiftManager = (CameraLiftManager) context.getSystemService(Context.CAMERA_LIFT_SERVICE);
    }
    public synchronized void registerCallback(@Nullable CameraLiftCallbackProxy callbackProxy)  {
        if (!mCallbackMap.containsKey(callbackProxy)){
            CameraLiftCallbackWrapper wrapper = new CameraLiftCallbackWrapper(callbackProxy);
            mCallbackMap.put(callbackProxy, wrapper);
            mCameraLiftManager.registerCallback(wrapper);
        } else  {
            Log.i(TAG, "this call back has registered");
        }
    }
    public synchronized void unregisterCallback(@Nullable CameraLiftCallbackProxy callbackProxy)  {
        if (mCallbackMap.containsKey(callbackProxy)) {
            CameraLiftCallbackWrapper wrapper = mCallbackMap.remove(callbackProxy);
            mCameraLiftManager.unregisterCallback(wrapper);
        }
    }
    public void sendEvent(int type , @Nullable String value)  {
        mCameraLiftManager.sendEvent(type, value);
    }
    public synchronized void release() {
        for (Map.Entry<CameraLiftCallbackProxy, CameraLiftCallbackWrapper> value : mCallbackMap.entrySet()) {
            CameraLiftCallbackWrapper wrapper = value.getValue();
            mCameraLiftManager.unregisterCallback(wrapper);
        }
        mCallbackMap.clear();
    }
}