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