以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);
}