开始之前需准备以下工具:
Android 7.1.1源码
Linux系统(Ubuntu or others)
JDK_1.8.0_191 (openjdk亦可)
Android源码可从google官网下载,当然国内因为墙的原因,可以购买VPN或其他方式获取。笔者推荐使用清华镜像下载,不用,且速度较快。因代码较大,可能需要长达10个小时的时间才能下载完成。笔者下载了一晚上,搞定。建议不要直接下载aosp.zip的压缩包文件,解压容易出错。导致源码编译不过。
PS: 因Android7.1.1源码很大,大概有30多个G。编译之后生成的文件更大,建议留足空间。笔者Home目录有200G硬盘。
https://blog.csdn.net/sk569437/article/details/52046917
Ubuntu16.04 LTS 编译Android6.0.1源码
source build/envsetup.sh
执行结果如下:
如下命令选择产品:
lunch
笔者编译源码时使用的是第五个aosp_x86-eng(编译64位占用硬盘空间太大),因此这里选择编译时选择的产品,结果如下:
android开发中调用系统服务,使用Context的getSystemService(String service_name)函数获取。了解安卓的知道具体实现函数在ContextImpl.java中。调用方法如下:
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
跟踪代码进入上面的context.getSystemService的调用代码,最终到ContextImpl中,如下:
@Override
public Object getSystemService(String name) {
return SystemServiceRegistry.getSystemService(this, name);
}
从上面可以知道系统服务的注册流程,实际上ContextImpl也是通过SystemServiceRegistry.getSystemService()来获取具体的服务,这些系统服务都是在SystemServiceRegistry.java的static静态代码块中进行注册的。
可以按照系统服务注册使用的方式,加入我们自定义的测试服务----- SelfService
系统里面很多的aidl文件定义在android_7.1.1/frameworks/base/core/java/android/os下,所以我们需要做的就是参考其他的aidl,照样子写一个简单的ISelfManager.aidl
在android_7.1.1/frameworks/base/core/java/android/os/目录下建立ISelfManager.aidl文件。代码如下:
package android.os;
interface ISelfManager {
int selfAddNumber(int numberFirst, int numberSecond);
String selfAddString(String originalStr);
}
在android_7.1.1/frameworks/base/Android.mk文件的LOCAL_SRC_FILES中添加自定义ISelfManager.aidl文件,可以看到这里有很多aidl文件。
LOCAL_SRC_FILES += \
core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl \
...
core/java/android/os/ISelfManager.aidl \
...
然后使用命令mmm frameworks/base,此时会自动根据aidl文件生成对应的stub接口
mmm frameworks/base
这里,我们没有特殊的需求就放在android_7.1.1/frameworks/base/services/core/java/com/android/server里。当然也可以在这个目录下新建一个文件加放入我们的服务。为方便,我们直接在当前目录新建SelfManagerService.java文件。代码如下:
package com.android.server;
import android.util.Log;
import android.os.ISelfManager;
public class SelfManagerService extends ISelfManager.Stub {
private static final String TAG = "SelfManagerService";
public int selfAddNumber(int numberFirst, int numberSecond) {
Log.d(TAG,"I WILL CALCULATE IT numberFirst is:"+numberFirst+" numberSecond is :"+numberSecond);
return numberFirst + numberSecond;
}
public String selfAddString(String originalStr) {
Log.d(TAG,"I will add a string to originalStr previous....");
return "previous lalala "+originalStr;
}
}
在android_7.1.1/frameworks/base/core/java/android/app/目录下创建SelfManager.java,代码如下:
package android.app;
import android.util.Log;
import android.os.ISelfManager;
import android.content.Context;
import android.os.RemoteException;
public class SelfManager {
private static String TAG = "SelfManager";
ISelfManager mSelfManager;
public SelfManager(Context ctx,ISelfManager selfManager) {
mSelfManager = selfManager;
}
public int selfAddNumber(int numberFirst, int numberSecond) throws RemoteException {
Log.d(TAG,"SelfManager selfAddNumber ......... ");
return mSelfManager.selfAddNumber(numberFirst,numberSecond);
}
public String selfAddString(String originalStr) throws RemoteException {
Log.d(TAG,"SelfManager selfAddString .........");
return mSelfManager.selfAddString(originalStr);
}
}
在Context文件中,添加我们自定义的SelfService服务的名字 ---- self , 代码如下:
public static final String SELF_SERVICE = "self";
我们知道wifi_service, location_service, window_service都必须添加到SystemServer中。SystemServer.java文件在以下目录。
frameworks/base/services/java/com/android/server/SystemServer.java
在SystemServer中添加自定义的SelfManagerService服务,服务名字用前面在Context中定义的SELF_SERVICE代替,代码如下:
private void startOtherServices() {
....
ServiceManager.addService(Context.SELF_SERVICE, new SelfManagerService());
....
}
在以下文件android_7.1.1/frameworks/base/core/java/android/app/SystemServiceRegistry.java中静态注册自定义SelfManagerService服务。代码如下:
Log.e("SelfManager", "----------------- before register selfManager service-------");
registerService(Context.SELF_SERVICE, SelfManager.class,
new CachedServiceFetcher() {
@Override
public SelfManager createService(ContextImpl ctx) {
IBinder b = ServiceManager.getService(Context.SELF_SERVICE);
ISelfManager service = ISelfManager.Stub.asInterface(b);
Log.e("SelfManager", "%%%%%%%%%%% SelfManager NEW %%%%%%%%%%%%%%");
return new SelfManager(ctx,service);
}});
Log.e("SelfManager", "++++++++++++++++++++ end register selfManager service-------");
需要更新sepolicy的配置,否则即使编译通过也是不会生效的。
不同版本不同厂商sepolicy文件位置不同,android7.1.1源码的位置在android_7.1.1/system/sepolicy/目录下面。
更新android_7.1.1/system/sepolicy/service.te文件,在里面找写代码,如下:
type self_service, system_api_service, system_server_service, service_manager_type;
注意这里写的self_service。 当前目录下另外一个文件service_contexts中添加的代码必须用这个字符串,代码如下:
self u:object_r:self_service:s0
PS:前面写的self就是Context.java重定义的服务名SELF_SERVICE的内容。后面的self_service是前面service.te文件中定义的那个名字。
需要更新当前系统的API,执行如下命令:
make update-api -j4
完成之后会生成自己添加的服务的API。可以在android_7.1.1/frameworks/base/api/current.txt里面查看,有如下代码说明更新成功:
public class SelfManager {
ctor public SelfManager(android.content.Context, android.os.ISelfManager);
method public int selfAddNumber(int, int) throws android.os.RemoteException;
method public java.lang.String selfAddString(java.lang.String) throws android.os.RemoteException;
}
执行如下命令编译代码,更新system.img文件。
make -j8
在android studio IDE中新建一个工程TestSelfService。 获取SelfService服务,调用其函数,看是否正常。
由于用到的SelfManager类在android sdk中不存在,为了正常编译打包,可自定义一个module,新建一个SelfManager文件,内容如下:
package android.app;
public class SelfManager {
public int selfAddNumber(int numberFirst, int numberSecond){
return 0;
}
public String selfAddString(String originalStr){
return null;
}
}
不用写具体的函数实现,只要写空函数就行。打包成SelfManager-release.jar包,供工程使用。
打包时使用provided或compileOnly 只参与编译,不参与打包命令。打包成apk文件。测试代码如下:
package com.ts.sk.testselfservice;
import android.app.SelfManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "SelfService";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.tv_tip).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
testSelfService();
}
});
}
private void testSelfService() {
try {
SelfManager sm = (SelfManager) getSystemService("self");
if(sm == null) {
Log.e(TAG, "self manager service is null....");
return;
}
Log.d(TAG, "self manager before called....");
int ret = sm.selfAddNumber(3, 4);
Log.d(TAG, "self manager add num is:" + ret);
String ret2 = sm.selfAddString("hello self service");
Log.d(TAG, "self manager add String is:" + ret2);
}catch (Exception e){
Log.e(TAG, "self manager invoke method get exception, msg:" + e.getMessage());
}
}
}
使用compileOnly命令参与编译,不参与打包APK,配置如下:
PS: 使用getSystemService(String name)函数获取selfManager服务时,使用self字符串,因为andrid SDK中没有定义SELF_SERVICE。
有条件的可以将生成的system.img烧写到手机中。没有工程手机,也可以直接运行生成的模拟器。
在终端中输入如下命令,运行模拟器:
//这里是以源码自带的内核启动模拟器
emulator&
//若想以自定义的内核启动模拟器,用以下命令,-kernel 后面跟自己编译出来的内核文件全路径
emulator -kernel ./kernel/android-goldfish-3.10/arch/x86/boot/bzImage &
使用adb命令将打包的测试apk文件安装到模拟器上。运行。
adb install -r TestSelfService.apk
安装之后如下:
通过adb shell service list命令可以列出当前设备中所有已注册的服务。命令如下:
adb shell service list
从上面可以看到我们自定义服务 self 已经注册成功。
运行TestSelfService,并用adb shell logcat 查看日志,如下:
查看日志发现报NullPointerException错误。仔细查看log,发现里面有如下错误代码:
12-07 10:32:13.795 2100 2100 E SelfManager: %%%%%%%%%%%%% SelfManager NEW %%%%%%%%%%%%%%%%
12-07 10:32:13.795 2100 2100 D SelfManager: SelfManager constructor called begin*********************
12-07 10:32:13.795 2100 2100 D SelfManager: SelfManager constructor called end**********************
12-07 10:32:13.795 2100 2100 D SelfManager: SelfManager fuzhi is null...error...........
12-07 10:32:13.795 2100 2100 D SelfManager: SelfManager selfAddNumber .........
12-07 10:32:13.795 2100 2100 E SelfService: self manager invoke method get exception, msg:Attempt to invoke interface method 'int android.os.ISelfManager.selfAddNumber(int, int)' on a null object reference
根据log查看代码发现selfservice服务已经加入到systemserver中。且获取SelfManager服务时正常的。但执行的时候报错了。
仔细查看详细日志,发现里面存在以下与 self 有关的log,如下:
SELinux : avc: denied { find } for service=self
说明是SELinux权限问题。跟代码无关。接下来需要打开权限,或者关闭SELinux。使用adb shell 命令查看和设置SELinux模式。执行如下命令:
adb shell getenforce // 获取SELinux的模式(enforcing, permissive)
结果如下:
可以看到SELinux为Enforcing模式。用以下命令切换模式:
setenforce 1 // 设置SELinux 成为enforcing模式
setenforce 0 // 设置SELinux 成为permissive模式
结果如下:
经过验证,设置成permissive模式后, 可以运行正常了。结果如下:
https://blog.csdn.net/mockingbirds/article/details/54382072