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