1,添加AIDL
frameworks\base\core\java\android\os\ILgyManager.aidl
package android.os;
/** @hide */
interface ILgyManager
{
String getVal();
}
2,在frameworks\base\Android.bp中添加我们的AIDL,让其编译进系统
"core/java/android/os/ILgyManager.aidl",
3,添加service,
在frameworks\base\services\core\java\com\android\server\下创建自己的文件夹lgy,并创建自己的service
lgy\LgyManagerService.java
/*
* Copyright (C) 2007 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.lgy;
import com.android.server.SystemService;
import android.content.Context;
import android.util.Log;
import java.util.HashMap;
import android.os.ILgyManager;
public final class LgyManagerService extends ILgyManager.Stub{
private static final String TAG = "LgyManagerService";
final Context mContext;
private native String GetFromJni();
public LgyManagerService(Context context) {
mContext = context;
}
@Override
public String getVal(){
try{
Log.d("lgy_bubug", "GetFromJni ");
return GetFromJni();
}catch(Exception e){
Log.d("lgy_bubug", "nativeReadPwd Exception msg = " + e.getMessage());
return " read nothings!!!";
}
}
}
4,添加对应的JNI
frameworks\base\services\core\jni\com_android_server_lgy_LgyManagerService.cpp
/*
* Copyright (C) 2011 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.
*/
#include "utils/Log.h"
#include "jni.h"
#include
#include "android_runtime/AndroidRuntime.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
/*
#include "libnvram.h"
#include "CFG_file_lid.h"
#include "CFG_PRODUCT_INFO_File.h"
#include "Custom_NvRam_LID.h"
#include "CFG_Wifi_File.h"
#include "CFG_BT_File.h"
*/
//#include "libnvram.h"
//#include "Custom_NvRam_LID.h"
//#include "CFG_PRODUCT_INFO_File.h"
namespace android
{
#define NETLINK_TEST (25)
#define MAX_PAYLOAD (1024)
#define TEST_PID (100)
#define LOGI(fmt, args...) //__android_log_print(ANDROID_LOG_INFO, UTAG, fmt, ##args)
#define LOGW(fmt, args...) //__android_log_print(ANDROID_LOG_WARN, UTAG, fmt, ##args)
#define LOGE(fmt, args...) //__android_log_print(ANDROID_LOG_ERROR, UTAG, fmt, ##args)
#define PRO_INFO_SIZE 16384
//#define DRIVER_NAME "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq"
//#define DRIVER_NAME "/sys/class/timed_output/vibrator/enable"
#define MAX_DESCRIPTORS_LENGTH 4096
inline const sockaddr * asSockaddr(const sockaddr_nl *nladdr) {
return reinterpret_cast(nladdr);
}
static jstring android_server_lgy_LgyManagerService_GetFromJni(JNIEnv *env, jobject) {
std::string netlink_recvmsg_ok = "netlink_recvmsg_ok";
std::string netlink_recvmsg_error = "netlink_recvmsg_error";
jstring j_str = env->NewStringUTF(netlink_recvmsg_error.c_str());
struct sockaddr_nl dest_addr;
struct nlmsghdr *nlh = NULL;
struct iovec iov;
int sock_fd=-1;
struct msghdr msg;
if((sock_fd=socket(AF_NETLINK, SOCK_RAW,NETLINK_TEST))<0){
return j_str = env->NewStringUTF(netlink_recvmsg_error.c_str());
}
memset(&dest_addr, 0, sizeof(dest_addr));
dest_addr.nl_family = AF_NETLINK;
dest_addr.nl_pid = 100; /*我们的消息是发给内核的*/
dest_addr.nl_groups = 0; /*在本示例中不存在使用该值的情况*/
if(bind(sock_fd, (struct sockaddr*)&dest_addr, sizeof(dest_addr))<0){
}
if(NULL == (nlh=(struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD)))){
}
memset(nlh,0,MAX_PAYLOAD);
char message[] = "getMcuStatus";
int len =strlen(message)+1;
nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD);
nlh->nlmsg_pid = 100;//getpid();
nlh->nlmsg_flags = 0;
memcpy(NLMSG_DATA(nlh), message, len);
/*这个是模板,暂时不用纠结为什么要这样用。*/
memset(&iov, 0, sizeof(iov));
iov.iov_base = (void *)nlh;
iov.iov_len = nlh->nlmsg_len;
memset(&msg, 0, sizeof(msg));
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
sendmsg(sock_fd, &msg, 0); //通过Netlink socket向内核发送消息
//接收内核消息的消息
memset((char*)NLMSG_DATA(nlh),0,1024);
if((recvmsg(sock_fd,&msg,0))>0){
j_str = env->NewStringUTF((char*)NLMSG_DATA(nlh));
}
close(sock_fd);
free(nlh);
return j_str;
/* int fd = open(DRIVER_NAME, O_RDWR);
if(fd < 0 ){
return env->NewStringUTF(neo_error.c_str());
}
//jbyte buffer[64];
char buffer[64];
//size_t numUSC2Bytes = 0;
jstring j_str = env->NewStringUTF(neo_ok.c_str());
int numBytes = read(fd, buffer, sizeof(buffer));
if (numBytes > 0) {
//j_str = env->NewStringUTF(numBytes_ok.c_str());
j_str = env->NewStringUTF(buffer);
} else {
j_str = env->NewStringUTF(numBytes_error.c_str());
}
close(fd);
return j_str;
*/
}
static const JNINativeMethod method_table[] = {
{"GetFromJni","()Ljava/lang/String;",(void*)android_server_lgy_LgyManagerService_GetFromJni},
};
int register_android_server_LgyManagerService(JNIEnv *env)
{
LOGE("register_android_server_LgyManagerService.");
jclass clazz = env->FindClass("com/android/server/lgy/LgyManagerService");
if (clazz == NULL) {
LOGE("Can't find com/android/server/lgy/LgyManagerService");
return -1;
}
return jniRegisterNativeMethods(env, "com/android/server/lgy/LgyManagerService",
method_table, NELEM(method_table));
}
};
5,将新建的jni也添加到frameworks\base\services\core\jni\Android.bp中
"com_android_server_power_PowerManagerService.cpp",
"com_android_server_lgy_LgyManagerService.cpp",
6,frameworks\base\services\core\jni\onload.cpp中注册
com_android_server_lgy_LgyManagerService
int register_android_server_PowerManagerService(JNIEnv* env);
int register_android_server_LgyManagerService(JNIEnv* env);
7,在frameworks\base\services\java\com\android\server\SystemServer.java中启动我们的服务
private void startOtherServices() {
LgyManagerService lgyService = null;//lgy
.......
.......
.......
traceBeginAndSlog("StartVibratorService");
vibrator = new VibratorService(context);
ServiceManager.addService("vibrator", vibrator);
traceEnd();
//lgy
traceBeginAndSlog("StartLgyManService");
try {
if(lgyService==null){
lgyService = new LgyManagerService(context);
}
ServiceManager.addService("lgy", lgyService);
} catch (Throwable e) {
Slog.e(TAG, "Failure starting LgyManagerService ", e);
}
traceEnd();
//lgy
}
8,添加给运用层调用的接口
a), frameworks\base\core\java\android\os\LgyManager.java
/*
* Copyright (C) 2007 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 android.os;
import android.annotation.SystemService;
import android.content.Context;
import android.util.Log;
import android.os.Handler;
import android.os.SystemProperties;
import java.io.IOException;
import java.io.DataInputStream;
//@SystemService(Context.LGY_SERVICE)
public final class LgyManager {
private static final String TAG = "LgyManager";
final Context mContext;
final ILgyManager mService;
/**
* {@hide}
*/
public LgyManager(Context context, ILgyManager service, Handler handler) {
mContext = context;
mService = service;
mHandler = handler;
}
public String getVal() {
Log.d(TAG,"lgy_debug getVal ");
try {
return mService.getVal();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}
b) frameworks\base\core\java\android\content\Context.java 添加
+++ public static final String LGY_SERVICE = "lgy";
/** @hide */
@StringDef(suffix = { "_SERVICE" }, value = {
POWER_SERVICE,
WINDOW_SERVICE,
LAYOUT_INFLATER_SERVICE,
ACCOUNT_SERVICE,
ACTIVITY_SERVICE,
ALARM_SERVICE,
NOTIFICATION_SERVICE,
ACCESSIBILITY_SERVICE,
CAPTIONING_SERVICE,
KEYGUARD_SERVICE,
LOCATION_SERVICE,
//@hide: COUNTRY_DETECTOR,
SEARCH_SERVICE,
SENSOR_SERVICE,
STORAGE_SERVICE,
STORAGE_STATS_SERVICE,
WALLPAPER_SERVICE,
TIME_ZONE_RULES_MANAGER_SERVICE,
VIBRATOR_SERVICE,
+++ LGY_SERVICE,
c),frameworks\base\core\java\android\app\SystemServiceRegistry.java
registerService(Context.LGY_SERVICE, LgyManager.class,
new CachedServiceFetcher() {
@Override
public LgyManager createService(ContextImpl ctx) throws ServiceNotFoundException {
IBinder b = ServiceManager.getServiceOrThrow(Context.LGY_SERVICE);
ILgyManager service = ILgyManager.Stub.asInterface(b);
return new LgyManager(ctx.getOuterContext(),
service, ctx.mMainThread.getHandler());
}});
9,添加Selinux
完成上边8个步骤,adb shell service list 发现并没有我们的service,那是因为没添加Selinux这部分。
这部分改的比较多。不打算一个个的贴出来了,按照系统有的服务(Vibrator、 PowerManager),仿着添加就可以了。