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