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