Android 11新增系统服务

1.编写.aidl文件

存放位置:frameworks/base/core/java/android/os

package android.os;

interface ISystemVoiceServer {

    void setHeightVoice(int flag);

    void setBassVoice(int flag);

    void setReverbVoice(int flag);

}

2.将.aidl文件添加到frameworks/base/Android.bp

filegroup {
    name: "framework-core-sources",
    srcs: [
        "core/java/**/*.java",
        "core/java/**/*.aidl",
    ],
    path: "core/java",
}

说明:android.bp文件中默认把core/java/目录下的aidl文件添加到编译文件中,所以这一步不需要操作.

由于Android 11对语法检测比较严格,所以针对我们新增的文件先加入忽略:

// TODO(b/145644363): move this to under StubLibraries.bp or ApiDocs.bp
metalava_framework_docs_args = "--manifest $(location core/res/AndroidManifest.xml) " +
    "--ignore-classes-on-classpath " +
    "--hide-package com.android.server " +
    "--error UnhiddenSystemApi " +
    "--hide RequiresPermission " +
    "--hide CallbackInterface " +
    "--hide MissingPermission --hide BroadcastBehavior " +
    "--hide HiddenSuperclass --hide DeprecationMismatch --hide UnavailableSymbol " +
    "--hide SdkConstant --hide HiddenTypeParameter --hide Todo --hide Typo " +
    "--force-convert-to-warning-nullability-annotations +*:-android.*:+android.icu.*:-dalvik.* " +
    "--api-lint-ignore-prefix android.icu. " +
    "--api-lint-ignore-prefix java. " +
    "--api-lint-ignore-prefix android.os. " +   //新增这一行 
    "--api-lint-ignore-prefix android.app. " +  //新增这一行  
    "--api-lint-ignore-prefix junit. " +
    "--api-lint-ignore-prefix org. "

3、Context.java添加服务注册名称, 添加该服务名称, 用于快捷注册和快捷引用

修改位置:frameworks/base/core/java/android/content/

  //增加新增定义服务名称  
  /**
     * Use with {@link #getSystemService(String)} to retrieve a
     * {@link  android.app.SystemVoiceManager} for accessing
     * text services.
     *
     * @see #getSystemService(String)
     */
  
    public static final String SYSTEMVOCIE_SERVICER = "systemvoice";
    

    /** @hide */
    @StringDef(suffix = { "_SERVICE" }, value = {
            POWER_SERVICE,
            SYSTEMVOCIE_SERVICER,   //此处新增服务
            WINDOW_SERVICE,
            LAYOUT_INFLATER_SERVICE,
            ......}

4、新建SystemVoiceService.java和SystemVoiceManager.java

存放位置:frameworks\base\services\core\java\com\android\server\SystemVoiceService.java

frameworks\base\core\java\android\app\SystemVoiceManager.java

package com.android.server;

import android.app.SystemVoiceManager;
import android.content.Context;
import android.os.ISystemVoiceServer;
import android.os.RemoteException;
import com.android.server.SystemService;
import com.android.internal.app.IAppOpsService;


public class SystemVoiceService extends SystemService {
    private final String TAG = "SystemVoiceService";

    private Context mContext;
    private IAppOpsService mAppOps;
    private SystemVoiceManager mManager;

    public SystemVoiceService(Context context) {
        super(context);
        this.mContext = context;
    }

    public void systemReady(IAppOpsService appOps) {
        mAppOps = appOps;
        if (mManager == null) {
            mManager = (SystemVoiceManager) mContext.getSystemService(Context.SYSTEMVOICE_SERVICE);
        }
    }

    @Override
    public void onStart() {
        publishBinderService(Context.SYSTEMVOICE_SERVICE, new BinderService());
    }


    private final class BinderService extends ISystemVoiceServer.Stub {

        @Override
        public void setHeightVoice(int flag) throws RemoteException {
            
        }

        @Override
        public void setBassVoice(int flag) throws RemoteException {

        }

        @Override
        public void setReverbVoice(int flag) throws RemoteException {

        }
    }
}
package android.app;

import android.content.Context;
import android.os.ISystemVoiceServer;
import android.util.Log;
import android.annotation.SystemService;
import android.os.RemoteException;


@SystemService(Context.SYSTEMVOICE_SERVICE)
public class SystemVoiceManager {

    private static final String TAG = "SystemVoiceManager";
    private ISystemVoiceServer mService;
    private Context context;

    public SystemVoiceManager(Context ctx, ISystemVoiceServer service) {
        mService = service;
        context = ctx;
    }

    public void setHeightVoice(int flag) {
        try {
            mService.setHeightVoice(flag);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public void setBassVoice(int flag) {
        try {
            mService.setBassVoice(flag);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    public void setReverbVoice(int flag) {
        try {
            mService.setReverbVoice(flag);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


}

5、SystemServer.java 中注册该service

修改位置: frameworks\base\services\java\com\android\server

import com.android.server.SystemVoiceService ;//导包
 
private SystemVoiceService  mSystemVoiceService; //定义

  //系统服务加入的位置加入以下内容
  t.traceBegin("StartSystemVoiceManager");
  mSystemVoiceService = mSystemServiceManager.startService(SystemVoiceService.class);
  t.traceEnd();

  //系统服务加入的位置加入以下内容
   t.traceBegin("MakeSystemVoiceManagerServiceReady");
   try {
           // TODO: use boot phase
       mSystemVoiceService.systemReady(mActivityManagerService.getAppOpsService());
    } catch (Throwable e) {
           reportWtf("making SystemVoice Manager Service ready", e);
    }
     t.traceEnd();

6、SystemServiceRegistry的static{}, 并在其中注册该service

修改位置:frameworks\base\core\java\android\app

import android.os.ISystemVoiceServer;//导包

//SystemVoiceManager在同一目录下所以不用导包

   registerService(Context.SYSTEMVOICE_SERVICE, SystemVoiceManager.class,
                new CachedServiceFetcher<SystemVoiceManager>() {
                    @Override
                    public SystemVoiceManager createService(ContextImpl ctx)
                            throws ServiceNotFoundException {
                        IBinder b = ServiceManager.getServiceOrThrow(
                                Context.SYSTEMVOICE_SERVICE);
                        return new SystemVoiceManager(
                                ctx.getOuterContext(),ISystemVoiceService.Stub.asInterface(b));
                    }});

以上步骤完成我们的自定义系统服务就完成了90% 但是我们还有最后一步,也是最重要的一步:

然后我们只需要添加这个自定义服务SystemVoiceService相关的 SELinux 规则。为了方便之后验证,打开selinux

要记住这个命令 adb shell setenforce 1 # 1为打开 #0为关闭

Android 11 的 selinux 规则是放在 system/sepolicy 目录下的:

service.te 和 service_contexts 都要加上SystemVoiceService的配置:

//在以下目录文件
./prebuilts/api/30.0/public/service.te   # 需要
./public/service.te                 # 需要
//添加以下内容
type systemvoice_service, app_api_service, ephemeral_app_api_service, system_server_service, service_manager_type;

//在以下目录文件
./prebuilts/api/30.0/private/service_contexts   # 需要
./private/service_contexts         # 需要
//添加以下内容
systemvoice_service                      u:object_r:isystemvoice_service:s0

添加完配置后,Android11版本还要需要在以下目录修改以下忽略配置,才能正常编译

在以下目录
./prebuilts/api/30.0/private/compat/29.0/29.0.ignore.cil
./prebuilts/api/30.0/private/compat/28.0/28.0.ignore.cil
./prebuilts/api/30.0/private/compat/27.0/27.0.ignore.cil
./prebuilts/api/30.0/private/compat/26.0/26.0.ignore.cil
./private/compat/29.0/29.0.ignore.cil
./private/compat/28.0/28.0.ignore.cil
./private/compat/27.0/27.0.ignore.cil
./private/compat/26.0/26.0.ignore.cil

到此,android 11 系统服务已经添加完成!.

8、验证:

编译完成后,输入adb shell

#service list

查看服务列表中 是否存在有添加服务 :itest

如果不存在 逐步排查 参照上一步看哪一步错误

如果存在 就在代码中验证

找到编译最新生成的class.jar文件,导入Androidstudio(如何导入自行百度)

编译后的class.jar目录\out\target\common\obj\JAVA_LIBRARIES\framework_intermediates

如果未生成 执行下make javac-check-framework 这个命令 就会生成!!!

觉得我写的好的兄弟 动动你发财的小手 点个赞 !!!

你们的认同将是我继续写下去的动力 !!

猜你喜欢

转载自blog.csdn.net/a546036242/article/details/129683832