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.components.UserCallIntentProcessor; 21 import com.android.server.telecom.components.UserCallIntentProcessorFactory; 22 import com.android.server.telecom.ui.MissedCallNotifierImpl.MissedCallNotifierImplFactory; 23 import com.android.server.telecom.BluetoothPhoneServiceImpl.BluetoothPhoneServiceImplFactory; 24 import com.android.server.telecom.CallAudioManager.AudioServiceFactory; 25 import com.android.server.telecom.TelecomServiceImpl.DefaultDialerManagerAdapter; 26 27 import android.Manifest; 28 import android.content.BroadcastReceiver; 29 import android.content.Context; 30 import android.content.Intent; 31 import android.content.IntentFilter; 32 import android.net.Uri; 33 import android.os.UserHandle; 34 35 import java.io.FileNotFoundException; 36 import java.io.InputStream; 37 38 /** 39 * Top-level Application class for Telecom. 40 */ 41 public 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 mContext = context.getApplicationContext(); 160 Log.setContext(mContext); 161 Log.initMd5Sum(); 162 163 Log.startSession("TS.init"); 164 mPhoneAccountRegistrar = new PhoneAccountRegistrar(mContext); 165 mContactsAsyncHelper = new ContactsAsyncHelper( 166 new ContactsAsyncHelper.ContentResolverAdapter() { 167 @Override 168 public InputStream openInputStream(Context context, Uri uri) 169 throws FileNotFoundException { 170 return context.getContentResolver().openInputStream(uri); 171 } 172 }); 173 BluetoothManager bluetoothManager = new BluetoothManager(mContext, 174 new BluetoothAdapterProxy()); 175 WiredHeadsetManager wiredHeadsetManager = new WiredHeadsetManager(mContext); 176 SystemStateProvider systemStateProvider = new SystemStateProvider(mContext); 177 178 mMissedCallNotifier = missedCallNotifierImplFactory 179 .makeMissedCallNotifierImpl(mContext, mPhoneAccountRegistrar, 180 phoneNumberUtilsAdapter); 181 182 DefaultDialerManagerAdapter defaultDialerAdapter = 183 new TelecomServiceImpl.DefaultDialerManagerAdapterImpl(); 184 185 mCallsManager = new CallsManager( 186 mContext, 187 mLock, 188 mContactsAsyncHelper, 189 callerInfoAsyncQueryFactory, 190 mMissedCallNotifier, 191 mPhoneAccountRegistrar, 192 headsetMediaButtonFactory, 193 proximitySensorManagerFactory, 194 inCallWakeLockControllerFactory, 195 audioServiceFactory, 196 bluetoothManager, 197 wiredHeadsetManager, 198 systemStateProvider, 199 defaultDialerAdapter, 200 timeoutsAdapter, 201 asyncRingtonePlayer, 202 phoneNumberUtilsAdapter); 203 204 mRespondViaSmsManager = new RespondViaSmsManager(mCallsManager, mLock); 205 mCallsManager.setRespondViaSmsManager(mRespondViaSmsManager); 206 207 mContext.registerReceiver(mUserSwitchedReceiver, USER_SWITCHED_FILTER); 208 mContext.registerReceiver(mUserStartingReceiver, USER_STARTING_FILTER); 209 210 mBluetoothPhoneServiceImpl = bluetoothPhoneServiceImplFactory.makeBluetoothPhoneServiceImpl( 211 mContext, mLock, mCallsManager, mPhoneAccountRegistrar); 212 mCallIntentProcessor = new CallIntentProcessor(mContext, mCallsManager); 213 mTelecomBroadcastIntentProcessor = new TelecomBroadcastIntentProcessor( 214 mContext, mCallsManager); 215 216 // Register the receiver for the dialer secret codes, used to enable extended logging. 217 mDialerCodeReceiver = new DialerCodeReceiver(mCallsManager); 218 mContext.registerReceiver(mDialerCodeReceiver, DIALER_SECRET_CODE_FILTER, 219 Manifest.permission.CONTROL_INCALL_EXPERIENCE, null); 220 221 mTelecomServiceImpl = new TelecomServiceImpl( 222 mContext, mCallsManager, mPhoneAccountRegistrar, 223 new CallIntentProcessor.AdapterImpl(), 224 new UserCallIntentProcessorFactory() { 225 @Override 226 public UserCallIntentProcessor create(Context context, UserHandle userHandle) { 227 return new UserCallIntentProcessor(context, userHandle); 228 } 229 }, 230 defaultDialerAdapter, 231 new TelecomServiceImpl.SubscriptionManagerAdapterImpl(), 232 mLock); 233 Log.endSession(); 234 } 235 236 @VisibleForTesting 237 public PhoneAccountRegistrar getPhoneAccountRegistrar() { 238 return mPhoneAccountRegistrar; 239 } 240 241 @VisibleForTesting 242 public CallsManager getCallsManager() { 243 return mCallsManager; 244 } 245 246 public BluetoothPhoneServiceImpl getBluetoothPhoneServiceImpl() { 247 return mBluetoothPhoneServiceImpl; 248 } 249 250 public CallIntentProcessor getCallIntentProcessor() { 251 return mCallIntentProcessor; 252 } 253 254 public TelecomBroadcastIntentProcessor getTelecomBroadcastIntentProcessor() { 255 return mTelecomBroadcastIntentProcessor; 256 } 257 258 public TelecomServiceImpl getTelecomServiceImpl() { 259 return mTelecomServiceImpl; 260 } 261 262 public Object getLock() { 263 return mLock; 264 } 265 } 266