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