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