1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.telecom; 18 19 import android.app.role.RoleManager; 20 import android.content.BroadcastReceiver; 21 import android.content.ComponentName; 22 import android.content.Context; 23 import android.content.Intent; 24 import android.content.IntentFilter; 25 import android.content.ServiceConnection; 26 import android.os.IBinder; 27 import android.os.RemoteException; 28 import android.os.ServiceManager; 29 import android.os.UserHandle; 30 import android.telecom.DefaultDialerManager; 31 import android.telecom.PhoneAccountHandle; 32 import android.telecom.TelecomManager; 33 import android.telephony.CarrierConfigManager; 34 import android.util.IntArray; 35 import android.util.Slog; 36 37 import com.android.internal.annotations.GuardedBy; 38 import com.android.internal.telephony.SmsApplication; 39 import com.android.server.LocalServices; 40 import com.android.server.SystemService; 41 import com.android.server.pm.UserManagerService; 42 import com.android.server.pm.permission.PermissionManagerServiceInternal; 43 44 /** 45 * Starts the telecom component by binding to its ITelecomService implementation. Telecom is setup 46 * to run in the system-server process so once it is loaded into memory it will stay running. 47 * @hide 48 */ 49 public class TelecomLoaderService extends SystemService { 50 private static final String TAG = "TelecomLoaderService"; 51 52 private class TelecomServiceConnection implements ServiceConnection { 53 @Override onServiceConnected(ComponentName name, IBinder service)54 public void onServiceConnected(ComponentName name, IBinder service) { 55 // Normally, we would listen for death here, but since telecom runs in the same process 56 // as this loader (process="system") thats redundant here. 57 try { 58 service.linkToDeath(new IBinder.DeathRecipient() { 59 @Override 60 public void binderDied() { 61 connectToTelecom(); 62 } 63 }, 0); 64 SmsApplication.getDefaultMmsApplication(mContext, false); 65 ServiceManager.addService(Context.TELECOM_SERVICE, service); 66 67 synchronized (mLock) { 68 final PermissionManagerServiceInternal permissionManager = 69 LocalServices.getService(PermissionManagerServiceInternal.class); 70 if (mDefaultSimCallManagerRequests != null) { 71 if (mDefaultSimCallManagerRequests != null) { 72 TelecomManager telecomManager = 73 (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE); 74 PhoneAccountHandle phoneAccount = telecomManager.getSimCallManager(); 75 if (phoneAccount != null) { 76 final int requestCount = mDefaultSimCallManagerRequests.size(); 77 final String packageName = 78 phoneAccount.getComponentName().getPackageName(); 79 for (int i = requestCount - 1; i >= 0; i--) { 80 final int userId = mDefaultSimCallManagerRequests.get(i); 81 mDefaultSimCallManagerRequests.remove(i); 82 permissionManager 83 .grantDefaultPermissionsToDefaultSimCallManager( 84 packageName, userId); 85 } 86 } 87 } 88 } 89 } 90 } catch (RemoteException e) { 91 Slog.w(TAG, "Failed linking to death."); 92 } 93 } 94 95 @Override onServiceDisconnected(ComponentName name)96 public void onServiceDisconnected(ComponentName name) { 97 connectToTelecom(); 98 } 99 } 100 101 private static final ComponentName SERVICE_COMPONENT = new ComponentName( 102 "com.android.server.telecom", 103 "com.android.server.telecom.components.TelecomService"); 104 105 private static final String SERVICE_ACTION = "com.android.ITelecomService"; 106 107 private final Object mLock = new Object(); 108 109 @GuardedBy("mLock") 110 private IntArray mDefaultSimCallManagerRequests; 111 112 private final Context mContext; 113 114 @GuardedBy("mLock") 115 private TelecomServiceConnection mServiceConnection; 116 TelecomLoaderService(Context context)117 public TelecomLoaderService(Context context) { 118 super(context); 119 mContext = context; 120 registerDefaultAppProviders(); 121 } 122 123 @Override onStart()124 public void onStart() { 125 } 126 127 @Override onBootPhase(int phase)128 public void onBootPhase(int phase) { 129 if (phase == PHASE_ACTIVITY_MANAGER_READY) { 130 registerDefaultAppNotifier(); 131 registerCarrierConfigChangedReceiver(); 132 connectToTelecom(); 133 } 134 } 135 connectToTelecom()136 private void connectToTelecom() { 137 synchronized (mLock) { 138 if (mServiceConnection != null) { 139 // TODO: Is unbinding worth doing or wait for system to rebind? 140 mContext.unbindService(mServiceConnection); 141 mServiceConnection = null; 142 } 143 144 TelecomServiceConnection serviceConnection = new TelecomServiceConnection(); 145 Intent intent = new Intent(SERVICE_ACTION); 146 intent.setComponent(SERVICE_COMPONENT); 147 int flags = Context.BIND_IMPORTANT | Context.BIND_FOREGROUND_SERVICE 148 | Context.BIND_AUTO_CREATE; 149 150 // Bind to Telecom and register the service 151 if (mContext.bindServiceAsUser(intent, serviceConnection, flags, UserHandle.SYSTEM)) { 152 mServiceConnection = serviceConnection; 153 } 154 } 155 } 156 157 registerDefaultAppProviders()158 private void registerDefaultAppProviders() { 159 final PermissionManagerServiceInternal permissionManager = 160 LocalServices.getService(PermissionManagerServiceInternal.class); 161 162 // Set a callback for the permission grant policy to query the default sms app. 163 permissionManager.setSmsAppPackagesProvider(userId -> { 164 synchronized (mLock) { 165 if (mServiceConnection == null) { 166 return null; 167 } 168 } 169 ComponentName smsComponent = SmsApplication.getDefaultSmsApplication( 170 mContext, true); 171 if (smsComponent != null) { 172 return new String[]{smsComponent.getPackageName()}; 173 } 174 return null; 175 }); 176 177 // Set a callback for the permission grant policy to query the default dialer app. 178 permissionManager.setDialerAppPackagesProvider(userId -> { 179 synchronized (mLock) { 180 if (mServiceConnection == null) { 181 return null; 182 } 183 } 184 String packageName = DefaultDialerManager.getDefaultDialerApplication(mContext); 185 if (packageName != null) { 186 return new String[]{packageName}; 187 } 188 return null; 189 }); 190 191 // Set a callback for the permission grant policy to query the default sim call manager. 192 permissionManager.setSimCallManagerPackagesProvider(userId -> { 193 synchronized (mLock) { 194 if (mServiceConnection == null) { 195 if (mDefaultSimCallManagerRequests == null) { 196 mDefaultSimCallManagerRequests = new IntArray(); 197 } 198 mDefaultSimCallManagerRequests.add(userId); 199 return null; 200 } 201 } 202 TelecomManager telecomManager = 203 (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE); 204 PhoneAccountHandle phoneAccount = telecomManager.getSimCallManager(userId); 205 if (phoneAccount != null) { 206 return new String[]{phoneAccount.getComponentName().getPackageName()}; 207 } 208 return null; 209 }); 210 } 211 registerDefaultAppNotifier()212 private void registerDefaultAppNotifier() { 213 // Notify the package manager on default app changes 214 final RoleManager roleManager = mContext.getSystemService(RoleManager.class); 215 roleManager.addOnRoleHoldersChangedListenerAsUser(mContext.getMainExecutor(), 216 (roleName, user) -> updateSimCallManagerPermissions(user.getIdentifier()), 217 UserHandle.ALL); 218 } 219 220 registerCarrierConfigChangedReceiver()221 private void registerCarrierConfigChangedReceiver() { 222 BroadcastReceiver receiver = new BroadcastReceiver() { 223 @Override 224 public void onReceive(Context context, Intent intent) { 225 if (intent.getAction().equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) { 226 for (int userId : UserManagerService.getInstance().getUserIds()) { 227 updateSimCallManagerPermissions(userId); 228 } 229 } 230 } 231 }; 232 233 mContext.registerReceiverAsUser(receiver, UserHandle.ALL, 234 new IntentFilter(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED), null, null); 235 } 236 updateSimCallManagerPermissions(int userId)237 private void updateSimCallManagerPermissions(int userId) { 238 final PermissionManagerServiceInternal permissionManager = 239 LocalServices.getService(PermissionManagerServiceInternal.class); 240 TelecomManager telecomManager = 241 (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE); 242 PhoneAccountHandle phoneAccount = telecomManager.getSimCallManager(userId); 243 if (phoneAccount != null) { 244 Slog.i(TAG, "updating sim call manager permissions for userId:" + userId); 245 String packageName = phoneAccount.getComponentName().getPackageName(); 246 permissionManager.grantDefaultPermissionsToDefaultSimCallManager(packageName, userId); 247 } 248 } 249 } 250