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