TelecomSystem.java revision fc9c8ffcac8fb7c6796d0fe74152bb1fb14d74d9
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 17package com.android.server.telecom; 18 19import com.android.internal.annotations.VisibleForTesting; 20import com.android.server.telecom.bluetooth.BluetoothDeviceManager; 21import com.android.server.telecom.bluetooth.BluetoothRouteManager; 22import com.android.server.telecom.components.UserCallIntentProcessor; 23import com.android.server.telecom.components.UserCallIntentProcessorFactory; 24import com.android.server.telecom.ui.IncomingCallNotifier; 25import com.android.server.telecom.ui.MissedCallNotifierImpl.MissedCallNotifierImplFactory; 26import com.android.server.telecom.BluetoothPhoneServiceImpl.BluetoothPhoneServiceImplFactory; 27import com.android.server.telecom.CallAudioManager.AudioServiceFactory; 28import com.android.server.telecom.DefaultDialerCache.DefaultDialerManagerAdapter; 29 30import android.Manifest; 31import android.content.BroadcastReceiver; 32import android.content.Context; 33import android.content.Intent; 34import android.content.IntentFilter; 35import android.content.pm.ApplicationInfo; 36import android.content.pm.PackageManager; 37import android.net.Uri; 38import android.os.UserHandle; 39import android.telecom.Log; 40import android.telecom.PhoneAccountHandle; 41 42import java.io.FileNotFoundException; 43import java.io.InputStream; 44 45/** 46 * Top-level Application class for Telecom. 47 */ 48public 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 { 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 93 .addDataAuthority(DialerCodeReceiver.TELECOM_SECRET_CODE_DEBUG_ON, null); 94 DIALER_SECRET_CODE_FILTER 95 .addDataAuthority(DialerCodeReceiver.TELECOM_SECRET_CODE_DEBUG_OFF, null); 96 DIALER_SECRET_CODE_FILTER 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 166 public static TelecomSystem getInstance() { 167 return INSTANCE; 168 } 169 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 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 InCallControllerFactory inCallControllerFactory = new InCallControllerFactory() { 240 @Override 241 public InCallController create(Context context, SyncRoot lock, 242 CallsManager callsManager, SystemStateProvider systemStateProvider, 243 DefaultDialerCache defaultDialerCache, Timeouts.Adapter timeoutsAdapter, 244 EmergencyCallHelper emergencyCallHelper) { 245 return new InCallController(context, lock, callsManager, systemStateProvider, 246 defaultDialerCache, timeoutsAdapter, emergencyCallHelper); 247 } 248 }; 249 250 mCallsManager = new CallsManager( 251 mContext, 252 mLock, 253 mContactsAsyncHelper, 254 callerInfoAsyncQueryFactory, 255 mMissedCallNotifier, 256 mPhoneAccountRegistrar, 257 headsetMediaButtonFactory, 258 proximitySensorManagerFactory, 259 inCallWakeLockControllerFactory, 260 audioServiceFactory, 261 bluetoothRouteManager, 262 wiredHeadsetManager, 263 systemStateProvider, 264 defaultDialerCache, 265 timeoutsAdapter, 266 asyncRingtonePlayer, 267 phoneNumberUtilsAdapter, 268 emergencyCallHelper, 269 toneGeneratorFactory, 270 clockProxy, 271 inCallControllerFactory); 272 273 mIncomingCallNotifier = incomingCallNotifier; 274 incomingCallNotifier.setCallsManagerProxy(new IncomingCallNotifier.CallsManagerProxy() { 275 @Override 276 public boolean hasCallsForOtherPhoneAccount(PhoneAccountHandle phoneAccountHandle) { 277 return mCallsManager.hasCallsForOtherPhoneAccount(phoneAccountHandle); 278 } 279 280 @Override 281 public int getNumCallsForOtherPhoneAccount(PhoneAccountHandle phoneAccountHandle) { 282 return mCallsManager.getNumCallsForOtherPhoneAccount(phoneAccountHandle); 283 } 284 285 @Override 286 public Call getActiveCall() { 287 return mCallsManager.getActiveCall(); 288 } 289 }); 290 mCallsManager.setIncomingCallNotifier(mIncomingCallNotifier); 291 292 mRespondViaSmsManager = new RespondViaSmsManager(mCallsManager, mLock); 293 mCallsManager.setRespondViaSmsManager(mRespondViaSmsManager); 294 295 mContext.registerReceiver(mUserSwitchedReceiver, USER_SWITCHED_FILTER); 296 mContext.registerReceiver(mUserStartingReceiver, USER_STARTING_FILTER); 297 mContext.registerReceiver(mBootCompletedReceiver, BOOT_COMPLETE_FILTER); 298 299 mBluetoothPhoneServiceImpl = bluetoothPhoneServiceImplFactory.makeBluetoothPhoneServiceImpl( 300 mContext, mLock, mCallsManager, mPhoneAccountRegistrar); 301 mCallIntentProcessor = new CallIntentProcessor(mContext, mCallsManager); 302 mTelecomBroadcastIntentProcessor = new TelecomBroadcastIntentProcessor( 303 mContext, mCallsManager); 304 305 // Register the receiver for the dialer secret codes, used to enable extended logging. 306 mDialerCodeReceiver = new DialerCodeReceiver(mCallsManager); 307 mContext.registerReceiver(mDialerCodeReceiver, DIALER_SECRET_CODE_FILTER, 308 Manifest.permission.CONTROL_INCALL_EXPERIENCE, null); 309 310 mTelecomServiceImpl = new TelecomServiceImpl( 311 mContext, mCallsManager, mPhoneAccountRegistrar, 312 new CallIntentProcessor.AdapterImpl(), 313 new UserCallIntentProcessorFactory() { 314 @Override 315 public UserCallIntentProcessor create(Context context, UserHandle userHandle) { 316 return new UserCallIntentProcessor(context, userHandle); 317 } 318 }, 319 defaultDialerCache, 320 new TelecomServiceImpl.SubscriptionManagerAdapterImpl(), 321 mLock); 322 Log.endSession(); 323 } 324 325 @VisibleForTesting 326 public PhoneAccountRegistrar getPhoneAccountRegistrar() { 327 return mPhoneAccountRegistrar; 328 } 329 330 @VisibleForTesting 331 public CallsManager getCallsManager() { 332 return mCallsManager; 333 } 334 335 public BluetoothPhoneServiceImpl getBluetoothPhoneServiceImpl() { 336 return mBluetoothPhoneServiceImpl; 337 } 338 339 public CallIntentProcessor getCallIntentProcessor() { 340 return mCallIntentProcessor; 341 } 342 343 public TelecomBroadcastIntentProcessor getTelecomBroadcastIntentProcessor() { 344 return mTelecomBroadcastIntentProcessor; 345 } 346 347 public TelecomServiceImpl getTelecomServiceImpl() { 348 return mTelecomServiceImpl; 349 } 350 351 public Object getLock() { 352 return mLock; 353 } 354 355 public boolean isBootComplete() { 356 return mIsBootComplete; 357 } 358} 359