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.content.BroadcastReceiver; 20 import android.content.ComponentName; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.content.IntentFilter; 24 import android.content.ServiceConnection; 25 import android.content.pm.PackageManagerInternal; 26 import android.database.ContentObserver; 27 import android.net.Uri; 28 import android.os.Handler; 29 import android.os.IBinder; 30 import android.os.Looper; 31 import android.os.RemoteException; 32 import android.os.ServiceManager; 33 import android.os.UserHandle; 34 import android.provider.Settings; 35 import android.telecom.DefaultDialerManager; 36 import android.telecom.PhoneAccountHandle; 37 import android.telecom.TelecomManager; 38 import android.telephony.CarrierConfigManager; 39 import android.util.IntArray; 40 import android.util.Slog; 41 42 import android.util.SparseBooleanArray; 43 import com.android.internal.annotations.GuardedBy; 44 import com.android.internal.telephony.SmsApplication; 45 import com.android.server.LocalServices; 46 import com.android.server.SystemService; 47 import com.android.server.pm.UserManagerService; 48 49 /** 50 * Starts the telecom component by binding to its ITelecomService implementation. Telecom is setup 51 * to run in the system-server process so once it is loaded into memory it will stay running. 52 * @hide 53 */ 54 public class TelecomLoaderService extends SystemService { 55 private static final String TAG = "TelecomLoaderService"; 56 57 private class TelecomServiceConnection implements ServiceConnection { 58 @Override 59 public void onServiceConnected(ComponentName name, IBinder service) { 60 // Normally, we would listen for death here, but since telecom runs in the same process 61 // as this loader (process="system") thats redundant here. 62 try { 63 service.linkToDeath(new IBinder.DeathRecipient() { 64 @Override 65 public void binderDied() { 66 connectToTelecom(); 67 } 68 }, 0); 69 SmsApplication.getDefaultMmsApplication(mContext, false); 70 ServiceManager.addService(Context.TELECOM_SERVICE, service); 71 72 synchronized (mLock) { 73 if (mDefaultSmsAppRequests != null || mDefaultDialerAppRequests != null 74 || mDefaultSimCallManagerRequests != null) { 75 final PackageManagerInternal packageManagerInternal = LocalServices 76 .getService(PackageManagerInternal.class); 77 78 if (mDefaultSmsAppRequests != null) { 79 ComponentName smsComponent = SmsApplication.getDefaultSmsApplication( 80 mContext, true); 81 if (smsComponent != null) { 82 final int requestCount = mDefaultSmsAppRequests.size(); 83 for (int i = requestCount - 1; i >= 0; i--) { 84 final int userid = mDefaultSmsAppRequests.get(i); 85 mDefaultSmsAppRequests.remove(i); 86 packageManagerInternal.grantDefaultPermissionsToDefaultSmsApp( 87 smsComponent.getPackageName(), userid); 88 } 89 } 90 } 91 92 if (mDefaultDialerAppRequests != null) { 93 String packageName = DefaultDialerManager.getDefaultDialerApplication( 94 mContext); 95 if (packageName != null) { 96 final int requestCount = mDefaultDialerAppRequests.size(); 97 for (int i = requestCount - 1; i >= 0; i--) { 98 final int userId = mDefaultDialerAppRequests.get(i); 99 mDefaultDialerAppRequests.remove(i); 100 packageManagerInternal.grantDefaultPermissionsToDefaultDialerApp( 101 packageName, userId); 102 } 103 } 104 } 105 if (mDefaultSimCallManagerRequests != null) { 106 TelecomManager telecomManager = 107 (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE); 108 PhoneAccountHandle phoneAccount = telecomManager.getSimCallManager(); 109 if (phoneAccount != null) { 110 final int requestCount = mDefaultSimCallManagerRequests.size(); 111 final String packageName = 112 phoneAccount.getComponentName().getPackageName(); 113 for (int i = requestCount - 1; i >= 0; i--) { 114 final int userId = mDefaultSimCallManagerRequests.get(i); 115 mDefaultSimCallManagerRequests.remove(i); 116 packageManagerInternal 117 .grantDefaultPermissionsToDefaultSimCallManager( 118 packageName, userId); 119 } 120 } 121 } 122 } 123 } 124 } catch (RemoteException e) { 125 Slog.w(TAG, "Failed linking to death."); 126 } 127 } 128 129 @Override 130 public void onServiceDisconnected(ComponentName name) { 131 connectToTelecom(); 132 } 133 } 134 135 private static final ComponentName SERVICE_COMPONENT = new ComponentName( 136 "com.android.server.telecom", 137 "com.android.server.telecom.components.TelecomService"); 138 139 private static final String SERVICE_ACTION = "com.android.ITelecomService"; 140 141 private final Object mLock = new Object(); 142 143 @GuardedBy("mLock") 144 private IntArray mDefaultSmsAppRequests; 145 146 @GuardedBy("mLock") 147 private IntArray mDefaultDialerAppRequests; 148 149 @GuardedBy("mLock") 150 private IntArray mDefaultSimCallManagerRequests; 151 152 private final Context mContext; 153 154 @GuardedBy("mLock") 155 private TelecomServiceConnection mServiceConnection; 156 157 public TelecomLoaderService(Context context) { 158 super(context); 159 mContext = context; 160 registerDefaultAppProviders(); 161 } 162 163 @Override 164 public void onStart() { 165 } 166 167 @Override 168 public void onBootPhase(int phase) { 169 if (phase == PHASE_ACTIVITY_MANAGER_READY) { 170 registerDefaultAppNotifier(); 171 registerCarrierConfigChangedReceiver(); 172 connectToTelecom(); 173 } 174 } 175 176 private void connectToTelecom() { 177 synchronized (mLock) { 178 if (mServiceConnection != null) { 179 // TODO: Is unbinding worth doing or wait for system to rebind? 180 mContext.unbindService(mServiceConnection); 181 mServiceConnection = null; 182 } 183 184 TelecomServiceConnection serviceConnection = new TelecomServiceConnection(); 185 Intent intent = new Intent(SERVICE_ACTION); 186 intent.setComponent(SERVICE_COMPONENT); 187 int flags = Context.BIND_IMPORTANT | Context.BIND_FOREGROUND_SERVICE 188 | Context.BIND_AUTO_CREATE; 189 190 // Bind to Telecom and register the service 191 if (mContext.bindServiceAsUser(intent, serviceConnection, flags, UserHandle.SYSTEM)) { 192 mServiceConnection = serviceConnection; 193 } 194 } 195 } 196 197 198 private void registerDefaultAppProviders() { 199 final PackageManagerInternal packageManagerInternal = LocalServices.getService( 200 PackageManagerInternal.class); 201 202 // Set a callback for the package manager to query the default sms app. 203 packageManagerInternal.setSmsAppPackagesProvider( 204 new PackageManagerInternal.PackagesProvider() { 205 @Override 206 public String[] getPackages(int userId) { 207 synchronized (mLock) { 208 if (mServiceConnection == null) { 209 if (mDefaultSmsAppRequests == null) { 210 mDefaultSmsAppRequests = new IntArray(); 211 } 212 mDefaultSmsAppRequests.add(userId); 213 return null; 214 } 215 } 216 ComponentName smsComponent = SmsApplication.getDefaultSmsApplication( 217 mContext, true); 218 if (smsComponent != null) { 219 return new String[]{smsComponent.getPackageName()}; 220 } 221 return null; 222 } 223 }); 224 225 // Set a callback for the package manager to query the default dialer app. 226 packageManagerInternal.setDialerAppPackagesProvider( 227 new PackageManagerInternal.PackagesProvider() { 228 @Override 229 public String[] getPackages(int userId) { 230 synchronized (mLock) { 231 if (mServiceConnection == null) { 232 if (mDefaultDialerAppRequests == null) { 233 mDefaultDialerAppRequests = new IntArray(); 234 } 235 mDefaultDialerAppRequests.add(userId); 236 return null; 237 } 238 } 239 String packageName = DefaultDialerManager.getDefaultDialerApplication(mContext); 240 if (packageName != null) { 241 return new String[]{packageName}; 242 } 243 return null; 244 } 245 }); 246 247 // Set a callback for the package manager to query the default sim call manager. 248 packageManagerInternal.setSimCallManagerPackagesProvider( 249 new PackageManagerInternal.PackagesProvider() { 250 @Override 251 public String[] getPackages(int userId) { 252 synchronized (mLock) { 253 if (mServiceConnection == null) { 254 if (mDefaultSimCallManagerRequests == null) { 255 mDefaultSimCallManagerRequests = new IntArray(); 256 } 257 mDefaultSimCallManagerRequests.add(userId); 258 return null; 259 } 260 } 261 TelecomManager telecomManager = 262 (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE); 263 PhoneAccountHandle phoneAccount = telecomManager.getSimCallManager(userId); 264 if (phoneAccount != null) { 265 return new String[]{phoneAccount.getComponentName().getPackageName()}; 266 } 267 return null; 268 } 269 }); 270 } 271 272 private void registerDefaultAppNotifier() { 273 final PackageManagerInternal packageManagerInternal = LocalServices.getService( 274 PackageManagerInternal.class); 275 276 // Notify the package manager on default app changes 277 final Uri defaultSmsAppUri = Settings.Secure.getUriFor( 278 Settings.Secure.SMS_DEFAULT_APPLICATION); 279 final Uri defaultDialerAppUri = Settings.Secure.getUriFor( 280 Settings.Secure.DIALER_DEFAULT_APPLICATION); 281 282 ContentObserver contentObserver = new ContentObserver( 283 new Handler(Looper.getMainLooper())) { 284 @Override 285 public void onChange(boolean selfChange, Uri uri, int userId) { 286 if (defaultSmsAppUri.equals(uri)) { 287 ComponentName smsComponent = SmsApplication.getDefaultSmsApplication( 288 mContext, true); 289 if (smsComponent != null) { 290 packageManagerInternal.grantDefaultPermissionsToDefaultSmsApp( 291 smsComponent.getPackageName(), userId); 292 } 293 } else if (defaultDialerAppUri.equals(uri)) { 294 String packageName = DefaultDialerManager.getDefaultDialerApplication( 295 mContext); 296 if (packageName != null) { 297 packageManagerInternal.grantDefaultPermissionsToDefaultDialerApp( 298 packageName, userId); 299 } 300 updateSimCallManagerPermissions(packageManagerInternal, userId); 301 } 302 } 303 }; 304 305 mContext.getContentResolver().registerContentObserver(defaultSmsAppUri, 306 false, contentObserver, UserHandle.USER_ALL); 307 mContext.getContentResolver().registerContentObserver(defaultDialerAppUri, 308 false, contentObserver, UserHandle.USER_ALL); 309 } 310 311 312 private void registerCarrierConfigChangedReceiver() { 313 final PackageManagerInternal packageManagerInternal = LocalServices.getService( 314 PackageManagerInternal.class); 315 BroadcastReceiver receiver = new BroadcastReceiver() { 316 @Override 317 public void onReceive(Context context, Intent intent) { 318 if (intent.getAction().equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) { 319 for (int userId : UserManagerService.getInstance().getUserIds()) { 320 updateSimCallManagerPermissions(packageManagerInternal, userId); 321 } 322 } 323 } 324 }; 325 326 mContext.registerReceiverAsUser(receiver, UserHandle.ALL, 327 new IntentFilter(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED), null, null); 328 } 329 330 private void updateSimCallManagerPermissions(PackageManagerInternal packageManagerInternal, 331 int userId) { 332 TelecomManager telecomManager = 333 (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE); 334 PhoneAccountHandle phoneAccount = telecomManager.getSimCallManager(userId); 335 if (phoneAccount != null) { 336 Slog.i(TAG, "updating sim call manager permissions for userId:" + userId); 337 String packageName = phoneAccount.getComponentName().getPackageName(); 338 packageManagerInternal.grantDefaultPermissionsToDefaultSimCallManager( 339 packageName, userId); 340 } 341 } 342 } 343