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