Android 10 ServiceManager

自己看,如果不對(duì),請(qǐng)指出!

關(guān)聯(lián)類(lèi)

ServiceManager.java
framework 核心類(lèi),保存所有service的 binder引用,提供service添加和查詢(xún)接口。
是android中binder服務(wù)的管家,一般binder服務(wù)會(huì)先注冊(cè)到servicemanager中,
然后其他客戶(hù)端會(huì)通過(guò)servicemanager來(lái)獲取目標(biāo)binder的proxy binder,
這時(shí)候就可以通過(guò)獲取的proxy binder進(jìn)行ipc調(diào)用。
IServiceManager.java
提供ServiceManagerNative中的內(nèi)部類(lèi)ServiceManagerProxy跨進(jìn)程調(diào)用的接口
ServiceManagerNative.java
是個(gè)Binder類(lèi),需要了解AIDL的組成結(jié)構(gòu)
IInterface.java
提供基礎(chǔ)AIDL功能

與SystemServiceManager的區(qū)別

SystemServer中啟動(dòng)的各種服務(wù),在ServiceManager中注冊(cè)的是用于進(jìn)程間通信的,LocalServces中注冊(cè)的用于system_server進(jìn)程內(nèi)部通信的。
LocalServices中都是靜態(tài)方法,由SystemServiceManager啟動(dòng)并管理的服務(wù)都是是繼承了SystemService的。SystemService中很多方法都是通過(guò)操作LocalServices,ActivityManagerService也會(huì)有相關(guān)內(nèi)部類(lèi)的實(shí)例注冊(cè)到LocalServices,這個(gè)實(shí)例是提供system server進(jìn)程內(nèi)部的其他服務(wù)操作AMS的接口。把該服務(wù)在system server內(nèi)部使用到的接口封裝到一個(gè)獨(dú)立的類(lèi)中,把這個(gè)類(lèi)的實(shí)例注冊(cè)到LocalServices。
給其他進(jìn)程調(diào)用的接口封裝到一個(gè)Binder類(lèi)中,然后注冊(cè)到ServiceManager中。

使用

可參考SystemServer中的調(diào)用

代碼路徑

frameworks/base/core/java/android/os/ServiceManager.java
frameworks/base/core/java/android/os/IServiceManager.java
frameworks/base/core/java/android/os/ServiceManagerNative.java
frameworks/base/core/java/android/os/IInterface.java

源碼

IServiceManager, ServiceManagerNative, ServiceManagerProxy要理解AIDL

frameworks/base/core/java/android/os/ServiceManager.java

package android.os;

import android.annotation.UnsupportedAppUsage;
import android.util.ArrayMap;
import android.util.Log;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.os.BinderInternal;
import com.android.internal.util.StatLogger;

import java.util.Map;

/** @hide */
public final class ServiceManager {
    private static final String TAG = "ServiceManager";
    private static final Object sLock = new Object();

    // IserviceManager對(duì)象,用于IPC訪問(wèn),繼承自IInterface
    @UnsupportedAppUsage
    private static IServiceManager sServiceManager;

    /**
     * Cache for the "well known" services, such as WM and AM.
     */
    // 一些關(guān)鍵的服務(wù)信息存儲(chǔ)在這里
    // 由ActivityManagerService通過(guò)ActivityThread調(diào)用ServiceManager.initServiceCache
    // 傳進(jìn)來(lái)的。實(shí)際上ActivityManagerService中在添加的時(shí)候,調(diào)用的事Service的getService方法。
    @UnsupportedAppUsage
    private static Map<String, IBinder> sCache = new ArrayMap<String, IBinder>();

    /**
     * ...
     * 應(yīng)該不是太重要的略過(guò)
     */
    
    // 獲取IServiceManager對(duì)象,用于IPC調(diào)用
    @UnsupportedAppUsage
    private static IServiceManager getIServiceManager() {
        if (sServiceManager != null) {
            return sServiceManager;
        }

        // Find the service manager
        // ServiceManagerNative是binder,實(shí)現(xiàn)了IServiceManager
        sServiceManager = ServiceManagerNative
                .asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
        return sServiceManager;
    }

    /**
     * Returns a reference to a service with the given name.
     *
     * @param name the name of the service to get
     * @return a reference to the service, or <code>null</code> if the service doesn't exist
     */
    // 根據(jù)傳進(jìn)來(lái)的服務(wù)名稱(chēng),獲取對(duì)應(yīng)服務(wù)。
    @UnsupportedAppUsage
    public static IBinder getService(String name) {
        try {
            // cache中有就直接返回(ActivityManagerService中追加的)。
            // 剩下的需要IPC去調(diào)用獲取
            IBinder service = sCache.get(name);
            if (service != null) {
                return service;
            } else {
                return Binder.allowBlocking(rawGetService(name));
            }
        } catch (RemoteException e) {
            Log.e(TAG, "error in getService", e);
        }
        return null;
    }

    /**
     * Returns a reference to a service with the given name, or throws
     * {@link NullPointerException} if none is found.
     *
     * @hide
     */
    // 同樣是根據(jù)名稱(chēng)獲取服務(wù),內(nèi)部就是getService
    public static IBinder getServiceOrThrow(String name) throws ServiceNotFoundException {
        final IBinder binder = getService(name);
        if (binder != null) {
            return binder;
        } else {
            throw new ServiceNotFoundException(name);
        }
    }

    /**
     * Place a new @a service called @a name into the service
     * manager.
     *
     * @param name the name of the new service
     * @param service the service object
     */
    @UnsupportedAppUsage
    public static void addService(String name, IBinder service) {
        addService(name, service, false, IServiceManager.DUMP_FLAG_PRIORITY_DEFAULT);
    }

    /**
     * Place a new @a service called @a name into the service
     * manager.
     *
     * @param name the name of the new service
     * @param service the service object
     * @param allowIsolated set to true to allow isolated sandboxed processes
     * to access this service
     */
    @UnsupportedAppUsage
    public static void addService(String name, IBinder service, boolean allowIsolated) {
        addService(name, service, allowIsolated, IServiceManager.DUMP_FLAG_PRIORITY_DEFAULT);
    }

    /**
     * Place a new @a service called @a name into the service
     * manager.
     *
     * @param name the name of the new service
     * @param service the service object
     * @param allowIsolated set to true to allow isolated sandboxed processes
     * @param dumpPriority supported dump priority levels as a bitmask
     * to access this service
     */
    // IPC調(diào)用,添加服務(wù)
    @UnsupportedAppUsage
    public static void addService(String name, IBinder service, boolean allowIsolated,
            int dumpPriority) {
        try {
            getIServiceManager().addService(name, service, allowIsolated, dumpPriority);
        } catch (RemoteException e) {
            Log.e(TAG, "error in addService", e);
        }
    }

    /**
     * Retrieve an existing service called @a name from the
     * service manager.  Non-blocking.
     */
    // 檢查服務(wù)是否存在
    @UnsupportedAppUsage
    public static IBinder checkService(String name) {
        try {
            IBinder service = sCache.get(name);
            if (service != null) {
                return service;
            } else {
                return Binder.allowBlocking(getIServiceManager().checkService(name));
            }
        } catch (RemoteException e) {
            Log.e(TAG, "error in checkService", e);
            return null;
        }
    }

    /**
     * Return a list of all currently running services.
     * @return an array of all currently running services, or <code>null</code> in
     * case of an exception
     */
    // 查看所有添加的服務(wù)
    @UnsupportedAppUsage
    public static String[] listServices() {
        try {
            return getIServiceManager().listServices(IServiceManager.DUMP_FLAG_PRIORITY_ALL);
        } catch (RemoteException e) {
            Log.e(TAG, "error in listServices", e);
            return null;
        }
    }

    /**
     * This is only intended to be called when the process is first being brought
     * up and bound by the activity manager. There is only one thread in the process
     * at that time, so no locking is done.
     *
     * @param cache the cache of service references
     * @hide
     */
    // 在ActivityThread中由ActivityManagerService中添加一些關(guān)鍵服務(wù)
    public static void initServiceCache(Map<String, IBinder> cache) {
        if (sCache.size() != 0) {
            throw new IllegalStateException("setServiceCache may only be called once");
        }
        sCache.putAll(cache);
    }
    
    
    private static IBinder rawGetService(String name) throws RemoteException {

        // 通過(guò)IServiceManager獲取服務(wù)IBinder對(duì)象
        final IBinder binder = getIServiceManager().getService(name);
        
        return binder;
    }
}
frameworks/base/core/java/android/os/IServiceManager.java

package android.os;

import android.annotation.UnsupportedAppUsage;

/**
 * Basic interface for finding and publishing system services.
 *
 * An implementation of this interface is usually published as the
 * global context object, which can be retrieved via
 * BinderNative.getContextObject().  An easy way to retrieve this
 * is with the static method BnServiceManager.getDefault().
 *
 * @hide
 */
public interface IServiceManager extends IInterface
{
    /**
     * Retrieve an existing service called @a name from the
     * service manager.  Blocks for a few seconds waiting for it to be
     * published if it does not already exist.
     */
    @UnsupportedAppUsage
    IBinder getService(String name) throws RemoteException;

    /**
     * Retrieve an existing service called @a name from the
     * service manager.  Non-blocking.
     */
    @UnsupportedAppUsage
    IBinder checkService(String name) throws RemoteException;

    /**
     * Place a new @a service called @a name into the service
     * manager.
     */
    void addService(String name, IBinder service, boolean allowIsolated, int dumpFlags)
            throws RemoteException;

    /**
     * Return a list of all currently running services.
     */
    String[] listServices(int dumpFlags) throws RemoteException;

    /**
     * Assign a permission controller to the service manager.  After set, this
     * interface is checked before any services are added.
     */
    void setPermissionController(IPermissionController controller)
            throws RemoteException;

    static final String descriptor = "android.os.IServiceManager";

    int GET_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION;
    int CHECK_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+1;
    int ADD_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+2;
    int LIST_SERVICES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+3;
    int CHECK_SERVICES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+4;
    int SET_PERMISSION_CONTROLLER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+5;

    /*
     * Must update values in IServiceManager.h
     */
    /* Allows services to dump sections according to priorities. */
    int DUMP_FLAG_PRIORITY_CRITICAL = 1 << 0;
    int DUMP_FLAG_PRIORITY_HIGH = 1 << 1;
    int DUMP_FLAG_PRIORITY_NORMAL = 1 << 2;
    /**
     * Services are by default registered with a DEFAULT dump priority. DEFAULT priority has the
     * same priority as NORMAL priority but the services are not called with dump priority
     * arguments.
     */
    int DUMP_FLAG_PRIORITY_DEFAULT = 1 << 3;
    int DUMP_FLAG_PRIORITY_ALL = DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_HIGH
            | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PRIORITY_DEFAULT;
    /* Allows services to dump sections in protobuf format. */
    int DUMP_FLAG_PROTO = 1 << 4;

}

frameworks/base/core/java/android/os/ServiceManagerNative.java

package android.os;

import android.annotation.UnsupportedAppUsage;
import java.util.ArrayList;


/**
 * Native implementation of the service manager.  Most clients will only
 * care about getDefault() and possibly asInterface().
 * @hide
 */
public abstract class ServiceManagerNative extends Binder implements IServiceManager
{
    /**
     * Cast a Binder object into a service manager interface, generating
     * a proxy if needed.
     */
    @UnsupportedAppUsage
    static public IServiceManager asInterface(IBinder obj)
    {
        if (obj == null) {
            return null;
        }
        IServiceManager in =
            (IServiceManager)obj.queryLocalInterface(descriptor);
        if (in != null) {
            return in;
        }

        return new ServiceManagerProxy(obj);
    }

    public ServiceManagerNative()
    {
        attachInterface(this, descriptor);
    }
}

class ServiceManagerProxy implements IServiceManager {
    public ServiceManagerProxy(IBinder remote) {
        mRemote = remote;
    }

    public IBinder asBinder() {
        return mRemote;
    }

    @UnsupportedAppUsage
    public IBinder getService(String name) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IServiceManager.descriptor);
        data.writeString(name);
        mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
        IBinder binder = reply.readStrongBinder();
        reply.recycle();
        data.recycle();
        return binder;
    }

    public IBinder checkService(String name) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IServiceManager.descriptor);
        data.writeString(name);
        mRemote.transact(CHECK_SERVICE_TRANSACTION, data, reply, 0);
        IBinder binder = reply.readStrongBinder();
        reply.recycle();
        data.recycle();
        return binder;
    }

    public void addService(String name, IBinder service, boolean allowIsolated, int dumpPriority)
            throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IServiceManager.descriptor);
        data.writeString(name);
        data.writeStrongBinder(service);
        data.writeInt(allowIsolated ? 1 : 0);
        data.writeInt(dumpPriority);
        mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
        reply.recycle();
        data.recycle();
    }

    public String[] listServices(int dumpPriority) throws RemoteException {
        ArrayList<String> services = new ArrayList<String>();
        int n = 0;
        while (true) {
            Parcel data = Parcel.obtain();
            Parcel reply = Parcel.obtain();
            data.writeInterfaceToken(IServiceManager.descriptor);
            data.writeInt(n);
            data.writeInt(dumpPriority);
            n++;
            try {
                boolean res = mRemote.transact(LIST_SERVICES_TRANSACTION, data, reply, 0);
                if (!res) {
                    break;
                }
            } catch (RuntimeException e) {
                // The result code that is returned by the C++ code can
                // cause the call to throw an exception back instead of
                // returning a nice result...  so eat it here and go on.
                break;
            }
            services.add(reply.readString());
            reply.recycle();
            data.recycle();
        }
        String[] array = new String[services.size()];
        services.toArray(array);
        return array;
    }

    public void setPermissionController(IPermissionController controller)
            throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IServiceManager.descriptor);
        data.writeStrongBinder(controller.asBinder());
        mRemote.transact(SET_PERMISSION_CONTROLLER_TRANSACTION, data, reply, 0);
        reply.recycle();
        data.recycle();
    }

    @UnsupportedAppUsage
    private IBinder mRemote;
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容