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 com.android.internal.annotations.VisibleForTesting; 20 import com.android.server.telecom.bluetooth.BluetoothDeviceManager; 21 import com.android.server.telecom.bluetooth.BluetoothRouteManager; 22 import com.android.server.telecom.bluetooth.BluetoothStateReceiver; 23 import com.android.server.telecom.components.UserCallIntentProcessor; 24 import com.android.server.telecom.components.UserCallIntentProcessorFactory; 25 import com.android.server.telecom.ui.AudioProcessingNotification; 26 import com.android.server.telecom.ui.DisconnectedCallNotifier; 27 import com.android.server.telecom.ui.IncomingCallNotifier; 28 import com.android.server.telecom.ui.MissedCallNotifierImpl.MissedCallNotifierImplFactory; 29 import com.android.server.telecom.CallAudioManager.AudioServiceFactory; 30 import com.android.server.telecom.DefaultDialerCache.DefaultDialerManagerAdapter; 31 import com.android.server.telecom.ui.ToastFactory; 32 33 import android.app.ActivityManager; 34 import android.Manifest; 35 import android.content.BroadcastReceiver; 36 import android.content.Context; 37 import android.content.Intent; 38 import android.content.IntentFilter; 39 import android.content.ServiceConnection; 40 import android.content.pm.ApplicationInfo; 41 import android.content.pm.PackageManager; 42 import android.content.pm.ResolveInfo; 43 import android.net.Uri; 44 import android.os.UserHandle; 45 import android.os.UserManager; 46 import android.telecom.Log; 47 import android.telecom.PhoneAccountHandle; 48 import android.widget.Toast; 49 50 import androidx.annotation.NonNull; 51 52 import java.io.FileNotFoundException; 53 import java.io.InputStream; 54 import java.util.List; 55 56 /** 57 * Top-level Application class for Telecom. 58 */ 59 public class TelecomSystem { 60 61 /** 62 * This interface is implemented by system-instantiated components (e.g., Services and 63 * Activity-s) that wish to use the TelecomSystem but would like to be testable. Such a 64 * component should implement the getTelecomSystem() method to return the global singleton, 65 * and use its own method. Tests can subclass the component to return a non-singleton. 66 * 67 * A refactoring goal for Telecom is to limit use of the TelecomSystem singleton to those 68 * system-instantiated components, and have all other parts of the system just take all their 69 * dependencies as explicit arguments to their constructor or other methods. 70 */ 71 public interface Component { getTelecomSystem()72 TelecomSystem getTelecomSystem(); 73 } 74 75 76 /** 77 * Tagging interface for the object used for synchronizing multi-threaded operations in 78 * the Telecom system. 79 */ 80 public interface SyncRoot { 81 } 82 83 private static final IntentFilter USER_SWITCHED_FILTER = 84 new IntentFilter(Intent.ACTION_USER_SWITCHED); 85 86 private static final IntentFilter USER_STARTING_FILTER = 87 new IntentFilter(Intent.ACTION_USER_STARTING); 88 89 private static final IntentFilter BOOT_COMPLETE_FILTER = 90 new IntentFilter(Intent.ACTION_BOOT_COMPLETED); 91 92 /** Intent filter for dialer secret codes. */ 93 private static final IntentFilter DIALER_SECRET_CODE_FILTER; 94 95 /** 96 * Initializes the dialer secret code intent filter. Setup to handle the various secret codes 97 * which can be dialed (e.g. in format *#*#code#*#*) to trigger various behavior in Telecom. 98 */ 99 static { 100 DIALER_SECRET_CODE_FILTER = new IntentFilter( 101 "android.provider.Telephony.SECRET_CODE"); 102 DIALER_SECRET_CODE_FILTER.addDataScheme("android_secret_code"); 103 DIALER_SECRET_CODE_FILTER addDataAuthority(DialerCodeReceiver.TELECOM_SECRET_CODE_DEBUG_ON, null)104 .addDataAuthority(DialerCodeReceiver.TELECOM_SECRET_CODE_DEBUG_ON, null); 105 DIALER_SECRET_CODE_FILTER addDataAuthority(DialerCodeReceiver.TELECOM_SECRET_CODE_DEBUG_OFF, null)106 .addDataAuthority(DialerCodeReceiver.TELECOM_SECRET_CODE_DEBUG_OFF, null); 107 DIALER_SECRET_CODE_FILTER addDataAuthority(DialerCodeReceiver.TELECOM_SECRET_CODE_MARK, null)108 .addDataAuthority(DialerCodeReceiver.TELECOM_SECRET_CODE_MARK, null); 109 DIALER_SECRET_CODE_FILTER addDataAuthority(DialerCodeReceiver.TELECOM_SECRET_CODE_MENU, null)110 .addDataAuthority(DialerCodeReceiver.TELECOM_SECRET_CODE_MENU, null); 111 } 112 113 private static TelecomSystem INSTANCE = null; 114 115 private final SyncRoot mLock = new SyncRoot() { }; 116 private final MissedCallNotifier mMissedCallNotifier; 117 private final IncomingCallNotifier mIncomingCallNotifier; 118 private final PhoneAccountRegistrar mPhoneAccountRegistrar; 119 private final CallsManager mCallsManager; 120 private final RespondViaSmsManager mRespondViaSmsManager; 121 private final Context mContext; 122 private final CallIntentProcessor mCallIntentProcessor; 123 private final TelecomBroadcastIntentProcessor mTelecomBroadcastIntentProcessor; 124 private final TelecomServiceImpl mTelecomServiceImpl; 125 private final ContactsAsyncHelper mContactsAsyncHelper; 126 private final DialerCodeReceiver mDialerCodeReceiver; 127 128 private boolean mIsBootComplete = false; 129 130 private final BroadcastReceiver mUserSwitchedReceiver = new BroadcastReceiver() { 131 @Override 132 public void onReceive(Context context, Intent intent) { 133 Log.startSession("TSSwR.oR"); 134 try { 135 synchronized (mLock) { 136 int userHandleId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); 137 UserHandle currentUserHandle = new UserHandle(userHandleId); 138 mPhoneAccountRegistrar.setCurrentUserHandle(currentUserHandle); 139 mCallsManager.onUserSwitch(currentUserHandle); 140 } 141 } finally { 142 Log.endSession(); 143 } 144 } 145 }; 146 147 private final BroadcastReceiver mUserStartingReceiver = new BroadcastReceiver() { 148 @Override 149 public void onReceive(Context context, Intent intent) { 150 Log.startSession("TSStR.oR"); 151 try { 152 synchronized (mLock) { 153 int userHandleId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); 154 UserHandle addingUserHandle = new UserHandle(userHandleId); 155 mCallsManager.onUserStarting(addingUserHandle); 156 } 157 } finally { 158 Log.endSession(); 159 } 160 } 161 }; 162 163 private final BroadcastReceiver mBootCompletedReceiver = new BroadcastReceiver() { 164 @Override 165 public void onReceive(Context context, Intent intent) { 166 Log.startSession("TSBCR.oR"); 167 try { 168 synchronized (mLock) { 169 mIsBootComplete = true; 170 mCallsManager.onBootCompleted(); 171 } 172 } finally { 173 Log.endSession(); 174 } 175 } 176 }; 177 getInstance()178 public static TelecomSystem getInstance() { 179 return INSTANCE; 180 } 181 setInstance(TelecomSystem instance)182 public static void setInstance(TelecomSystem instance) { 183 if (INSTANCE != null) { 184 Log.w("TelecomSystem", "Attempt to set TelecomSystem.INSTANCE twice"); 185 } 186 Log.i(TelecomSystem.class, "TelecomSystem.INSTANCE being set"); 187 INSTANCE = instance; 188 } 189 TelecomSystem( Context context, MissedCallNotifierImplFactory missedCallNotifierImplFactory, CallerInfoAsyncQueryFactory callerInfoAsyncQueryFactory, HeadsetMediaButtonFactory headsetMediaButtonFactory, ProximitySensorManagerFactory proximitySensorManagerFactory, InCallWakeLockControllerFactory inCallWakeLockControllerFactory, AudioServiceFactory audioServiceFactory, ConnectionServiceFocusManager.ConnectionServiceFocusManagerFactory connectionServiceFocusManagerFactory, Timeouts.Adapter timeoutsAdapter, AsyncRingtonePlayer asyncRingtonePlayer, PhoneNumberUtilsAdapter phoneNumberUtilsAdapter, IncomingCallNotifier incomingCallNotifier, InCallTonePlayer.ToneGeneratorFactory toneGeneratorFactory, CallAudioRouteStateMachine.Factory callAudioRouteStateMachineFactory, CallAudioModeStateMachine.Factory callAudioModeStateMachineFactory, ClockProxy clockProxy, RoleManagerAdapter roleManagerAdapter, ContactsAsyncHelper.Factory contactsAsyncHelperFactory, DeviceIdleControllerAdapter deviceIdleControllerAdapter)190 public TelecomSystem( 191 Context context, 192 MissedCallNotifierImplFactory missedCallNotifierImplFactory, 193 CallerInfoAsyncQueryFactory callerInfoAsyncQueryFactory, 194 HeadsetMediaButtonFactory headsetMediaButtonFactory, 195 ProximitySensorManagerFactory proximitySensorManagerFactory, 196 InCallWakeLockControllerFactory inCallWakeLockControllerFactory, 197 AudioServiceFactory audioServiceFactory, 198 ConnectionServiceFocusManager.ConnectionServiceFocusManagerFactory 199 connectionServiceFocusManagerFactory, 200 Timeouts.Adapter timeoutsAdapter, 201 AsyncRingtonePlayer asyncRingtonePlayer, 202 PhoneNumberUtilsAdapter phoneNumberUtilsAdapter, 203 IncomingCallNotifier incomingCallNotifier, 204 InCallTonePlayer.ToneGeneratorFactory toneGeneratorFactory, 205 CallAudioRouteStateMachine.Factory callAudioRouteStateMachineFactory, 206 CallAudioModeStateMachine.Factory callAudioModeStateMachineFactory, 207 ClockProxy clockProxy, 208 RoleManagerAdapter roleManagerAdapter, 209 ContactsAsyncHelper.Factory contactsAsyncHelperFactory, 210 DeviceIdleControllerAdapter deviceIdleControllerAdapter) { 211 mContext = context.getApplicationContext(); 212 LogUtils.initLogging(mContext); 213 DefaultDialerManagerAdapter defaultDialerAdapter = 214 new DefaultDialerCache.DefaultDialerManagerAdapterImpl(); 215 216 DefaultDialerCache defaultDialerCache = new DefaultDialerCache(mContext, 217 defaultDialerAdapter, roleManagerAdapter, mLock); 218 219 Log.startSession("TS.init"); 220 // Wrap this in a try block to ensure session cleanup occurs in the case of error. 221 try { 222 mPhoneAccountRegistrar = new PhoneAccountRegistrar(mContext, defaultDialerCache, 223 packageName -> AppLabelProxy.Util.getAppLabel( 224 mContext.getPackageManager(), packageName)); 225 226 mContactsAsyncHelper = contactsAsyncHelperFactory.create( 227 new ContactsAsyncHelper.ContentResolverAdapter() { 228 @Override 229 public InputStream openInputStream(Context context, Uri uri) 230 throws FileNotFoundException { 231 return context.getContentResolver().openInputStream(uri); 232 } 233 }); 234 BluetoothDeviceManager bluetoothDeviceManager = new BluetoothDeviceManager(mContext, 235 new BluetoothAdapterProxy()); 236 BluetoothRouteManager bluetoothRouteManager = new BluetoothRouteManager(mContext, mLock, 237 bluetoothDeviceManager, new Timeouts.Adapter()); 238 BluetoothStateReceiver bluetoothStateReceiver = new BluetoothStateReceiver( 239 bluetoothDeviceManager, bluetoothRouteManager); 240 mContext.registerReceiver(bluetoothStateReceiver, BluetoothStateReceiver.INTENT_FILTER); 241 242 WiredHeadsetManager wiredHeadsetManager = new WiredHeadsetManager(mContext); 243 SystemStateHelper systemStateHelper = new SystemStateHelper(mContext, mLock); 244 245 mMissedCallNotifier = missedCallNotifierImplFactory 246 .makeMissedCallNotifierImpl(mContext, mPhoneAccountRegistrar, 247 defaultDialerCache, 248 deviceIdleControllerAdapter); 249 DisconnectedCallNotifier.Factory disconnectedCallNotifierFactory = 250 new DisconnectedCallNotifier.Default(); 251 252 CallerInfoLookupHelper callerInfoLookupHelper = 253 new CallerInfoLookupHelper(context, callerInfoAsyncQueryFactory, 254 mContactsAsyncHelper, mLock); 255 256 EmergencyCallHelper emergencyCallHelper = new EmergencyCallHelper(mContext, 257 defaultDialerCache, timeoutsAdapter); 258 259 InCallControllerFactory inCallControllerFactory = new InCallControllerFactory() { 260 @Override 261 public InCallController create(Context context, SyncRoot lock, 262 CallsManager callsManager, SystemStateHelper systemStateProvider, 263 DefaultDialerCache defaultDialerCache, Timeouts.Adapter timeoutsAdapter, 264 EmergencyCallHelper emergencyCallHelper) { 265 return new InCallController(context, lock, callsManager, systemStateProvider, 266 defaultDialerCache, timeoutsAdapter, emergencyCallHelper, 267 new CarModeTracker(), clockProxy); 268 } 269 }; 270 271 CallDiagnosticServiceController callDiagnosticServiceController = 272 new CallDiagnosticServiceController( 273 new CallDiagnosticServiceController.ContextProxy() { 274 @Override 275 public List<ResolveInfo> queryIntentServicesAsUser( 276 @NonNull Intent intent, int flags, int userId) { 277 return mContext.getPackageManager().queryIntentServicesAsUser( 278 intent, flags, userId); 279 } 280 281 @Override 282 public boolean bindServiceAsUser(@NonNull Intent service, 283 @NonNull ServiceConnection conn, int flags, 284 @NonNull UserHandle user) { 285 return mContext.bindServiceAsUser(service, conn, flags, user); 286 } 287 288 @Override 289 public void unbindService(@NonNull ServiceConnection conn) { 290 mContext.unbindService(conn); 291 } 292 293 @Override 294 public UserHandle getCurrentUserHandle() { 295 return mCallsManager.getCurrentUserHandle(); 296 } 297 }, 298 mContext.getResources().getString( 299 com.android.server.telecom.R.string 300 .call_diagnostic_service_package_name), 301 mLock 302 ); 303 304 AudioProcessingNotification audioProcessingNotification = 305 new AudioProcessingNotification(mContext); 306 307 ToastFactory toastFactory = new ToastFactory() { 308 @Override 309 public Toast makeText(Context context, int resId, int duration) { 310 return Toast.makeText(context, context.getMainLooper(), 311 context.getString(resId), 312 duration); 313 } 314 315 @Override 316 public Toast makeText(Context context, CharSequence text, int duration) { 317 return Toast.makeText(context, context.getMainLooper(), text, duration); 318 } 319 }; 320 321 mCallsManager = new CallsManager( 322 mContext, 323 mLock, 324 callerInfoLookupHelper, 325 mMissedCallNotifier, 326 disconnectedCallNotifierFactory, 327 mPhoneAccountRegistrar, 328 headsetMediaButtonFactory, 329 proximitySensorManagerFactory, 330 inCallWakeLockControllerFactory, 331 connectionServiceFocusManagerFactory, 332 audioServiceFactory, 333 bluetoothRouteManager, 334 wiredHeadsetManager, 335 systemStateHelper, 336 defaultDialerCache, 337 timeoutsAdapter, 338 asyncRingtonePlayer, 339 phoneNumberUtilsAdapter, 340 emergencyCallHelper, 341 toneGeneratorFactory, 342 clockProxy, 343 audioProcessingNotification, 344 bluetoothStateReceiver, 345 callAudioRouteStateMachineFactory, 346 callAudioModeStateMachineFactory, 347 inCallControllerFactory, 348 callDiagnosticServiceController, 349 roleManagerAdapter, 350 toastFactory); 351 352 mIncomingCallNotifier = incomingCallNotifier; 353 incomingCallNotifier.setCallsManagerProxy(new IncomingCallNotifier.CallsManagerProxy() { 354 @Override 355 public boolean hasUnholdableCallsForOtherConnectionService( 356 PhoneAccountHandle phoneAccountHandle) { 357 return mCallsManager.hasUnholdableCallsForOtherConnectionService( 358 phoneAccountHandle); 359 } 360 361 @Override 362 public int getNumUnholdableCallsForOtherConnectionService( 363 PhoneAccountHandle phoneAccountHandle) { 364 return mCallsManager.getNumUnholdableCallsForOtherConnectionService( 365 phoneAccountHandle); 366 } 367 368 @Override 369 public Call getActiveCall() { 370 return mCallsManager.getActiveCall(); 371 } 372 }); 373 mCallsManager.setIncomingCallNotifier(mIncomingCallNotifier); 374 375 mRespondViaSmsManager = new RespondViaSmsManager(mCallsManager, mLock); 376 mCallsManager.setRespondViaSmsManager(mRespondViaSmsManager); 377 378 mContext.registerReceiverAsUser(mUserSwitchedReceiver, UserHandle.ALL, 379 USER_SWITCHED_FILTER, null, null); 380 mContext.registerReceiverAsUser(mUserStartingReceiver, UserHandle.ALL, 381 USER_STARTING_FILTER, null, null); 382 mContext.registerReceiverAsUser(mBootCompletedReceiver, UserHandle.ALL, 383 BOOT_COMPLETE_FILTER, null, null); 384 385 // Set current user explicitly since USER_SWITCHED_FILTER intent can be missed at 386 // startup 387 synchronized (mLock) { 388 UserHandle currentUserHandle = UserHandle.of(ActivityManager.getCurrentUser()); 389 mPhoneAccountRegistrar.setCurrentUserHandle(currentUserHandle); 390 mCallsManager.onUserSwitch(currentUserHandle); 391 } 392 393 mCallIntentProcessor = new CallIntentProcessor(mContext, mCallsManager, 394 defaultDialerCache); 395 mTelecomBroadcastIntentProcessor = new TelecomBroadcastIntentProcessor( 396 mContext, mCallsManager); 397 398 // Register the receiver for the dialer secret codes, used to enable extended logging. 399 mDialerCodeReceiver = new DialerCodeReceiver(mCallsManager); 400 mContext.registerReceiver(mDialerCodeReceiver, DIALER_SECRET_CODE_FILTER, 401 Manifest.permission.CONTROL_INCALL_EXPERIENCE, null); 402 403 // There is no USER_SWITCHED broadcast for user 0, handle it here explicitly. 404 final UserManager userManager = UserManager.get(mContext); 405 mTelecomServiceImpl = new TelecomServiceImpl( 406 mContext, mCallsManager, mPhoneAccountRegistrar, 407 new CallIntentProcessor.AdapterImpl(defaultDialerCache), 408 new UserCallIntentProcessorFactory() { 409 @Override 410 public UserCallIntentProcessor create(Context context, 411 UserHandle userHandle) { 412 return new UserCallIntentProcessor(context, userHandle); 413 } 414 }, 415 defaultDialerCache, 416 new TelecomServiceImpl.SubscriptionManagerAdapterImpl(), 417 new TelecomServiceImpl.SettingsSecureAdapterImpl(), 418 mLock); 419 } finally { 420 Log.endSession(); 421 } 422 } 423 424 @VisibleForTesting getPhoneAccountRegistrar()425 public PhoneAccountRegistrar getPhoneAccountRegistrar() { 426 return mPhoneAccountRegistrar; 427 } 428 429 @VisibleForTesting getCallsManager()430 public CallsManager getCallsManager() { 431 return mCallsManager; 432 } 433 getCallIntentProcessor()434 public CallIntentProcessor getCallIntentProcessor() { 435 return mCallIntentProcessor; 436 } 437 getTelecomBroadcastIntentProcessor()438 public TelecomBroadcastIntentProcessor getTelecomBroadcastIntentProcessor() { 439 return mTelecomBroadcastIntentProcessor; 440 } 441 getTelecomServiceImpl()442 public TelecomServiceImpl getTelecomServiceImpl() { 443 return mTelecomServiceImpl; 444 } 445 getLock()446 public Object getLock() { 447 return mLock; 448 } 449 isBootComplete()450 public boolean isBootComplete() { 451 return mIsBootComplete; 452 } 453 } 454