这篇文章接上一篇文章,主要介绍,如何在SystemServer服务中添加 HelloService,并解决遇见的selinux问题。
AndroidQ 从app到驱动 第一章 编写Linux内核驱动程序
AndroidQ 从app到驱动 第二章 添加HAL层,先打通JNI层到驱动的访问
AndroidQ 从app到驱动 第三章 SystemServer服务中添加 HelloService
AndroidQ 从app到驱动 第四章 编写app验证新添加的helloservice是否正常
AndroidQ 从app到驱动 第五章 编写JNI层完成HelloService与Hal层的对接
AndroidQ 从app到驱动 第六章 从app到驱动的所有的代码整理
其实在这里就有人问了,按照Android系统的架构流程,这第三章应该是添加JNI层接口才对,但是为什么这里直接就是添加HelloService呢?其实这个我也考虑过按照其他人的方式,一层一层向上加,直到app结束,但是如果在这里直接添加JNI 层之后我们无法进行及时的验证,来验证我们添加的JNI层代码是否正常,因此这里就直接略过了JNI层的添加,直接跳到了framework层添加HelloService的地方,添加JNI层计划放在这些文章的最后一章介绍,这样子就可以用前面几章的代码直接验证了。
这篇文章从两个方面来介绍添加过程
1:添加HelloService所需要修改以及添加的文件
2:解决添加HelloService遇到的selinux权限问题
一,添加HelloService所需要修改以及添加的文件
首先看截图:截图接上一篇文章中的修改,因此这里只关心红色的部分,绿色部分不关注。
截图显示,本次修改,添加了三个新的文件,修改了四个原有的文件,下面就这几个文件的修改内容贴出来。
1)frameworks/base/Android.bp的修改 添加了一行 "core/java/android/os/IHelloService.aidl",
2)frameworks/base/core/java/android/content/Context.java的修改,添加了一行
3) frameworks/base/core/java/android/app/SystemServiceRegistry.java的修改,这里修改的比较多。
import android.os.Vibrator;
import android.os.health.SystemHealthManager;
import android.os.storage.StorageManager;
+import android.os.IHelloService;
import android.print.IPrintManager;
import android.print.PrintManager;
import android.service.oemlock.IOemLockService;
@@ -1027,6 +1028,23 @@ public final class SystemServiceRegistry {
Context.DEVICE_IDLE_CONTROLLER));
return new DeviceIdleManager(ctx.getOuterContext(), service);
}});
+
+ registerService(Context.HELLO_SERVICE, HelloManager.class,
+ new CachedServiceFetcher() {
+ @Override
+ public HelloManager createService(ContextImpl ctx) {
+ try {
+ IBinder b = ServiceManager.getServiceOrThrow(Context.HELLO_SERVICE);
+ Log.i(TAG, "registerService HELLO_SERVICE b = "+b);
+ IHelloService service = IHelloService.Stub.asInterface(b);
+ Log.i(TAG, "registerService HELLO_SERVICE service = "+service);
+ return new HelloManager(ctx, service);
+ } catch (ServiceNotFoundException e) {
+ Log.i(TAG, "registerService ServiceNotFoundException e = "+e);
+ onServiceNotFound(e);
+ return new HelloManager(ctx,null);
+ }
+ }});
}
/**
4) frameworks/base/services/java/com/android/server/SystemServer.java 的修改,
frameworks/base/services/java/com/android/server/SystemServer.java在startOtherServices中添加启动helloservice的代码
5)新添加的 frameworks/base/core/java/android/app/HelloManager.java 的内容
package android.app;
import android.annotation.SdkConstant;
import android.annotation.SystemApi;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;
import android.os.IHelloService;
import android.util.Log;
public class HelloManager {
IHelloService mService;
public HelloManager(Context ctx,IHelloService service){
mService = service;
}
public void setVal(String value){
try{
Log.e("HelloManager","HelloManager setVal");
mService.setVal(value);
}catch(Exception e){
Log.e("HelloManager",e.toString());
e.printStackTrace();
}
}
public String getVal(){
try{
Log.e("HelloManager","HelloManager getVal");
return mService.getVal();
}catch(Exception e){
Log.e("HelloManager",e.toString());
e.printStackTrace();
}
return null;
}
}
6)新添加的 frameworks/base/core/java/android/os/IHelloService.aidl 的内容
/**
* Copyright (c) 2012, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License. HelloService
*/
package android.os;
interface IHelloService {
void setVal(String value);
String getVal();
}
7)新添加的 frameworks/base/services/core/java/com/android/server/HelloService.java 的内容
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.IHelloService;
import android.os.RemoteException;
import android.os.TokenWatcher;
import android.os.UpdateLock;
import android.os.UserHandle;
import android.util.Slog;
import com.android.internal.util.DumpUtils;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.HashMap;
public class HelloService extends IHelloService.Stub {
static final String TAG = "HelloService";
Context mContext;
HelloService(Context context) {
Slog.i(TAG, "HelloService init");
mContext = context;
}
@Override
public void setVal(String value) throws RemoteException {
Slog.i(TAG, "setVal value = "+value);
}
@Override
public String getVal() throws RemoteException {
Slog.i(TAG, "getVal ");
return "getVal";
}
}
到此需要修改,以及添加的文件就完成了,这里由于给系统新添加了API函数,因此这里需要先执行 make update-api
要不然,会报下面的错误。
******************************
You have tried to change the API from what has been previously approved.
To make these errors go away, you have two choices:
1) You can add "@hide" javadoc comments to the methods, etc. listed in the
errors above.
2) You can update current.txt by executing the following command:
make update-api
To submit the revised current.txt to the main Android repository,
you will need approval.
******************************
执行完 make update-api,之后,全部编译,烧录验证。log信息如下:
06-01 22:50:10.190 793 793 D SystemServerTiming: PinnerService took to complete: 3ms
06-01 22:50:10.190 793 793 I SystemServer: start hello Service
06-01 22:50:10.191 793 793 I HelloService: HelloService init
06-01 22:50:10.192 793 793 E System : ******************************************
06-01 22:50:10.193 793 853 D PinnerService: pinRangeStream: null
06-01 22:50:10.193 793 793 E System : ************ Failure starting core service
06-01 22:50:10.193 793 793 E System : java.lang.SecurityException
06-01 22:50:10.193 793 793 E System : at android.os.BinderProxy.transactNative(Native Method)
06-01 22:50:10.193 793 793 E System : at android.os.BinderProxy.transact(Binder.java:1135)
06-01 22:50:10.193 793 793 E System : at android.os.ServiceManagerProxy.addService(ServiceManagerNative.java:153)
06-01 22:50:10.193 793 793 E System : at android.os.ServiceManager.addService(ServiceManager.java:184)
06-01 22:50:10.193 793 793 E System : at android.os.ServiceManager.addService(ServiceManager.java:155)
06-01 22:50:10.193 793 793 E System : at com.android.server.SystemServer.startOtherServices(SystemServer.java:967)
06-01 22:50:10.193 793 793 E System : at com.android.server.SystemServer.run(SystemServer.java:449)
06-01 22:50:10.193 793 793 E System : at com.android.server.SystemServer.main(SystemServer.java:304)
06-01 22:50:10.193 793 793 E System : at java.lang.reflect.Method.invoke(Native Method)
06-01 22:50:10.193 793 793 E System : at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
06-01 22:50:10.193 793 793 E System : at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:891)
06-01 22:50:10.193 793 793 I SystemServer: StartInputMethodManagerLifecycle
06-01 22:50:10.193 793 793 I SystemServiceManager: Starting com.android.server.InputMethodManagerService$Lifecycle
log显示,因为安全问题,新添加的hello service 不能正常add到ServiceManager中。下面就需要解决面临的selinux的问题了。
二,解决添加HelloService遇到的selinux权限问题
解决selinux权限,需要修改下面几个文件,其中这些文件分为4组,每一组的修改都是一样的,因此这里只看一组的修改就可以了,其他组的修改,直接复制过去就可以了,
修改的文件列表:
system/sepolicy/prebuilts/api/26.0/private/service_contexts
system/sepolicy/prebuilts/api/26.0/public/service.te
system/sepolicy/prebuilts/api/27.0/private/service_contexts
system/sepolicy/prebuilts/api/27.0/public/service.te
system/sepolicy/prebuilts/api/28.0/private/service_contexts
system/sepolicy/prebuilts/api/28.0/public/service.te
system/sepolicy/private/service_contexts
system/sepolicy/public/service.te
文件的修改详情如下:其他六个文件,两两一组,修改方式是一样的,因此这里就不截图了。
添加完这些selinux权限之后,重新编译验证。
06-02 08:15:42.939 659 823 D PinnerService: pinRangeStream: null
06-02 08:15:42.939 659 659 I HelloService: HelloService init
06-02 08:15:42.941 659 823 E PinnerService: Could not pin file /system/framework/arm/boot-mediatek-framework.vdex
06-02 08:15:42.941 659 659 I SystemServer: StartInputMethodManagerLifecycle
log显示,hello服务启动正常,没有发现有报错的log,下一步,为了验证我们添加的helloservice是否正常,需要写一个app来进行验证。
最后在贴一张截图,展现本次文章中所涉及到的所有修改。这里system/sepolicy/prebuilts/api/27.0/private/service_contexts这个文件由于被 git add了,因此显示为绿色。
这篇文章就到这里了。