ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Android之ServiceManager服务

2021-09-11 20:34:03  阅读:176  来源: 互联网

标签:服务 name service addService manager ServiceManager Android


一、ServiceManager的作用是什么

  ServiceManager从字面意思是管理服务的。

  ServiceManager是用于查询服务和获取服务的。

二、ServiceManager启动过程

  源码:frameworks/native/cmds/servicemanager

  ServiceManager是系统服务,与zygote、surfaceflinger一样,由系统进程init启动,init进程通过init.rc配置文件读取需要启动的配置,ServiceManager启动命名:

  源码:frameworks/native/cmds/servicemanager/servicemanager.rc

service servicemanager /system/bin/servicemanager
    class core animation
    user system
    group system readproc
    critical
    onrestart restart apexd
    onrestart restart audioserver
    onrestart restart gatekeeperd
    onrestart class_restart main
    onrestart class_restart hal
    onrestart class_restart early_hal
    writepid /dev/cpuset/system-background/tasks
    shutdown critical

  ServiceManager进程启动后,执行ServiceManager的main.cpp里main()函数:

int main(int argc, char** argv) {
    if (argc > 2) {
        LOG(FATAL) << "usage: " << argv[0] << " [binder driver]";
    }

    const char* driver = argc == 2 ? argv[1] : "/dev/binder";

    sp<ProcessState> ps = ProcessState::initWithDriver(driver);
    ps->setThreadPoolMaxThreadCount(0);
    ps->setCallRestriction(ProcessState::CallRestriction::FATAL_IF_NOT_ONEWAY);

    sp<ServiceManager> manager = sp<ServiceManager>::make(std::make_unique<Access>());
    if (!manager->addService("manager", manager, false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()) {
        LOG(ERROR) << "Could not self register servicemanager";
    }

    IPCThreadState::self()->setTheContextObject(manager);
    ps->becomeContextManager();

    sp<Looper> looper = Looper::prepare(false /*allowNonCallbacks*/);

    BinderCallback::setupTo(looper);
    ClientCallbackCallback::setupTo(looper, manager);

    while(true) {
        looper->pollAll(-1);
    }

    // should not be reached
    return EXIT_FAILURE;
}

  通过解读上面代码ServiceManager启动流程:

  1. 启动Binder线程池。

sp<ProcessState> ps = ProcessState::initWithDriver(driver);

  2. 启动ServiceManager服务并获取ServiceManager服务Binder代理对象。

sp<ServiceManager> manager = sp<ServiceManager>::make(std::make_unique<Access>());

  3. 将ServiceManager服务的Binder代理对象注册到ServiceManager服务中。

if (!manager->addService("manager", manager, false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()) {
    LOG(ERROR) << "Could not self register servicemanager";
}

  4. 将ServiceMager服务自己注册为上下文管理者。

IPCThreadState::self()->setTheContextObject(manager);
ps->becomeContextManager();

  5. 启动Binder线程池Looper并接收处理消息。

sp<Looper> looper = Looper::prepare(false /*allowNonCallbacks*/);
BinderCallback::setupTo(looper);
ClientCallbackCallback::setupTo(looper, manager);
while(true) {
    looper->pollAll(-1);
}

 三、怎么获取ServiceManager

  源码:frameworks/base/core/java/android/os/ServiceManager.java

  1. 其它服务如何获取ServiceManager服务

  下面以渲染服务surfaceflinger服务为例,在surfaceflinger服务是怎么获取到ServiceManager服务的Binder代理对象。

  源码:frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp

int main(int, char**) {
    ……

    // publish surface flinger
    sp<IServiceManager> sm(defaultServiceManager());
   
    ……
}

  通过函数defaultServiceManager()函数获取ServiceManager服务的Binder代理对象。

  IServiceManager.h在binder源码里。

四、ServiceManager如何添加服务

  下面以渲染服务surfaceflinger服务为例:

sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false,
                   IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO);

  通过获取到的ServiceManager的Binder代理对象,调用addService(...)函数注册服务。

/**
 * 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
 * @hide
 */
@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
 * @hide
 */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
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);
    }
}

  在

五、ServiceManager如何获取服务

   通过ServiceManager的Binder代理对象,调用getService(String name)获取指定名称服务。

/**
    * 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
    * @hide
    */
@UnsupportedAppUsage
public static IBinder getService(String name) {
    try {
        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;
}

  在通过addService()函数注册服务时,ServiceManager会将服务存储在ServiceManager.sCache数据结构中,sCache是Map。key是服务名称。

六、Java层,应用启动时,服务是如何注册到应用的ServiceManager里

/**
 * 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
 */
public static void initServiceCache(Map<String, IBinder> cache) {
    if (sCache.size() != 0) {
        throw new IllegalStateException("setServiceCache may only be called once");
    }
    sCache.putAll(cache);
}
  这个方法只会被调用一个,在服务

  在应用进程启动后,通知AMS,AMS再通知应用创建Application时,会将系统中注册的Services一起发送给就算的ServiceManager,存储在Java层的ServiceManager.sCache数据结构中。sCache是一个Map数据结构。

  

private class ApplicationThread extends IApplicationThread.Stub {
    ……

    public final void bindApplication(String processName, ApplicationInfo appInfo,
            ProviderInfoList providerList, ComponentName instrumentationName,
            ProfilerInfo profilerInfo, Bundle instrumentationArgs,
            IInstrumentationWatcher instrumentationWatcher,
            IUiAutomationConnection instrumentationUiConnection, int debugMode,
            boolean enableBinderTracking, boolean trackAllocation,
            boolean isRestrictedBackupMode, boolean persistent, Configuration config,
            CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
            String buildSerial, AutofillOptions autofillOptions,
            ContentCaptureOptions contentCaptureOptions, long[] disabledCompatChanges) {
        if (services != null) {
            if (false) {
                // Test code to make sure the app could see the passed-in services.
                for (Object oname : services.keySet()) {
                    if (services.get(oname) == null) {
                        continue; // AM just passed in a null service.
                    }
                    String name = (String) oname;

                    // See b/79378449 about the following exemption.
                    switch (name) {
                        case "package":
                        case Context.WINDOW_SERVICE:
                            continue;
                    }

                    if (ServiceManager.getService(name) == null) {
                        Log.wtf(TAG, "Service " + name + " should be accessible by this app");
                    }
                }
            }

            // Setup the service cache in the ServiceManager
            ServiceManager.initServiceCache(services);
        }
    }

    ……
}

  ServiceManager.initServiceCache()函数在应用启动调用,并且仅调用一次。就是在AMS通知应用创建Application对象时。

标签:服务,name,service,addService,manager,ServiceManager,Android
来源: https://www.cnblogs.com/naray/p/15227430.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有