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