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