软件平台:Android11
硬件平台:QCS6125
直接上需求:首先添加自定义系统服务并且开机自启动;其次该服务要调用HW层service的方法。
前半部分之前添加过N次,不是难点,后半部分的实现最开始也是想借助binder通信,直接去调用接口,遇到了一大堆selinux权限问题,这是google针对android8.0之后新添加的策略,使用了三个binder,分别是标准/dev/binder该节点主要用于System分区的系统服务去注册使用,/dev/hwbinder该节点主要用于运行于HW的服务注册使用,/dev/vndbinder该节点主要用于运行在vendor分区的服务注册使用,而需求中所说的HW层的服务注册的是vndbinder,自定义的服务是binder,因此系统层面是隔离的,无法通过binder直接通信,只能通过hwbinder去迂回,因为binder可以跟hwbinder通信,而hwbinder可以和vndbinder交互,从而达到binder服务和vndbinder服务通信的目的。
前半部分(系统服务)的实现:
1、创建frameworks/base/core/java/android/app/yfd/目录,建立如下文件:
HandWriteManager.java
/*************************************************************************
* File Name: HandWriteManager.java
* Author: kongbo
* Mail: shenyoutianji@126.com
* Created Time: 2022年11月21日 星期一 17时17分35秒
************************************************************************/
package android.app.yfd;
import android.content.Context;
import android.os.RemoteException;
import android.util.Slog;
public class HandWriteManager {
Context mContext;
IHandWriteManager mService;
static final String TAG = "HandWriteManager";
public HandWriteManager(Context context, IHandWriteManager service) {
mContext = context;
mService = service;
if (mService != null)
Slog.d(TAG, " mService not null");
}
public void setRefreshMode(int mode) {
if (mService != null) {
Slog.d(TAG, " Will setRefreshMode");
try {
mService.setRefreshMode(mode);
} catch (RemoteException e) {
Slog.d(TAG, "RemoteException " + e);
}
}
//return null;
}
public void commitRefreshArea(int x, int y, int h, int w) {
if (mService != null) {
Slog.d(TAG, " Will commitRefreshArea");
try {
mService.commitRefreshArea(x, y, h, w);
} catch (RemoteException e) {
Slog.d(TAG, "RemoteException " + e);
}
}
}
}
IHandWriteManager.aidl
/**
* Hand Writes Service
*/
package android.app.yfd;
interface IHandWriteManager {
void setRefreshMode(int mode);
void commitRefreshArea(int x, int y, int h, int w);
}
frameworks/base/services/core/java/com/android/server目录添加HandWriteManagerService.java
/*************************************************************************
* File Name: HandWriteManagerService.java
* Author: kongbo
* Mail:nubility@gmail.com
* Created Time: 2022年11月21日 星期一 17时36分04秒
************************************************************************/
package com.android.server;
import android.app.yfd.IHandWriteManager;
import android.content.Context;
import android.os.Build;
import android.util.Slog;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.FileReader;
import java.io.IOException;
public class HandWriteManagerService extends IHandWriteManager.Stub {
private Context mContext;
static final String TAG = "HandWriteManagerService";
private boolean Debug = true;
private final int LEISURE_MODE = 1;
private final int WRITE_MODE = 2;
private final int NETWORK_MODE = 3;
private native void HandWriteServiceNative_setRefreshMode(int mode);
private native void HandWriteServiceNative_Init();
private native void HandWriteServiceNative_commitRefreshArea(int x, int y, int h, int w);
public HandWriteManagerService(Context context) {
//Slog.e(TAG," ====== call native method HandWriteServiceNative_Init");
HandWriteServiceNative_Init();
mContext = context;
/*try {
Slog.e(TAG," ====== Runtime will exec ======");
Runtime.getRuntime().exec("su");
Runtime.getRuntime().exec("vndservice call display.qservice 47 i32 2");
Slog.e(TAG," ====== Runtime exec end ======");
} catch (IOException e) {
Slog.e(TAG," ====== Runtime exec has exception ======");
e.printStackTrace();
}*/
}
@Override
public void setRefreshMode(int mode) {
BufferedWriter bufWriter = null;
try {
//bufWriter = new BufferedWriter(new FileWriter(LMAP_BRIGHTNESS_PATH));
if (Debug)
Slog.e(TAG," ====== write brightness:");
HandWriteServiceNative_setRefreshMode(mode);
//bufWriter.write(String.valueOf(brightness));
//bufWriter.close();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void commitRefreshArea(int x, int y, int h, int w) {
HandWriteServiceNative_commitRefreshArea(x, y, h, w);
}
}
向SystemServer完成注册:
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 3d8328bd193..1279df76dd5 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -89,6 +89,7 @@ import com.android.internal.util.ConcurrentUtils;
import com.android.internal.util.EmergencyAffordanceManager;
import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.widget.ILockSettings;
+import com.android.server.HandWriteManagerService;
import com.android.server.am.ActivityManagerService;
import com.android.server.appbinding.AppBindingService;
import com.android.server.attention.AttentionManagerService;
@@ -1614,6 +1615,16 @@ public final class SystemServer {
}
t.traceEnd();
+ t.traceBegin("StartHandWriteManagerService");
+ try {
+ Slog.i(TAG, "HandWriteManagerService is create");
+ ServiceManager.addService(Context.HAND_WRITE_SERVICE,
+ new HandWriteManagerService(context));
+ } catch (Throwable e) {
+ reportWtf("starting HandWriteManagerService", e);
+ }
+ t.traceEnd();
+
t.traceBegin("StartNotificationManager");
mSystemServiceManager.startService(NotificationManagerService.class);
SystemNotificationChannels.removeDeprecated(context);
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index e599a5ce81e..38473ee5e6e 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -43,6 +43,8 @@ import android.app.usage.IUsageStatsManager;
import android.app.usage.NetworkStatsManager;
import android.app.usage.StorageStatsManager;
import android.app.usage.UsageStatsManager;
+import android.app.yfd.HandWriteManager;
+import android.app.yfd.IHandWriteManager;
import android.appwidget.AppWidgetManager;
import android.bluetooth.BluetoothManager;
import android.companion.CompanionDeviceManager;
@@ -1189,6 +1191,17 @@ public final class SystemServiceRegistry {
}
});
+ registerService(Context.HAND_WRITE_SERVICE, HandWriteManager.class,
+ new CachedServiceFetcher<HandWriteManager>() {
+ @Override
+ public HandWriteManager createService(ContextImpl ctx)
+ throws ServiceNotFoundException {
+ IBinder b = ServiceManager.getServiceOrThrow(
+ Context.HAND_WRITE_SERVICE);
+ return new HandWriteManager(ctx, IHandWriteManager.Stub.asInterface(b));
+ }
+ });
+
registerService(Context.SLICE_SERVICE, SliceManager.class,
new CachedServiceFetcher<SliceManager>() {
@Override
在Context.java添加服务ID定义:
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 8472144a92c..d9ee340cd55 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -5024,6 +5024,15 @@ public abstract class Context {
*/
public static final String CROSS_PROFILE_APPS_SERVICE = "crossprofileapps";
+ /**
+ * Use with {@link #getSystemService(String)} to retrieve a
+ * {@link android.app.yfd.HandWriteManager} for handwriting
+ *
+ * @see #getSystemService(String)
+ * @see android.app.yfd.HandWriteManager
+ */
+ public static final String HAND_WRITE_SERVICE = "hand_write";
+
/**
* Use with {@link #getSystemService} to retrieve a
* {@link android.se.omapi.ISecureElementService}
此时增量编译代码,会提示api需要更新还有一个lint检测的报错,API更新执行make update-api指令,去掉lint检查需要修改framework/base/Android.bp如下:
diff --git a/Android.bp b/Android.bp
index bf6c99d0cf2..bb4a6a9a4e7 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1219,7 +1219,8 @@ metalava_framework_docs_args = "--manifest $(location core/res/AndroidManifest.x
"--api-lint-ignore-prefix android.icu. " +
"--api-lint-ignore-prefix java. " +
"--api-lint-ignore-prefix junit. " +
- "--api-lint-ignore-prefix org. "
+ "--api-lint-ignore-prefix org. " +
+ "--api-lint-ignore-prefix android.app.yfd. "
build = [
"StubLibraries.bp",
在执行完make update-api之后,系统会自动更新api文件:
diff --git a/api/current.txt b/api/current.txt
index 952ccdad992..f91544dde68 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -8106,6 +8106,37 @@ package android.app.usage {
}
+package android.app.yfd {
+
+ public class HandWriteManager {
+ ctor public HandWriteManager(android.content.Context, android.app.yfd.IHandWriteManager);
+ method public void commitRefreshArea(int, int, int, int);
+ method public void setRefreshMode(int);
+ }
+
+ public interface IHandWriteManager extends android.os.IInterface {
+ method public void commitRefreshArea(int, int, int, int) throws android.os.RemoteException;
+ method public void setRefreshMode(int) throws android.os.RemoteException;
+ }
+
+ public static class IHandWriteManager.Default implements android.app.yfd.IHandWriteManager {
+ ctor public IHandWriteManager.Default();
+ method public android.os.IBinder asBinder();
+ method public void commitRefreshArea(int, int, int, int) throws android.os.RemoteException;
+ method public void setRefreshMode(int) throws android.os.RemoteException;
+ }
+
+ public abstract static class IHandWriteManager.Stub extends android.os.Binder implements android.app.yfd.IHandWriteManager {
+ ctor public IHandWriteManager.Stub();
+ method public android.os.IBinder asBinder();
+ method public static android.app.yfd.IHandWriteManager asInterface(android.os.IBinder);
+ method public static android.app.yfd.IHandWriteManager getDefaultImpl();
+ method public boolean onTransact(int, android.os.Parcel, android.os.Parcel, int) throws android.os.RemoteException;
+ method public static boolean setDefaultImpl(android.app.yfd.IHandWriteManager);
+ }
+
+}
+
package android.appwidget {
public class AppWidgetHost {
@@ -10190,6 +10221,7 @@ package android.content {
field public static final String EUICC_SERVICE = "euicc";
field public static final String FILE_INTEGRITY_SERVICE = "file_integrity";
field public static final String FINGERPRINT_SERVICE = "fingerprint";
+ field public static final String HAND_WRITE_SERVICE = "hand_write";
field public static final String HARDWARE_PROPERTIES_SERVICE = "hardware_properties";
field public static final String INPUT_METHOD_SERVICE = "input_method";
field public static final String INPUT_SERVICE = "input";
diff --git a/non-updatable-api/current.txt b/non-updatable-api/current.txt
index 5f15216e840..c6047ab6ff4 100644
--- a/non-updatable-api/current.txt
+++ b/non-updatable-api/current.txt
@@ -8106,6 +8106,37 @@ package android.app.usage {
}
+package android.app.yfd {
+
+ public class HandWriteManager {
+ ctor public HandWriteManager(android.content.Context, android.app.yfd.IHandWriteManager);
+ method public void commitRefreshArea(int, int, int, int);
+ method public void setRefreshMode(int);
+ }
+
+ public interface IHandWriteManager extends android.os.IInterface {
+ method public void commitRefreshArea(int, int, int, int) throws android.os.RemoteException;
+ method public void setRefreshMode(int) throws android.os.RemoteException;
+ }
+
+ public static class IHandWriteManager.Default implements android.app.yfd.IHandWriteManager {
+ ctor public IHandWriteManager.Default();
+ method public android.os.IBinder asBinder();
+ method public void commitRefreshArea(int, int, int, int) throws android.os.RemoteException;
+ method public void setRefreshMode(int) throws android.os.RemoteException;
+ }
+
+ public abstract static class IHandWriteManager.Stub extends android.os.Binder implements android.app.yfd.IHandWriteManager {
+ ctor public IHandWriteManager.Stub();
+ method public android.os.IBinder asBinder();
+ method public static android.app.yfd.IHandWriteManager asInterface(android.os.IBinder);
+ method public static android.app.yfd.IHandWriteManager getDefaultImpl();
+ method public boolean onTransact(int, android.os.Parcel, android.os.Parcel, int) throws android.os.RemoteException;
+ method public static boolean setDefaultImpl(android.app.yfd.IHandWriteManager);
+ }
+
+}
+
package android.appwidget {
public class AppWidgetHost {
@@ -10190,6 +10221,7 @@ package android.content