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, DeviceIdleControllerAdapter deviceIdleControllerAdapter)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 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 mPhoneAccountRegistrar = new PhoneAccountRegistrar(mContext, defaultDialerCache, 222 packageName -> AppLabelProxy.Util.getAppLabel( 223 mContext.getPackageManager(), packageName)); 224 225 mContactsAsyncHelper = contactsAsyncHelperFactory.create( 226 new ContactsAsyncHelper.ContentResolverAdapter() { 227 @Override 228 public InputStream openInputStream(Context context, Uri uri) 229 throws FileNotFoundException { 230 return context.getContentResolver().openInputStream(uri); 231 } 232 }); 233 BluetoothDeviceManager bluetoothDeviceManager = new BluetoothDeviceManager(mContext, 234 new BluetoothAdapterProxy()); 235 BluetoothRouteManager bluetoothRouteManager = new BluetoothRouteManager(mContext, mLock, 236 bluetoothDeviceManager, new Timeouts.Adapter()); 237 BluetoothStateReceiver bluetoothStateReceiver = new BluetoothStateReceiver( 238 bluetoothDeviceManager, bluetoothRouteManager); 239 mContext.registerReceiver(bluetoothStateReceiver, BluetoothStateReceiver.INTENT_FILTER); 240 241 WiredHeadsetManager wiredHeadsetManager = new WiredHeadsetManager(mContext); 242 SystemStateHelper systemStateHelper = new SystemStateHelper(mContext); 243 244 mMissedCallNotifier = missedCallNotifierImplFactory 245 .makeMissedCallNotifierImpl(mContext, mPhoneAccountRegistrar, defaultDialerCache, 246 deviceIdleControllerAdapter); 247 DisconnectedCallNotifier.Factory disconnectedCallNotifierFactory = 248 new DisconnectedCallNotifier.Default(); 249 250 CallerInfoLookupHelper callerInfoLookupHelper = 251 new CallerInfoLookupHelper(context, callerInfoAsyncQueryFactory, 252 mContactsAsyncHelper, mLock); 253 254 EmergencyCallHelper emergencyCallHelper = new EmergencyCallHelper(mContext, 255 defaultDialerCache, timeoutsAdapter); 256 257 InCallControllerFactory inCallControllerFactory = new InCallControllerFactory() { 258 @Override 259 public InCallController create(Context context, SyncRoot lock, 260 CallsManager callsManager, SystemStateHelper systemStateProvider, 261 DefaultDialerCache defaultDialerCache, Timeouts.Adapter timeoutsAdapter, 262 EmergencyCallHelper emergencyCallHelper) { 263 return new InCallController(context, lock, callsManager, systemStateProvider, 264 defaultDialerCache, timeoutsAdapter, emergencyCallHelper, 265 new CarModeTracker(), clockProxy); 266 } 267 }; 268 269 AudioProcessingNotification audioProcessingNotification = 270 new AudioProcessingNotification(mContext); 271 272 ToastFactory toastFactory = new ToastFactory() { 273 @Override 274 public Toast makeText(Context context, int resId, int duration) { 275 return Toast.makeText(context, context.getMainLooper(), context.getString(resId), 276 duration); 277 } 278 279 @Override 280 public Toast makeText(Context context, CharSequence text, int duration) { 281 return Toast.makeText(context, context.getMainLooper(), text, duration); 282 } 283 }; 284 285 mCallsManager = new CallsManager( 286 mContext, 287 mLock, 288 callerInfoLookupHelper, 289 mMissedCallNotifier, 290 disconnectedCallNotifierFactory, 291 mPhoneAccountRegistrar, 292 headsetMediaButtonFactory, 293 proximitySensorManagerFactory, 294 inCallWakeLockControllerFactory, 295 connectionServiceFocusManagerFactory, 296 audioServiceFactory, 297 bluetoothRouteManager, 298 wiredHeadsetManager, 299 systemStateHelper, 300 defaultDialerCache, 301 timeoutsAdapter, 302 asyncRingtonePlayer, 303 phoneNumberUtilsAdapter, 304 emergencyCallHelper, 305 toneGeneratorFactory, 306 clockProxy, 307 audioProcessingNotification, 308 bluetoothStateReceiver, 309 callAudioRouteStateMachineFactory, 310 callAudioModeStateMachineFactory, 311 inCallControllerFactory, 312 roleManagerAdapter, 313 incomingCallFilterFactory, 314 toastFactory); 315 316 mIncomingCallNotifier = incomingCallNotifier; 317 incomingCallNotifier.setCallsManagerProxy(new IncomingCallNotifier.CallsManagerProxy() { 318 @Override 319 public boolean hasUnholdableCallsForOtherConnectionService( 320 PhoneAccountHandle phoneAccountHandle) { 321 return mCallsManager.hasUnholdableCallsForOtherConnectionService( 322 phoneAccountHandle); 323 } 324 325 @Override 326 public int getNumUnholdableCallsForOtherConnectionService( 327 PhoneAccountHandle phoneAccountHandle) { 328 return mCallsManager.getNumUnholdableCallsForOtherConnectionService( 329 phoneAccountHandle); 330 } 331 332 @Override 333 public Call getActiveCall() { 334 return mCallsManager.getActiveCall(); 335 } 336 }); 337 mCallsManager.setIncomingCallNotifier(mIncomingCallNotifier); 338 339 mRespondViaSmsManager = new RespondViaSmsManager(mCallsManager, mLock); 340 mCallsManager.setRespondViaSmsManager(mRespondViaSmsManager); 341 342 mContext.registerReceiverAsUser(mUserSwitchedReceiver, UserHandle.ALL, 343 USER_SWITCHED_FILTER, null, null); 344 mContext.registerReceiverAsUser(mUserStartingReceiver, UserHandle.ALL, 345 USER_STARTING_FILTER, null, null); 346 mContext.registerReceiverAsUser(mBootCompletedReceiver, UserHandle.ALL, 347 BOOT_COMPLETE_FILTER, null, null); 348 349 // Set current user explicitly since USER_SWITCHED_FILTER intent can be missed at startup 350 synchronized(mLock) { 351 UserHandle currentUserHandle = UserHandle.of(ActivityManager.getCurrentUser()); 352 mPhoneAccountRegistrar.setCurrentUserHandle(currentUserHandle); 353 mCallsManager.onUserSwitch(currentUserHandle); 354 } 355 356 mBluetoothPhoneServiceImpl = bluetoothPhoneServiceImplFactory.makeBluetoothPhoneServiceImpl( 357 mContext, mLock, mCallsManager, mPhoneAccountRegistrar); 358 mCallIntentProcessor = new CallIntentProcessor(mContext, mCallsManager, defaultDialerCache); 359 mTelecomBroadcastIntentProcessor = new TelecomBroadcastIntentProcessor( 360 mContext, mCallsManager); 361 362 // Register the receiver for the dialer secret codes, used to enable extended logging. 363 mDialerCodeReceiver = new DialerCodeReceiver(mCallsManager); 364 mContext.registerReceiver(mDialerCodeReceiver, DIALER_SECRET_CODE_FILTER, 365 Manifest.permission.CONTROL_INCALL_EXPERIENCE, null); 366 367 // There is no USER_SWITCHED broadcast for user 0, handle it here explicitly. 368 final UserManager userManager = UserManager.get(mContext); 369 mTelecomServiceImpl = new TelecomServiceImpl( 370 mContext, mCallsManager, mPhoneAccountRegistrar, 371 new CallIntentProcessor.AdapterImpl(defaultDialerCache), 372 new UserCallIntentProcessorFactory() { 373 @Override 374 public UserCallIntentProcessor create(Context context, UserHandle userHandle) { 375 return new UserCallIntentProcessor(context, userHandle); 376 } 377 }, 378 defaultDialerCache, 379 new TelecomServiceImpl.SubscriptionManagerAdapterImpl(), 380 new TelecomServiceImpl.SettingsSecureAdapterImpl(), 381 mLock); 382 Log.endSession(); 383 } 384 385 @VisibleForTesting getPhoneAccountRegistrar()386 public PhoneAccountRegistrar getPhoneAccountRegistrar() { 387 return mPhoneAccountRegistrar; 388 } 389 390 @VisibleForTesting getCallsManager()391 public CallsManager getCallsManager() { 392 return mCallsManager; 393 } 394 getBluetoothPhoneServiceImpl()395 public BluetoothPhoneServiceImpl getBluetoothPhoneServiceImpl() { 396 return mBluetoothPhoneServiceImpl; 397 } 398 getCallIntentProcessor()399 public CallIntentProcessor getCallIntentProcessor() { 400 return mCallIntentProcessor; 401 } 402 getTelecomBroadcastIntentProcessor()403 public TelecomBroadcastIntentProcessor getTelecomBroadcastIntentProcessor() { 404 return mTelecomBroadcastIntentProcessor; 405 } 406 getTelecomServiceImpl()407 public TelecomServiceImpl getTelecomServiceImpl() { 408 return mTelecomServiceImpl; 409 } 410 getLock()411 public Object getLock() { 412 return mLock; 413 } 414 isBootComplete()415 public boolean isBootComplete() { 416 return mIsBootComplete; 417 } 418 } 419