TelecomSystem.java revision eaaf074d6b8b0b16fb922d8d511d6e8b979bfe0d
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.components.UserCallIntentProcessor; 21import com.android.server.telecom.components.UserCallIntentProcessorFactory; 22import com.android.server.telecom.ui.MissedCallNotifierImpl.MissedCallNotifierImplFactory; 23import com.android.server.telecom.BluetoothPhoneServiceImpl.BluetoothPhoneServiceImplFactory; 24import com.android.server.telecom.CallAudioManager.AudioServiceFactory; 25import com.android.server.telecom.TelecomServiceImpl.DefaultDialerManagerAdapter; 26 27import android.Manifest; 28import android.content.BroadcastReceiver; 29import android.content.Context; 30import android.content.Intent; 31import android.content.IntentFilter; 32import android.net.Uri; 33import android.os.UserHandle; 34 35import java.io.FileNotFoundException; 36import java.io.InputStream; 37 38/** 39 * Top-level Application class for Telecom. 40 */ 41public final class TelecomSystem { 42 43 /** 44 * This interface is implemented by system-instantiated components (e.g., Services and 45 * Activity-s) that wish to use the TelecomSystem but would like to be testable. Such a 46 * component should implement the getTelecomSystem() method to return the global singleton, 47 * and use its own method. Tests can subclass the component to return a non-singleton. 48 * 49 * A refactoring goal for Telecom is to limit use of the TelecomSystem singleton to those 50 * system-instantiated components, and have all other parts of the system just take all their 51 * dependencies as explicit arguments to their constructor or other methods. 52 */ 53 public interface Component { 54 TelecomSystem getTelecomSystem(); 55 } 56 57 58 /** 59 * Tagging interface for the object used for synchronizing multi-threaded operations in 60 * the Telecom system. 61 */ 62 public interface SyncRoot { 63 } 64 65 private static final IntentFilter USER_SWITCHED_FILTER = 66 new IntentFilter(Intent.ACTION_USER_SWITCHED); 67 68 private static final IntentFilter USER_STARTING_FILTER = 69 new IntentFilter(Intent.ACTION_USER_STARTING); 70 71 /** Intent filter for dialer secret codes. */ 72 private static final IntentFilter DIALER_SECRET_CODE_FILTER; 73 74 /** 75 * Initializes the dialer secret code intent filter. Setup to handle the various secret codes 76 * which can be dialed (e.g. in format *#*#code#*#*) to trigger various behavior in Telecom. 77 */ 78 static { 79 DIALER_SECRET_CODE_FILTER = new IntentFilter( 80 "android.provider.Telephony.SECRET_CODE"); 81 DIALER_SECRET_CODE_FILTER.addDataScheme("android_secret_code"); 82 DIALER_SECRET_CODE_FILTER 83 .addDataAuthority(DialerCodeReceiver.TELECOM_SECRET_CODE_DEBUG_ON, null); 84 DIALER_SECRET_CODE_FILTER 85 .addDataAuthority(DialerCodeReceiver.TELECOM_SECRET_CODE_DEBUG_OFF, null); 86 DIALER_SECRET_CODE_FILTER 87 .addDataAuthority(DialerCodeReceiver.TELECOM_SECRET_CODE_MARK, null); 88 } 89 90 private static TelecomSystem INSTANCE = null; 91 92 private final SyncRoot mLock = new SyncRoot() { }; 93 private final MissedCallNotifier mMissedCallNotifier; 94 private final PhoneAccountRegistrar mPhoneAccountRegistrar; 95 private final CallsManager mCallsManager; 96 private final RespondViaSmsManager mRespondViaSmsManager; 97 private final Context mContext; 98 private final BluetoothPhoneServiceImpl mBluetoothPhoneServiceImpl; 99 private final CallIntentProcessor mCallIntentProcessor; 100 private final TelecomBroadcastIntentProcessor mTelecomBroadcastIntentProcessor; 101 private final TelecomServiceImpl mTelecomServiceImpl; 102 private final ContactsAsyncHelper mContactsAsyncHelper; 103 private final DialerCodeReceiver mDialerCodeReceiver; 104 105 private final BroadcastReceiver mUserSwitchedReceiver = new BroadcastReceiver() { 106 @Override 107 public void onReceive(Context context, Intent intent) { 108 Log.startSession("TSSwR.oR"); 109 try { 110 int userHandleId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); 111 UserHandle currentUserHandle = new UserHandle(userHandleId); 112 mPhoneAccountRegistrar.setCurrentUserHandle(currentUserHandle); 113 mCallsManager.onUserSwitch(currentUserHandle); 114 } finally { 115 Log.endSession(); 116 } 117 } 118 }; 119 120 private final BroadcastReceiver mUserStartingReceiver = new BroadcastReceiver() { 121 @Override 122 public void onReceive(Context context, Intent intent) { 123 Log.startSession("TSStR.oR"); 124 try { 125 int userHandleId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); 126 UserHandle addingUserHandle = new UserHandle(userHandleId); 127 mCallsManager.onUserStarting(addingUserHandle); 128 } finally { 129 Log.endSession(); 130 } 131 } 132 }; 133 134 public static TelecomSystem getInstance() { 135 return INSTANCE; 136 } 137 138 public static void setInstance(TelecomSystem instance) { 139 if (INSTANCE != null) { 140 throw new RuntimeException("Attempt to set TelecomSystem.INSTANCE twice"); 141 } 142 Log.i(TelecomSystem.class, "TelecomSystem.INSTANCE being set"); 143 INSTANCE = instance; 144 } 145 146 public TelecomSystem( 147 Context context, 148 MissedCallNotifierImplFactory missedCallNotifierImplFactory, 149 CallerInfoAsyncQueryFactory callerInfoAsyncQueryFactory, 150 HeadsetMediaButtonFactory headsetMediaButtonFactory, 151 ProximitySensorManagerFactory proximitySensorManagerFactory, 152 InCallWakeLockControllerFactory inCallWakeLockControllerFactory, 153 AudioServiceFactory audioServiceFactory, 154 BluetoothPhoneServiceImplFactory 155 bluetoothPhoneServiceImplFactory, 156 Timeouts.Adapter timeoutsAdapter, 157 AsyncRingtonePlayer asyncRingtonePlayer, 158 PhoneNumberUtilsAdapter phoneNumberUtilsAdapter, 159 InterruptionFilterProxy interruptionFilterProxy) { 160 mContext = context.getApplicationContext(); 161 Log.setContext(mContext); 162 Log.initMd5Sum(); 163 164 Log.startSession("TS.init"); 165 mPhoneAccountRegistrar = new PhoneAccountRegistrar(mContext); 166 mContactsAsyncHelper = new ContactsAsyncHelper( 167 new ContactsAsyncHelper.ContentResolverAdapter() { 168 @Override 169 public InputStream openInputStream(Context context, Uri uri) 170 throws FileNotFoundException { 171 return context.getContentResolver().openInputStream(uri); 172 } 173 }); 174 BluetoothManager bluetoothManager = new BluetoothManager(mContext, 175 new BluetoothAdapterProxy()); 176 WiredHeadsetManager wiredHeadsetManager = new WiredHeadsetManager(mContext); 177 SystemStateProvider systemStateProvider = new SystemStateProvider(mContext); 178 179 mMissedCallNotifier = missedCallNotifierImplFactory 180 .makeMissedCallNotifierImpl(mContext, mPhoneAccountRegistrar, 181 phoneNumberUtilsAdapter); 182 183 DefaultDialerManagerAdapter defaultDialerAdapter = 184 new TelecomServiceImpl.DefaultDialerManagerAdapterImpl(); 185 186 mCallsManager = new CallsManager( 187 mContext, 188 mLock, 189 mContactsAsyncHelper, 190 callerInfoAsyncQueryFactory, 191 mMissedCallNotifier, 192 mPhoneAccountRegistrar, 193 headsetMediaButtonFactory, 194 proximitySensorManagerFactory, 195 inCallWakeLockControllerFactory, 196 audioServiceFactory, 197 bluetoothManager, 198 wiredHeadsetManager, 199 systemStateProvider, 200 defaultDialerAdapter, 201 timeoutsAdapter, 202 asyncRingtonePlayer, 203 phoneNumberUtilsAdapter, 204 interruptionFilterProxy); 205 206 mRespondViaSmsManager = new RespondViaSmsManager(mCallsManager, mLock); 207 mCallsManager.setRespondViaSmsManager(mRespondViaSmsManager); 208 209 mContext.registerReceiver(mUserSwitchedReceiver, USER_SWITCHED_FILTER); 210 mContext.registerReceiver(mUserStartingReceiver, USER_STARTING_FILTER); 211 212 mBluetoothPhoneServiceImpl = bluetoothPhoneServiceImplFactory.makeBluetoothPhoneServiceImpl( 213 mContext, mLock, mCallsManager, mPhoneAccountRegistrar); 214 mCallIntentProcessor = new CallIntentProcessor(mContext, mCallsManager); 215 mTelecomBroadcastIntentProcessor = new TelecomBroadcastIntentProcessor( 216 mContext, mCallsManager); 217 218 // Register the receiver for the dialer secret codes, used to enable extended logging. 219 mDialerCodeReceiver = new DialerCodeReceiver(mCallsManager); 220 mContext.registerReceiver(mDialerCodeReceiver, DIALER_SECRET_CODE_FILTER, 221 Manifest.permission.CONTROL_INCALL_EXPERIENCE, null); 222 223 mTelecomServiceImpl = new TelecomServiceImpl( 224 mContext, mCallsManager, mPhoneAccountRegistrar, 225 new CallIntentProcessor.AdapterImpl(), 226 new UserCallIntentProcessorFactory() { 227 @Override 228 public UserCallIntentProcessor create(Context context, UserHandle userHandle) { 229 return new UserCallIntentProcessor(context, userHandle); 230 } 231 }, 232 defaultDialerAdapter, 233 new TelecomServiceImpl.SubscriptionManagerAdapterImpl(), 234 mLock); 235 Log.endSession(); 236 } 237 238 @VisibleForTesting 239 public PhoneAccountRegistrar getPhoneAccountRegistrar() { 240 return mPhoneAccountRegistrar; 241 } 242 243 @VisibleForTesting 244 public CallsManager getCallsManager() { 245 return mCallsManager; 246 } 247 248 public BluetoothPhoneServiceImpl getBluetoothPhoneServiceImpl() { 249 return mBluetoothPhoneServiceImpl; 250 } 251 252 public CallIntentProcessor getCallIntentProcessor() { 253 return mCallIntentProcessor; 254 } 255 256 public TelecomBroadcastIntentProcessor getTelecomBroadcastIntentProcessor() { 257 return mTelecomBroadcastIntentProcessor; 258 } 259 260 public TelecomServiceImpl getTelecomServiceImpl() { 261 return mTelecomServiceImpl; 262 } 263 264 public Object getLock() { 265 return mLock; 266 } 267} 268