Android P注册系统服务

以HsaeAudioManager为例,底层服务提供API给应用层使用.
1、定义AIDL接口
\vendor\hsae\frameworks\base\core\java\com\hsae\audio\IHsaeAudioManager.aidl

// IHsaeAudioManager.aidl
package com.hsae.audio;

// Declare any non-default types here with import statements
import com.hsae.audio.ILcFilterResultCallback;
import com.hsae.audio.IAudioCtrlServiceClient;
import android.os.Message;

interface IHsaeAudioManager {
	int setVol(String source, int volume);
    int setMute(String source, boolean mute, int ramp,int fastMode);
	int setRoomMode(int roomMode);
}

2、AIDL服务端代码实现
\vendor\hsae\frameworks\base\core\java\com\hsae\audio\HsaeAudioManager.java

public class HsaeAudioManager {
	private final static String TAG = "HsaeAudioManager";
	
	// = IHsaeAudioManager.Stub.asInterface( ServiceManager.getService(HsaeContext.HSAE_VEHICLE_AUDIO) );
	private IHsaeAudioManager mIHsaeAudioManager;

	private final String SERVICE_CONTEXT = "com.hsae.audio.IHsaeAudioManager";

    /**
     * {@hide} 
    */
    public static HsaeAudioManager getInstance(Context context,IHsaeAudioManager service) {
        synchronized (HsaeAudioManager.class) {
            if (null == mInstance)
                mInstance = new HsaeAudioManager(context,service);
            return mInstance;
        }
    }

    private HsaeAudioManager(Context context,IHsaeAudioManager service) {
        if(context != null && service != null){
            mIHsaeAudioManager = service;
        }
    }
	
	private IHsaeAudioManager getStub() {
        return mIHsaeAudioManager;
    }
	public int setVol(String source, int volume) {
        if (null == getStub()) {
            Log.e( TAG,"stub is null" );
            return -1;
        }
        try {
            return getStub().setVol( source, volume );
        } catch (RemoteException e) {
            Log.i( TAG,"setVol error : " + e.toString() );
            return -1;
        }
    }
	
    public int setMute(String source, boolean mute, int ramp, int fastMode) {
        if (null == getStub()) {
            Log.e( TAG,"stub is null" );
            return -1;
        }
        try {
            return getStub().setMute( source, mute, ramp, fastMode );
        } catch (RemoteException e) {
            Log.i( TAG,"setMute error : " + e.toString() );
            return -1;
        }
    }
	
    public int setRoomMode(int roomMode) {
        // 0x00 stereo all mode
        // 0x01 stereo driver mode
        // 0x08 bt phone mode
        if (null == getStub()) {
            Log.e( TAG,"stub is null" );
            return -1;
        }
        try {
            return getStub().setRoomMode(roomMode);
        } catch (RemoteException e) {
            Log.i( TAG,"setRoomMode error : " + e.toString() );
            return -1;
        }
    }
}

3、注册HsaeAudioManager到SystemService
定义Context
\vendor\hsae\frameworks\base\core\java\hsae\content\HsaeContext.java

package hsae.content;

@SuppressWarnings("JavadocReference")
public abstract class HsaeContext {
    /**
     * Use with {@link #getSystemService(String)} to retrieve a {@link
     * com.hsae.audio.HsaeAudioManager} for controlling audio
     * .
     *
     * @see com.hsae.audio.HsaeAudioManager
     */
    public static final String HSAE_VEHICLE_AUDIO = "hsae.audio";


    /**
     * @hide Use with {@link #getSystemService(String)} to retrieve a {@link
     * com.hase.mediasrcmanager.SrcManagerService} for controlling source
     * 
     * @see com.hase.mediasrcmanager.SrcManagerService
     */
    public static final String HSAE_SRC_MANAGER = "hsae.SrcManager";
}

注册服务
\frameworks\base\core\java\android\app\HsaeSystemServiceRegistry.java
\vendor\hsae\frameworks\base\core\java\android\app\HsaeSystemServiceRegistryImpl.java

package android.app;

import android.util.Slog;

 /** {@hide} */
class HsaeSystemServiceRegistry {
    static final String TAG = "HsaeSystemServiceRegistry";
    private static HsaeSystemServiceRegistry reflectClass = null;

    /** {@hide} */
    public static HsaeSystemServiceRegistry getInstance() {
        if(reflectClass != null){
            return reflectClass;
        }
        try {
            Class<?> cls = Class.forName("android.app.HsaeSystemServiceRegistryImpl");
            reflectClass = (HsaeSystemServiceRegistry) cls.newInstance();
            Slog.i(TAG, "reflect pass cls:" + cls.getSimpleName());
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        if (reflectClass == null) {
            reflectClass = new HsaeSystemServiceRegistry();
        }
        return reflectClass;
    }

    /**
     * Gets a system service from a given context.
     * {@hide}
     */
    Object getSystemService(ContextImpl ctx, String name) {
        return null;
    }

    /**
     * Gets the name of the system-level service that is represented by the specified class.
     * {@hide}
     */
    String getSystemServiceName(Class<?> serviceClass) {
        return null;
    }
}
import android.app.SystemServiceRegistry.*;
import android.os.IBinder;
import android.os.ServiceManager;
import android.os.ServiceManager.ServiceNotFoundException;
import com.hsae.libsrcmanager.ISrcManager;
import com.hsae.libsrcmanager.HsaeSrcManager;
import com.hsae.audio.HsaeAudioManager;
import com.hsae.audio.IHsaeAudioManager;
import java.util.HashMap;
import hsae.content.HsaeContext;

final class HsaeSystemServiceRegistryImpl extends HsaeSystemServiceRegistry {
	// Service registry information.
    // This information is never changed once static initialization has completed.
    private static final HashMap<Class<?>, String> SYSTEM_SERVICE_NAMES = new HashMap<>();
    private static final HashMap<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS = new HashMap<>();

    static {
    registerService(HsaeContext.HSAE_VEHICLE_AUDIO, HsaeAudioManager.class,
            new CachedServiceFetcher<HsaeAudioManager>() {
            	//讲HsaeAudioManagerService注册到系统服务中,并创建HsaeAudioManager的实例化对象
                @Override
                public HsaeAudioManager createService(ContextImpl ctx) throws ServiceNotFoundException {
                    IBinder b = ServiceManager.getServiceOrThrow(HsaeContext.HSAE_VEHICLE_AUDIO);
                    IHsaeAudioManager service = IHsaeAudioManager.Stub.asInterface(b);
                    return HsaeAudioManager.getInstance(ctx, service);
                }
            });

}
	}

    /**
     * Gets a system service from a given context.
     * {@hide}
     */
    @Override
    Object getSystemService(ContextImpl ctx, String name) {
        //Log.i(TAG, "getSystemService name:" + name);
        //Log.i(TAG, "SYSTEM_SERVICE_FETCHERS:" + SYSTEM_SERVICE_FETCHERS.toString());
        ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
        return fetcher != null ? fetcher.getService(ctx) : null;
    }

    /**
     * Gets the name of the system-level service that is represented by the specified class.
     * {@hide}
     */
    @Override
    String getSystemServiceName(Class<?> serviceClass) {
        //Log.i(TAG, "SYSTEM_SERVICE_NAMES:" + SYSTEM_SERVICE_NAMES.toString());
        return SYSTEM_SERVICE_NAMES.get(serviceClass);
    }

    /**
     * Statically registers a system service with the context.
     * This method must be called during static initialization only.
     * {@hide}
     */
    private static <T> void registerService(String serviceName, Class<T> serviceClass,
                                            ServiceFetcher<T> serviceFetcher) {
        //Log.i(TAG, "serviceName:" + serviceName + " serviceClass:" + serviceClass.toString() + "  serviceFetcher:" + serviceFetcher.toString());
        SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName);
        SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher);
    }

4、服务器端用法

public class HsaeAudioManagerService extends IHsaeAudioManager.Stub {

    public HsaeAudioManagerService(Context context) {
        mContext = context;
        HandlerThread handlerThread = new HandlerThread("HsaeAudioManagerServiceDispatch");
        handlerThread.start();
        mHandler = new AudioControlHandler(handlerThread.getLooper());
    }

    public static class Lifecycle extends SystemService {
        public Lifecycle(Context context) {
            super(context);
        }

        @Override
        public void onStart() {
            Log.d(TAG, "Lifecycle onStart");
            mHsaeAudioManagerService = new HsaeAudioManagerService(getContext());
            publishBinderService(HsaeContext.HSAE_VEHICLE_AUDIO, mHsaeAudioManagerService);
            mHsaeAudioManagerService.start();
        }

        @Override
        public void onBootPhase(int phase) {
            Log.d(TAG, "Lifecycle onBootPhase phase:" + phase);
            if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
                mHsaeAudioManagerService.systemReady();
            } else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
                mHsaeAudioManagerService.bootCompleted();
            }
        }

        @Override
        public void onSwitchUser(int userHandle) {
            Log.d(TAG, "Lifecycle onSwitchUser userHandle:" + userHandle);
        }

        @Override
        public void onUnlockUser(int userHandle) {
            Log.d(TAG, "Lifecycle onUnlockUser userHandle:" + userHandle);
            mHsaeAudioManagerService.onUnlockUser(userHandle);
        }

        @Override
        public void onCleanupUser(int userHandle) {
            Log.d(TAG, "Lifecycle onCleanupUser userHandle:" + userHandle);
            mHsaeAudioManagerService.onCleanupUser(userHandle);
        }
    }



    @Override
    public int setVol(String source, int volume) throws RemoteException {
        boolean ret = false;
		// do something
        if (ret == true) {
            return 0;
        } else {
            return -1;
        }
    }

    @Override
    public int setMute(String source, boolean mute, int remp, int fastMode) throws RemoteException {
        int mMute;

        boolean ret = false;
        if (!source.equals(HsaeAudioManager.AUDIO_SOURCE_NONE)) {
            if (true == mute) {
                mMute = 1;
            } else {
                mMute = 0;
            }
            ret = sendAudioMessage(mHandler, MSG_AUDIO_SET_MUTE, mMute, 
                mAudioSourceManager.getSourceRamp(source), source);
        }
        if (ret == true) {
            return 0;
        } else {
            return -1;
        }
    }
}

重点关注使用系统publishBinderService()注册Binder服务。

在SystemServiceRegistry.java中注册HsaeSystemServiceRegistry,
\frameworks\base\core\java\android\app\SystemServiceRegistry.java

	//...
	static {
	        HsaeSystemServiceRegistry.getInstance();
	}
	
    /**
     * Gets a system service from a given context.
     */
    public static Object getSystemService(ContextImpl ctx, String name) {
        ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
        Object serviceObject = fetcher != null ? fetcher.getService(ctx) : null;
        if (serviceObject == null)
            serviceObject = HsaeSystemServiceRegistry.getInstance().getSystemService(ctx, name);
        return serviceObject;
    }

    /**
     * Gets the name of the system-level service that is represented by the specified class.
     */
    public static String getSystemServiceName(Class<?> serviceClass) {
        String name = SYSTEM_SERVICE_NAMES.get(serviceClass);
        if (name == null)
            name = HsaeSystemServiceRegistry.getInstance().getSystemServiceName(serviceClass);
        return name;
    }
	//...

可以看到,在应用层app去调用getSystemService获取HsaeAudioManager实例对象时,HsaeSystemServiceRegistryImpl会进行实例化,初始化中会把HsaeAudioManagerService注册到系统服务中。

该处需要注意的地方:
此处修改了Android系统源码,源生开放API中getSystemService(),当获取到的serviceObject 为null时,说明应用层调用的可能是自定义的系统服务,即到HsaeSystemServiceRegistry中寻找注册的系统服务。

HsaeAudioManagerService在SystemServer中启动,
/vendor/hsaeframeworks/base/services/java/com/android/server/HsaeSystemServer.java

/*
 * Copyright (C) 2006 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.os.ServiceManager;
import android.util.Slog;

import com.hsae.server.HsaeAccessibilityManagerService;
import com.hsae.server.HsaeConstant;
import com.hsae.server.HsaeSystemUtils;
import com.hsae.server.HsaeTimeControl;
import com.hsae.server.autosdk.AutoSettings;
import com.hsae.server.autosdk.AutoSettingsExternal;
import com.hsae.server.autosdk.PopupStub;
import com.hsae.server.autosdk.Source;
import com.hsae.server.autosdk.Vehicle;
import com.hsae.server.canservice.CanManagerService;
import com.hsae.server.devipc.DevipcManagerService;
import com.hsae.server.dm.HsaeDeviceManagerService;
import com.hsae.server.key.CarKeyService;
import com.hsae.server.meter.MeterManagerService;
import com.hsae.server.audio.HsaeAudioManagerService;
import com.hsae.server.powermode.PowerModeService;

import hsae.content.HsaeContext;

public final class HsaeSystemServer extends VendorSystemServer {
    private static final String TAG = "HsaeSystemServer";

    public HsaeSystemServer() {
        Slog.w(TAG, "start HsaeSystemServer");
    }

    @Override
    protected void run() {
        Slog.w(TAG, "start run()");
    }

    @Override
    protected boolean isFirstBootOrUpgrade() {
        return true;
    }

    @Override
    protected void reportWtf(String msg, Throwable e) {
    }

    @Override
    protected void performPendingShutdown() {
    }

    @Override
    protected void createSystemContext(Context context) {
        Slog.w(TAG, " createSystemContext() context:" + context);
        mContext = context;
    }

    /**
     * Starts the small tangle of critical services that are needed to get
     * the system off the ground.  These services have complex mutual dependencies
     * which is why we initialize them all in one place here.  Unless your service
     * is also entwined in these dependencies, it should be initialized in one of
     * the other functions.
     */
    @Override
    protected void startBootstrapServices() {
        Slog.w(TAG, "start startBootstrapServices");
        traceBeginAndSlog("Start  HsaeAccessibilityManagerService");
        HsaeAccessibilityManagerService accessibility = new HsaeAccessibilityManagerService(mContext);
        ServiceManager.addService(HsaeContext.HSAE_ACCESSIBILITY, accessibility);
        traceEnd();
    }

    /**
     * Starts some essential services that are not tangled up in the bootstrap process.
     */
    @Override
    protected void startCoreServices() {
		//...

        Slog.w(TAG, "start startCoreServices");
        traceBeginAndSlog("Start  HsaeAudioManagerService");
        mSystemServiceManager.startService(HsaeAudioManagerService.Lifecycle.class);
        traceEnd();

		//...
    }

    /**
     * Starts a miscellaneous grab bag of stuff that has yet to be refactored
     * and organized.
     */
    @Override
    protected void startOtherServices() {
        Slog.w(TAG, "start startOtherServices");
		//...
    }
}

frameworks/base/services/java/com/android/server/VendorSystemServer.java

/*
 * Copyright (C) 2006 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.annotation.CallSuper;
import android.content.Context;
import android.os.Trace;
import android.util.Slog;
import android.util.TimingsTraceLog;

import java.lang.reflect.Constructor;

public class VendorSystemServer {
    private static final String TAG = "VendorSystemServer";
    private static VendorSystemServer vendorSystemServer;
    SystemServiceManager mSystemServiceManager;

    public Context mContext;

    private static final String SYSTEM_SERVER_TIMING_TAG = "VendorSystemServerTiming";

    private static final TimingsTraceLog BOOT_TIMINGS_TRACE_LOG
            = new TimingsTraceLog(SYSTEM_SERVER_TIMING_TAG,Trace.TRACE_TAG_SYSTEM_SERVER);

    /**
     * Start the sensor service. This is a blocking call and can take time.
     */
    private static native void startSensorService();

    /**
     * Start all HIDL services that are run inside the system server. This
     * may take some time.
     */
    private static native void startHidlServices();

    public VendorSystemServer() {
        Slog.w(TAG,"VendorSystemServer()");
    }

    public static VendorSystemServer getInstance() {
        VendorSystemServer vendorSystemServer = null;
        Slog.w(TAG,"getInstance()");
        try {
            Class<?> cls = Class.forName("com.android.server.HsaeSystemServer");
            vendorSystemServer = (VendorSystemServer) cls.newInstance();
            Slog.d(TAG,"reflect pass cls:" + cls.getSimpleName());
        } catch (Exception e) {
            // TODO Auto-generated catch block
            Slog.d(TAG,"initVendorHandle printStackTrace");
            e.printStackTrace();
            vendorSystemServer = null;
        }

        if (vendorSystemServer == null) {
            vendorSystemServer = new VendorSystemServer();
        }
        return vendorSystemServer;
    }

    @CallSuper
    protected void run() {
        Slog.w(TAG,"run()");
    }

    @CallSuper
    protected boolean isFirstBootOrUpgrade() {
        Slog.w(TAG,"isFirstBootOrUpgrade()");
        return true;
    }

    @CallSuper
    protected void reportWtf(String msg,Throwable e) {
        Slog.w(TAG,"reportWtf()");
    }

    @CallSuper
    protected void performPendingShutdown() {
        Slog.w(TAG,"performPendingShutdown()");
    }

    @CallSuper
    protected void createSystemContext(Context context) {
        mContext = context;
        Slog.w(TAG,"createSystemContext()");
    }

    /**
     * Starts the small tangle of critical services that are needed to get
     * the system off the ground.  These services have complex mutual dependencies
     * which is why we initialize them all in one place here.  Unless your service
     * is also entwined in these dependencies, it should be initialized in one of
     * the other functions.
     */
    @CallSuper
    protected void startBootstrapServices() {
        Slog.w(TAG,"startBootstrapServices()");
    }

    /**
     * Starts some essential services that are not tangled up in the bootstrap process.
     */
    @CallSuper
    protected void startCoreServices() {
        Slog.w(TAG,"startCoreServices()");
    }

    /**
     * Starts a miscellaneous grab bag of stuff that has yet to be refactored
     * and organized.
     */
    @CallSuper
    protected void startOtherServices() {
        Slog.w(TAG,"startOtherServices()");
    }

    protected static void traceBeginAndSlog(String name) {
        Slog.i(TAG,name);
        BOOT_TIMINGS_TRACE_LOG.traceBegin(name);
    }

    protected static void traceEnd() {
        BOOT_TIMINGS_TRACE_LOG.traceEnd();
    }

    public static <T> T loadVendorClass(String vendorClass) {
        try {
            Class<?> cls = Class.forName(vendorClass);
            T t = (T) cls.newInstance();
            Slog.d(TAG,"loadVendorClass :" + t + " success");
            return t;
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    public static <T> T loadVendorClass(String vendorClass,Class[] paramTypes,Object[] params) {
        try {
            Class<?> cls = Class.forName(vendorClass);
            Constructor con = cls.getConstructor(paramTypes);
            T t = (T) con.newInstance(params);
            Slog.d(TAG,"loadVendorClass :" + t + " success");
            return t;
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
}

frameworks/base/services/java/com/android/server/SystemServer.java

	private static final VendorSystemServer mVendorSystemServer = VendorSystemServer.getInstance();
	
    /**
     * The main entry point from zygote.
     */
    public static void main(String[] args) {
        mVendorSystemServer.run();
        new SystemServer().run();
    }

	/**
     * Starts the small tangle of critical services that are needed to get
     * the system off the ground.  These services have complex mutual dependencies
     * which is why we initialize them all in one place here.  Unless your service
     * is also entwined in these dependencies, it should be initialized in one of
     * the other functions.
     */
    private void startBootstrapServices() {
		//...

        if (mVendorSystemServer != null) {
            mVendorSystemServer.startBootstrapServices();
        }

		//...
	}

    /**
     * Starts some essential services that are not tangled up in the bootstrap process.
     */
    private void startCoreServices() {
    	//...

        if (mVendorSystemServer != null) {
            mVendorSystemServer.startCoreServices();
        }

		//...
	}

    /**
     * Starts a miscellaneous grab bag of stuff that has yet to be refactored
     * and organized.
     */
    private void startOtherServices() {
        //...

        if (mVendorSystemServer != null) {
            mVendorSystemServer.startOtherServices();
        }
        
    	//...

	}

5、应用app端代码

import com.hsae.audio.HsaeAudioManager;

public static HsaeAudioManager mHsaeAudioManager;

mHsaeAudioManager =(HsaeAudioManager) getActivity().getSystemService(HsaeContext.HSAE_VEHICLE_AUDIO);

if (mHsaeAudioManager != null) {
	int nReturn = mHsaeAudioManager.setMute(sourceIndex, true,0, 0);
}

//set volume to HsaeAudioManager
if (mHsaeAudioManager != null) {
	nReturn = mHsaeAudioManager.setVol(source, volume);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sunxiaolin2016

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值