Android System Server大纲之TelecomLoaderService
来源:互联网 发布:java恶魔城 编辑:程序博客网 时间:2024/05/22 04:34
Android System Server大纲之TelecomLoaderService
Telecom:通话逻辑控制
前言
在Android 5.0版本中,Android大幅地修改了Call(通话)模块,把Call的逻辑处理从Telephony抽出来,独立成Telecom模块。从此Call的流程中就多了Telecom,分工越来越明细,耦合度进一步降低,给维护带来了良好的改进。但是逻辑上也稍微变得复杂了那么一些。从Android 5.0开始到现在的最新的Android 7.0,Call的架构如下:
从Android 4.4开始,Android出于对Android安全方面的考虑,创立了默认APP的机制,当然这个默认APP的机制值限制于浏览器、通话、短彩信三个模块,只有用户设置了对应模块功能的默认APP,这个APP才能完成这些模块的功能,读者可以参考文章《Android default phone mechanism 》。
TelecomLoaderService在开机时会加载Call架构中Telecom的模块,把Telecom模块的服务添加在系统服务当中。对默认短信、通话模块的默认APP进行相应的授权,当然,这个是Android 6.0运行时权限处理时才需要添加的。运行时权限读者可以参考文章《Android M App Permissions 》。
TelecomLoaderService的启动
参考文章《Android系统之System Server大纲 》可知,启动过程如下:
mSystemServiceManager.startService(TelecomLoaderService.class);
这条语句定义在文件frameworks/base/services/java/com/android/server/SystemServer.java中。
参考文章《Android系统之System Server大纲 》中系统服务的启动方式,TelecomLoaderService启动之后会回调方法onStart(),以及system_process启动完毕后会回调所有SystemService的onBootPhase()方法。
@Overridepublic void onStart() {}@Overridepublic void onBootPhase(int phase) { if (phase == PHASE_ACTIVITY_MANAGER_READY) { registerDefaultAppNotifier(); registerCarrierConfigChangedReceiver(); connectToTelecom(); }}
这些方法定义在文件frameworks/base/services/core/java/com/android/server/telecom/TelecomLoaderService.java中。
上面的代码中,onStart()方法什么事情也没有做,onBootPhase()中分别调用了registerDefaultAppNotifier()、registerCarrierConfigChangedReceiver()、connectToTelecom(),前两个方法会监听一些数据的变化,如默认短彩信APP的变化等,本文不再往下阐述它们。最后一个方法connectToTelecom()就是便是连接到Telecom。如下:
private static final String SERVICE_ACTION = "com.android.ITelecomService";private static final ComponentName SERVICE_COMPONENT = new ComponentName( "com.android.server.telecom", "com.android.server.telecom.components.TelecomService");private void connectToTelecom() { synchronized (mLock) { TelecomServiceConnection serviceConnection = new TelecomServiceConnection(); Intent intent = new Intent(SERVICE_ACTION); intent.setComponent(SERVICE_COMPONENT); int flags = Context.BIND_IMPORTANT | Context.BIND_FOREGROUND_SERVICE | Context.BIND_AUTO_CREATE; // Bind to Telecom and register the service if (mContext.bindServiceAsUser(intent, serviceConnection, flags, UserHandle.OWNER)) { mServiceConnection = serviceConnection; } }}
这个方法定义在文件frameworks/base/services/core/java/com/android/server/telecom/TelecomLoaderService.java中。
实例化一个Intent,action是SERVICE_ACTION,以及指定Component为SERVICE_COMPONENT,随后调用bindServiceAsUser绑定远程服务,在Android四大组件的Service架构中,启动/绑定一个Service,需要传递一个ServiceConnection的子类,上面的代码传的是TelecomServiceConnection。被绑定的这个服务定义在文件packages/services/Telecomm/src/com/android/server/telecom/components/TelecomService.java中。当成功绑定应用com.android.server.telecom/.components.TelecomService中的Service后,便会回调TelecomServiceConnection中的onServiceConnected()方法:
public void onServiceConnected(ComponentName name, IBinder service) { // Normally, we would listen for death here, but since telecom runs in the same process // as this loader (process="system") thats redundant here. try { SmsApplication.getDefaultMmsApplication(mContext, false); ServiceManager.addService(Context.TELECOM_SERVICE, service); synchronized (mLock) { ...... if (smsComponent != null) { ...... packageManagerInternal.grantDefaultPermissionsToDefaultSmsApp( smsComponent.getPackageName(), userid); } } } if (mDefaultDialerAppRequests != null) { ...... packageManagerInternal.grantDefaultPermissionsToDefaultDialerApp( packageName, userId); } } } if (mDefaultSimCallManagerRequests != null) { ...... packageManagerInternal .grantDefaultPermissionsToDefaultSimCallManager( packageName, userId); ......}
这个方法定义在文件frameworks/base/services/core/java/com/android/server/telecom/TelecomLoaderService.java中。
为了看起来简洁,这里省略了很多代码,但是不会影响对功能的理解。在onServiceConnected()方法中,主要完成4个事情。
第一:
把Context.TELECOM_SERVICE添加到系统的服务中,这里的IBinder是绑定service返回的远程句柄,这个句柄的实现定义在文件packages/services/Telecomm/src/com/android/server/telecom/TelecomServiceImpl.java中,在以后的文章中再阐述这个服务。
第二:
给默认的短彩信(SMS)应用授予运行时权限。
第三:
给默认的通话(Dialer)应用授予运行时权限。
第四:
给默认的SimCallManager应用授予运行时权限。
由于授权的过程是一样的,本文就以通话的授权为例,阐述这个过程:
public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) { synchronized (mPackages) { mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr( packageName, userId); }}
这个方法定义在文件frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java中。
这里直接调用了grantDefaultPermissionsToDefaultDialerAppLPr()方法,如下:
public void grantDefaultPermissionsToDefaultDialerAppLPr(String packageName, int userId) { PackageParser.Package dialerPackage = getPackageLPr(packageName); if (dialerPackage != null && doesPackageSupportRuntimePermissions(dialerPackage)) { grantRuntimePermissionsLPw(dialerPackage, PHONE_PERMISSIONS, false, true, userId); grantRuntimePermissionsLPw(dialerPackage, CONTACTS_PERMISSIONS, false, true, userId); grantRuntimePermissionsLPw(dialerPackage, SMS_PERMISSIONS, false, true, userId); grantRuntimePermissionsLPw(dialerPackage, MICROPHONE_PERMISSIONS, false, true, userId); }}
这个方法定义在文件frameworks/base/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java中。
通过getPackageLPr()把Dialer抽象成PackageParser.Package对象,调用grantRuntimePermissionsLPw()分别给Dialer应用授予PHONE_PERMISSIONS、CONTACTS_PERMISSIONS、SMS_PERMISSIONS、MICROPHONE_PERMISSIONS权限,这几个权限的明细如下:
private static final Set<String> PHONE_PERMISSIONS = new ArraySet<>();static { PHONE_PERMISSIONS.add(Manifest.permission.READ_PHONE_STATE); PHONE_PERMISSIONS.add(Manifest.permission.CALL_PHONE); PHONE_PERMISSIONS.add(Manifest.permission.READ_CALL_LOG); PHONE_PERMISSIONS.add(Manifest.permission.WRITE_CALL_LOG); PHONE_PERMISSIONS.add(Manifest.permission.ADD_VOICEMAIL); PHONE_PERMISSIONS.add(Manifest.permission.USE_SIP); PHONE_PERMISSIONS.add(Manifest.permission.PROCESS_OUTGOING_CALLS);}
private static final Set<String> CONTACTS_PERMISSIONS = new ArraySet<>();static { CONTACTS_PERMISSIONS.add(Manifest.permission.READ_CONTACTS); CONTACTS_PERMISSIONS.add(Manifest.permission.WRITE_CONTACTS); CONTACTS_PERMISSIONS.add(Manifest.permission.GET_ACCOUNTS);}
private static final Set<String> SMS_PERMISSIONS = new ArraySet<>();static { SMS_PERMISSIONS.add(Manifest.permission.SEND_SMS); SMS_PERMISSIONS.add(Manifest.permission.RECEIVE_SMS); SMS_PERMISSIONS.add(Manifest.permission.READ_SMS); SMS_PERMISSIONS.add(Manifest.permission.RECEIVE_WAP_PUSH); SMS_PERMISSIONS.add(Manifest.permission.RECEIVE_MMS); SMS_PERMISSIONS.add(Manifest.permission.READ_CELL_BROADCASTS);}
private static final Set<String> MICROPHONE_PERMISSIONS = new ArraySet<>();static { MICROPHONE_PERMISSIONS.add(Manifest.permission.RECORD_AUDIO);}
所以,在手机启动后,会给默认的通话应用Dialer授予以上运行时的危险权限。
到这里,TelecomLoaderService的工作基本上就完成了。TelecomLoaderService所负责的事情并不多,由于Android系统用于很多设备,在某些设备上,会没有Telecom模块,所以,独立一个TelecomLoaderService来加载Telecom模块,也是非常美好的一个业务分配。
总结
TelecomLoaderService的名字非常完美的总结了TelecomLoaderService所需要完成的业务,虽然TelecomLoaderService的业务并不多,也不是很难理解,但是涉及到其它模块却不是很少,有TelecomService、默认应用、运行时权限等等。最后附一张时序图:
- Android System Server大纲之TelecomLoaderService
- Android系统之System Server大纲
- Android System Server大纲之VibratorService
- Android System Server大纲之ClipboardService
- Android System Server大纲之TelephonyRegistry
- Android System Server大纲之LightsService
- Android System Server大纲之StatusBarManagerService
- Android System Server大纲之ContentService和ContentProvider原理剖析
- Android system server之WatchDog看门狗分析
- Android system server之PackageManagerService详细分析
- Android system server
- Android的System Server
- android System Server 分析
- Android的System Server
- Android工程师之Android面试大纲
- Android工程师之Android面试大纲
- Android工程师之Android面试大纲
- Android工程师之Android面试大纲
- swift闭包的使用
- 欢迎使用CSDN-markdown编辑器
- C++ 11 中的右值引用
- java企业网站源码,模版,有前后台,springmvcSSM,freemaker
- [mac]CleanMyMac 3删除后,通知中心还有残留
- Android System Server大纲之TelecomLoaderService
- (ELK/EFK)之Fluentd日志过滤解析与客户端IP地址地理位置处理
- JavaScript入门基础学习
- Android Linker(一) 从loadLibrary开始-----上层调用流程
- 【Android】自定义TextView内容过长时不省略最后一个字符
- 多线程注意事项
- activiti工作流的web流程设计器整合视频教程 SSM和独立部署
- Psoc Creator 入门——接近感应组件的使用
- 【小工具】通过命令行获得代码行数