Android9.0系统中添加自定义系统服务给APP调用

软件平台:Android9.0

硬件平台:Mtk8175

        近日开发了一个产品需求,APP端需要控制硬件LED灯,由于是多个APP需要调用,固计划将控制接口做成System Service级别的服务,APP可以通过跨进程调用相关的方法,话不多说,开干:

1、在frameworks/base/core/java/android/app/目录添加aidl接口文件,内容如下:

/**

* Lamp brightness controller

*/

package android.app;

interface IGeninLampManager {

    String getLampBrightness();

    void setLampSwitch(boolean switchOn);

    void setLampBrightness(int brightness);

    void setLampMode(int mode);

}

2、将该文件引入mk编译:

diff --git a/Android.bp b/Android.bp

index 282206126bc..1c2dadd6624 100644

--- a/Android.bp

+++ b/Android.bp

@@ -105,6 +105,7 @@ java_library {

         "core/java/android/app/usage/ICacheQuotaService.aidl",

         "core/java/android/app/usage/IStorageStatsManager.aidl",

         "core/java/android/app/usage/IUsageStatsManager.aidl",

+        "core/java/android/app/IGeninLampManager.aidl",

         ":libbluetooth-binder-aidl",

         "core/java/android/content/IClipboard.aidl",

         "core/java/android/content/IContentService.aidl",

3、创建注册系统级服务:

diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java

index 149af262441..4e016d92adb 100644

--- a/core/java/android/app/SystemServiceRegistry.java

+++ b/core/java/android/app/SystemServiceRegistry.java

@@ -31,6 +31,7 @@ import android.app.usage.IUsageStatsManager;

import android.app.usage.NetworkStatsManager;

import android.app.usage.StorageStatsManager;

import android.app.usage.UsageStatsManager;

+import android.app.GeninLampManager;

import android.appwidget.AppWidgetManager;

import android.bluetooth.BluetoothManager;

import android.companion.CompanionDeviceManager;

@@ -1002,6 +1003,16 @@ public final class SystemServiceRegistry {

                     }

                 });

+        registerService(Context.LAMP_MANAGER_SERVICE, GeninLampManager.class,

+                new CachedServiceFetcher<GeninLampManager>() {

+                @Override

+                public GeninLampManager createService(ContextImpl ctx) {

+                    IBinder b = ServiceManager.getService(Context.LAMP_MANAGER_SERVICE);

+                    IGeninLampManager service = IGeninLampManager.Stub.asInterface(b);

+                    return new GeninLampManager(ctx, service);

+                }});

+

+

         registerService(Context.SLICE_SERVICE, SliceManager.class,

                 new CachedServiceFetcher<SliceManager>() {

                     @Override

4、在frameworks/base/core/java/android/app/目录创建GeninLampManager.java

/**

* Lamp brightness controller

*/

package android.app;

import android.content.Context;

import android.os.RemoteException;

import android.util.Slog;

public class GeninLampManager {

    Context mContext;

    IGeninLampManager mService;

    static final String TAG = "GeninLampManager";

    public GeninLampManager(Context context, IGeninLampManager service) {

        mContext = context;

        mService = service;

        if (mService != null)

            Slog.d(TAG, " mService not null");

    }   

    public String getLampBrightness() {

        if (mService != null) {

            try {

                //Slog.d(TAG, " Will return getLampBrightness");

                return mService.getLampBrightness();

            } catch (RemoteException e) {

                Slog.d(TAG, "RemoteException " + e);

                return null;

            }   

        }   

        return null;

    }   

public void setLampSwitch(boolean switchOn) {

        if (mService != null) {

            try {

                //Slog.d(TAG, " Will setLampSwitch======");

                mService.setLampSwitch(switchOn);

            } catch (RemoteException e) {

                Slog.d(TAG, "RemoteException " + e);

            }   

        }

    }

    public void setLampMode(int mode) {

        if (mService != null) {

            try {

                //Slog.d(TAG, " Will setLampMode======");

                mService.setLampMode(mode);

            } catch (RemoteException e) {

                Slog.d(TAG, "RemoteException " + e);

            }

        }

    }

    public void setLampBrightness(int brightness) {

        if (mService != null) {

            try {

                //Slog.d(TAG, " Will setLampBrightness======");

                mService.setLampBrightness(brightness);

            } catch (RemoteException e) {

                Slog.d(TAG, "RemoteException " + e);

            }

        }

    }

}

同aidl文件声明的方法相对应,并实现;

5、在Context.java文件添加Service的注册名称,APP通过这个名称获取远程调用代理:

diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java

index 90a94ee7608..1e2328419fe 100644

--- a/core/java/android/content/Context.java

+++ b/core/java/android/content/Context.java

@@ -4199,6 +4199,8 @@ public abstract class Context {

      */

     public static final String CROSS_PROFILE_APPS_SERVICE = "crossprofileapps";

+    public static final String LAMP_MANAGER_SERVICE = "lampmanager";

+

     /**

      * Use with {@link #getSystemService} to retrieve a

      * {@link android.se.omapi.ISecureElementService}

6、实现Service服务实体类:

frameworks/base/services/core/java/com/android/server/GeninLampManagerService.java:

package com.android.server;

import android.app.IGeninLampManager;

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 GeninLapManagerService extends IGeninLampManager.Stub {

    private Context mContext;

    static final String TAG = "GeninLampManagerService";

    private boolean Debug = false;

    private final int LEISURE_MODE = 1;

    private final int WRITE_MODE = 2;

    private final int NETWORK_MODE = 3;

    // 台灯控制节点

    static public final String LMAP_SWITCH_PATH = "/sys/bus/i2c/drivers/as9072/3-0011/as9072_debug/power"; //写1关灯,写2开灯

    static public final String LMAP_MODE_PATH = "/sys/bus/i2c/drivers/as9072/3-0011/as9072_debug/mode"; //写1 休闲模式;2 书写模式 ,3网课模式

    static public final String LMAP_BRIGHTNESS_PATH = "/sys/bus/i2c/drivers/as9072/3-0011/as9072_debug/brightness_level"; //写0x1-0xd 13个亮度级别;

    public GeninLampManagerService(Context context) {

        mContext = context;

    }   

    @Override

    public String getLampBrightness() {

        String brightness = null;

        BufferedReader reader = null;

        try {

            reader = new BufferedReader(new FileReader(LMAP_BRIGHTNESS_PATH));

            brightness = reader.readLine();

            if (Debug) {

                Slog.e("======", "read lamp brightness: " + brightness);

            }   

       } catch (IOException e) {

            e.printStackTrace();

        } finally {

            if(reader != null){

                try {

                    reader.close();

                } catch (IOException e) {

                    e.printStackTrace();

                }

            }

        }

        return brightness;

    }

    @Override

    public void setLampBrightness(int brightness) {

        BufferedWriter bufWriter = null;

        try {

            bufWriter = new BufferedWriter(new FileWriter(LMAP_BRIGHTNESS_PATH));

            if (Debug)

                Slog.e(TAG,"write brightness:" + String.valueOf(brightness));

            bufWriter.write(String.valueOf(brightness));

            bufWriter.close();

        } catch (IOException e) {

            e.printStackTrace();

        }

    }

    @Override

    public void setLampMode(int mode) {

        BufferedWriter bufWriter = null;

        try {

            bufWriter = new BufferedWriter(new FileWriter(LMAP_MODE_PATH));

            if (mode == LEISURE_MODE) {

                if (Debug)

                    Slog.e(TAG,"Go to 1 mode.");

                bufWriter.write("1");

            } else if (mode == WRITE_MODE){

                if (Debug)

                   Slog.e(TAG,"Go to 2 mode.");

                bufWriter.write("2");

            } else if (mode == NETWORK_MODE) {

                if (Debug)

                    Slog.e(TAG,"Go to 3 mode.");

                bufWriter.write("3");

            }

            bufWriter.close();

        } catch (IOException e) {

            e.printStackTrace();

            Slog.e(TAG,"can't write the " + LMAP_MODE_PATH);

        }

    }

    @Override

    public void setLampSwitch(boolean switchOn) {

        BufferedWriter bufWriter = null;

        try {

            bufWriter = new BufferedWriter(new FileWriter(LMAP_SWITCH_PATH));

            if (switchOn) {

                bufWriter.write("2");  //ON

            } else {

                bufWriter.write("1");  //OFF

            }

            bufWriter.close();

        } catch (IOException e) {

            e.printStackTrace();

            Slog.e(TAG,"can't write the " + LMAP_SWITCH_PATH);

        }

    }

}

7、向SystemServer注册开机启动服务:

diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java

index b5274586d3b..640c141eac1 100644

--- a/services/java/com/android/server/SystemServer.java

+++ b/services/java/com/android/server/SystemServer.java

@@ -120,6 +120,7 @@ import com.android.server.usage.UsageStatsService;

import com.android.server.vr.VrManagerService;

import com.android.server.webkit.WebViewUpdateService;

import com.android.server.wm.WindowManagerService;

+import com.android.server.GeninLampManagerService;

import com.mediatek.server.MtkSystemServer;

@@ -1261,6 +1262,15 @@ public final class SystemServer {

             }

             traceEnd();

+            traceBeginAndSlog("StartGeninLampManagerService");

+            try {

+               Slog.i(TAG, "ClassMonitor Service is create");

+               ServiceManager.addService(Context.LAMP_MANAGER_SERVICE, new GeninLampManagerService(context));

+            } catch (Throwable e) {

+               reportWtf("starting ClassMonitorService", e);

+            }

+            traceEnd();

+

             traceBeginAndSlog("StartNotificationManager");

             mSystemServiceManager.startService(NotificationManagerService.class);

             SystemNotificationChannels.createAll(context);

8、返回代码根目录,更新一下api,执行make update-api -j32命令,这个执行完毕,framework/base/api目录的current.txt会更新:

diff --git a/api/current.txt b/api/current.txt

index 65de90fdf8a..fc55efa1b56 100644

--- a/api/current.txt

+++ b/api/current.txt

@@ -4926,6 +4926,28 @@ package android.app {

     field public static final int TRANSIT_UNSET = -1; // 0xffffffff

   }

+  public class GeninLampManager {

+    ctor public GeninLampManager(android.content.Context, android.app.IGeninLampManager);

+    method public java.lang.String getLampBrightness();

+    method public void setLampBrightness(int);

+    method public void setLampMode(int);

+    method public void setLampSwitch(boolean);

+  }

+

+  public abstract interface IGeninLampManager implements android.os.IInterface {

+    method public abstract java.lang.String getLampBrightness() throws android.os.RemoteException;

+    method public abstract void setLampBrightness(int) throws android.os.RemoteException;

+    method public abstract void setLampMode(int) throws android.os.RemoteException;

+    method public abstract void setLampSwitch(boolean) throws android.os.RemoteException;

+  }

+

+  public static abstract class IGeninLampManager.Stub extends android.os.Binder implements android.app.IGeninLampManager {

+    ctor public IGeninLampManager.Stub();

+    method public android.os.IBinder asBinder();

+    method public static android.app.IGeninLampManager asInterface(android.os.IBinder);

+    method public boolean onTransact(int, android.os.Parcel, android.os.Parcel, int) throws android.os.RemoteException;

+  }

+

   public class Instrumentation {

     ctor public Instrumentation();

     method public android.os.TestLooperManager acquireLooperManager(android.os.Looper);

@@ -10460,6 +10482,7 @@ package android.content {

     field public static final java.lang.String IPSEC_SERVICE = "ipsec";

     field public static final java.lang.String JOB_SCHEDULER_SERVICE = "jobscheduler";

     field public static final java.lang.String KEYGUARD_SERVICE = "keyguard";

+    field public static final java.lang.String LAMP_MANAGER_SERVICE = "lampmanager";

     field public static final java.lang.String LAUNCHER_APPS_SERVICE = "launcherapps";

     field public static final java.lang.String LAYOUT_INFLATER_SERVICE = "layout_inflater";

     field public static final java.lang.String LOCATION_SERVICE = "location";

到这一步,服务添加流程基本完成;

9、如何使用该服务接口:

在app的类文件导入服务类包名,然后通过servicemanager拿到代理,进行方法调用:

mManager = (GeninLampManager) mContext.getSystemService(Context.LAMP_MANAGER_SERVICE);

mManager.setLampBrightness(bright);

10、这一步至关重要,添加系统服务需要修改selinux规则,否则会无法操作内核的设备节点:

修改device/mediatek/sepolicy/bsp目录对应文件

diff --git a/non_plat/system_server.te b/non_plat/system_server.te

index 6565630..d9f627b 100644

--- a/non_plat/system_server.te

+++ b/non_plat/system_server.te

@@ -136,6 +136,10 @@ hal_client_domain(system_server,hal_dfps)

allow system_server mute_key_file:dir { search read };

allow system_server mute_key_file:file { read open getattr };

+# For system service lamp_mcu permission

+allow system_server mcu_file:dir { search read };

+allow system_server mcu_file:file { read write open getattr };

+

#============= system_server ==============

allow system_server audioserver:file write;

diff --git a/plat_private/service.te b/plat_private/service.te

index d1dcaab..58571c2 100644

--- a/plat_private/service.te

+++ b/plat_private/service.te

@@ -5,3 +5,4 @@

# Other Services

type aal_service, service_manager_type;

type mtk_connmetrics_service, service_manager_type;

+type genin_lamp_service, app_api_service, system_server_service, service_manager_type;

diff --git a/plat_private/service_contexts b/plat_private/service_contexts

index b2b0002..af224f9 100644

--- a/plat_private/service_contexts

+++ b/plat_private/service_contexts

@@ -28,6 +28,7 @@ search_engine_service                   u:object_r:mtk_search_engine_service:s0

duraspeed                               u:object_r:mtk_duraspeed_service:s0

FullscreenSwitchService                 u:object_r:mtk_fullscreen_switch_service:s0

fm_radio_service                        u:object_r:mtk_fm_radio_service:s0

+lampmanager                             u:object_r:genin_lamp_service:s0

# Other Services

GoogleOtaBinder                         u:object_r:ota_agent_service:s0

至此,添加完成~~~欢迎老细和张老师多提宝贵意见!

感谢!

  • 6
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值