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.DefaultPermissionGrantPolicy; 43 import com.android.server.pm.permission.PermissionManagerServiceInternal; 44 45 /** 46 * Starts the telecom component by binding to its ITelecomService implementation. Telecom is setup 47 * to run in the system-server process so once it is loaded into memory it will stay running. 48 * @hide 49 */ 50 public class TelecomLoaderService extends SystemService { 51 private static final String TAG = "TelecomLoaderService"; 52 53 private class TelecomServiceConnection implements ServiceConnection { 54 @Override onServiceConnected(ComponentName name, IBinder service)55 public void onServiceConnected(ComponentName name, IBinder service) { 56 // Normally, we would listen for death here, but since telecom runs in the same process 57 // as this loader (process="system") thats redundant here. 58 try { 59 service.linkToDeath(new IBinder.DeathRecipient() { 60 @Override 61 public void binderDied() { 62 connectToTelecom(); 63 } 64 }, 0); 65 SmsApplication.getDefaultMmsApplication(mContext, false); 66 ServiceManager.addService(Context.TELECOM_SERVICE, service); 67 68 synchronized (mLock) { 69 if (mDefaultSimCallManagerRequests != null) { 70 final DefaultPermissionGrantPolicy permissionPolicy = 71 getDefaultPermissionGrantPolicy(); 72 if (mDefaultSimCallManagerRequests != null) { 73 TelecomManager telecomManager = 74 (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE); 75 PhoneAccountHandle phoneAccount = telecomManager.getSimCallManager(); 76 if (phoneAccount != null) { 77 final int requestCount = mDefaultSimCallManagerRequests.size(); 78 final String packageName = 79 phoneAccount.getComponentName().getPackageName(); 80 for (int i = requestCount - 1; i >= 0; i--) { 81 final int userId = mDefaultSimCallManagerRequests.get(i); 82 mDefaultSimCallManagerRequests.remove(i); 83 permissionPolicy 84 .grantDefaultPermissionsToDefaultSimCallManager( 85 packageName, userId); 86 } 87 } 88 } 89 } 90 } 91 } catch (RemoteException e) { 92 Slog.w(TAG, "Failed linking to death."); 93 } 94 } 95 96 @Override onServiceDisconnected(ComponentName name)97 public void onServiceDisconnected(ComponentName name) { 98 connectToTelecom(); 99 } 100 } 101 getDefaultPermissionGrantPolicy()102 private DefaultPermissionGrantPolicy getDefaultPermissionGrantPolicy() { 103 return LocalServices.getService(PermissionManagerServiceInternal.class) 104 .getDefaultPermissionGrantPolicy(); 105 } 106 107 private static final ComponentName SERVICE_COMPONENT = new ComponentName( 108 "com.android.server.telecom", 109 "com.android.server.telecom.components.TelecomService"); 110 111 private static final String SERVICE_ACTION = "com.android.ITelecomService"; 112 113 private final Object mLock = new Object(); 114 115 @GuardedBy("mLock") 116 private IntArray mDefaultSimCallManagerRequests; 117 118 private final Context mContext; 119 120 @GuardedBy("mLock") 121 private TelecomServiceConnection mServiceConnection; 122 TelecomLoaderService(Context context)123 public TelecomLoaderService(Context context) { 124 super(context); 125 mContext = context; 126 registerDefaultAppProviders(); 127 } 128 129 @Override onStart()130 public void onStart() { 131 } 132 133 @Override onBootPhase(int phase)134 public void onBootPhase(int phase) { 135 if (phase == PHASE_ACTIVITY_MANAGER_READY) { 136 registerDefaultAppNotifier(); 137 registerCarrierConfigChangedReceiver(); 138 connectToTelecom(); 139 } 140 } 141 connectToTelecom()142 private void connectToTelecom() { 143 synchronized (mLock) { 144 if (mServiceConnection != null) { 145 // TODO: Is unbinding worth doing or wait for system to rebind? 146 mContext.unbindService(mServiceConnection); 147 mServiceConnection = null; 148 } 149 150 TelecomServiceConnection serviceConnection = new TelecomServiceConnection(); 151 Intent intent = new Intent(SERVICE_ACTION); 152 intent.setComponent(SERVICE_COMPONENT); 153 int flags = Context.BIND_IMPORTANT | Context.BIND_FOREGROUND_SERVICE 154 | Context.BIND_AUTO_CREATE; 155 156 // Bind to Telecom and register the service 157 if (mContext.bindServiceAsUser(intent, serviceConnection, flags, UserHandle.SYSTEM)) { 158 mServiceConnection = serviceConnection; 159 } 160 } 161 } 162 163 registerDefaultAppProviders()164 private void registerDefaultAppProviders() { 165 final DefaultPermissionGrantPolicy permissionPolicy = getDefaultPermissionGrantPolicy(); 166 167 // Set a callback for the permission grant policy to query the default sms app. 168 permissionPolicy.setSmsAppPackagesProvider(userId -> { 169 synchronized (mLock) { 170 if (mServiceConnection == null) { 171 return null; 172 } 173 } 174 ComponentName smsComponent = SmsApplication.getDefaultSmsApplication( 175 mContext, true); 176 if (smsComponent != null) { 177 return new String[]{smsComponent.getPackageName()}; 178 } 179 return null; 180 }); 181 182 // Set a callback for the permission grant policy to query the default dialer app. 183 permissionPolicy.setDialerAppPackagesProvider(userId -> { 184 synchronized (mLock) { 185 if (mServiceConnection == null) { 186 return null; 187 } 188 } 189 String packageName = DefaultDialerManager.getDefaultDialerApplication(mContext); 190 if (packageName != null) { 191 return new String[]{packageName}; 192 } 193 return null; 194 }); 195 196 // Set a callback for the permission grant policy to query the default sim call manager. 197 permissionPolicy.setSimCallManagerPackagesProvider(userId -> { 198 synchronized (mLock) { 199 if (mServiceConnection == null) { 200 if (mDefaultSimCallManagerRequests == null) { 201 mDefaultSimCallManagerRequests = new IntArray(); 202 } 203 mDefaultSimCallManagerRequests.add(userId); 204 return null; 205 } 206 } 207 TelecomManager telecomManager = 208 (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE); 209 PhoneAccountHandle phoneAccount = telecomManager.getSimCallManager(userId); 210 if (phoneAccount != null) { 211 return new String[]{phoneAccount.getComponentName().getPackageName()}; 212 } 213 return null; 214 }); 215 } 216 registerDefaultAppNotifier()217 private void registerDefaultAppNotifier() { 218 final DefaultPermissionGrantPolicy permissionPolicy = getDefaultPermissionGrantPolicy(); 219 // Notify the package manager on default app changes 220 final RoleManager roleManager = mContext.getSystemService(RoleManager.class); 221 roleManager.addOnRoleHoldersChangedListenerAsUser(mContext.getMainExecutor(), 222 (roleName, user) -> updateSimCallManagerPermissions(permissionPolicy, 223 user.getIdentifier()), UserHandle.ALL); 224 } 225 226 registerCarrierConfigChangedReceiver()227 private void registerCarrierConfigChangedReceiver() { 228 BroadcastReceiver receiver = new BroadcastReceiver() { 229 @Override 230 public void onReceive(Context context, Intent intent) { 231 if (intent.getAction().equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) { 232 for (int userId : UserManagerService.getInstance().getUserIds()) { 233 updateSimCallManagerPermissions(getDefaultPermissionGrantPolicy(), userId); 234 } 235 } 236 } 237 }; 238 239 mContext.registerReceiverAsUser(receiver, UserHandle.ALL, 240 new IntentFilter(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED), null, null); 241 } 242 updateSimCallManagerPermissions( DefaultPermissionGrantPolicy permissionGrantPolicy, int userId)243 private void updateSimCallManagerPermissions( 244 DefaultPermissionGrantPolicy permissionGrantPolicy, int userId) { 245 TelecomManager telecomManager = 246 (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE); 247 PhoneAccountHandle phoneAccount = telecomManager.getSimCallManager(userId); 248 if (phoneAccount != null) { 249 Slog.i(TAG, "updating sim call manager permissions for userId:" + userId); 250 String packageName = phoneAccount.getComponentName().getPackageName(); 251 permissionGrantPolicy.grantDefaultPermissionsToDefaultSimCallManager( 252 packageName, userId); 253 } 254 } 255 } 256