blob: 9ed612a60ac8a3bbfcb5cc1bb36edcddda73ad7f [file] [log] [blame]
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.telecom;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.telecom.components.UserCallIntentProcessor;
import com.android.server.telecom.components.UserCallIntentProcessorFactory;
import com.android.server.telecom.ui.MissedCallNotifierImpl.MissedCallNotifierImplFactory;
import com.android.server.telecom.BluetoothPhoneServiceImpl.BluetoothPhoneServiceImplFactory;
import com.android.server.telecom.CallAudioManager.AudioServiceFactory;
import com.android.server.telecom.TelecomServiceImpl.DefaultDialerManagerAdapter;
import android.Manifest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.UserHandle;
import java.io.FileNotFoundException;
import java.io.InputStream;
/**
* Top-level Application class for Telecom.
*/
public final class TelecomSystem {
/**
* This interface is implemented by system-instantiated components (e.g., Services and
* Activity-s) that wish to use the TelecomSystem but would like to be testable. Such a
* component should implement the getTelecomSystem() method to return the global singleton,
* and use its own method. Tests can subclass the component to return a non-singleton.
*
* A refactoring goal for Telecom is to limit use of the TelecomSystem singleton to those
* system-instantiated components, and have all other parts of the system just take all their
* dependencies as explicit arguments to their constructor or other methods.
*/
public interface Component {
TelecomSystem getTelecomSystem();
}
/**
* Tagging interface for the object used for synchronizing multi-threaded operations in
* the Telecom system.
*/
public interface SyncRoot {
}
private static final IntentFilter USER_SWITCHED_FILTER =
new IntentFilter(Intent.ACTION_USER_SWITCHED);
private static final IntentFilter USER_STARTING_FILTER =
new IntentFilter(Intent.ACTION_USER_STARTING);
/** Intent filter for dialer secret codes. */
private static final IntentFilter DIALER_SECRET_CODE_FILTER;
/**
* Initializes the dialer secret code intent filter. Setup to handle the various secret codes
* which can be dialed (e.g. in format *#*#code#*#*) to trigger various behavior in Telecom.
*/
static {
DIALER_SECRET_CODE_FILTER = new IntentFilter(
"android.provider.Telephony.SECRET_CODE");
DIALER_SECRET_CODE_FILTER.addDataScheme("android_secret_code");
DIALER_SECRET_CODE_FILTER
.addDataAuthority(DialerCodeReceiver.TELECOM_SECRET_CODE_DEBUG_ON, null);
DIALER_SECRET_CODE_FILTER
.addDataAuthority(DialerCodeReceiver.TELECOM_SECRET_CODE_DEBUG_OFF, null);
DIALER_SECRET_CODE_FILTER
.addDataAuthority(DialerCodeReceiver.TELECOM_SECRET_CODE_MARK, null);
}
private static TelecomSystem INSTANCE = null;
private final SyncRoot mLock = new SyncRoot() { };
private final MissedCallNotifier mMissedCallNotifier;
private final PhoneAccountRegistrar mPhoneAccountRegistrar;
private final CallsManager mCallsManager;
private final RespondViaSmsManager mRespondViaSmsManager;
private final Context mContext;
private final BluetoothPhoneServiceImpl mBluetoothPhoneServiceImpl;
private final CallIntentProcessor mCallIntentProcessor;
private final TelecomBroadcastIntentProcessor mTelecomBroadcastIntentProcessor;
private final TelecomServiceImpl mTelecomServiceImpl;
private final ContactsAsyncHelper mContactsAsyncHelper;
private final DialerCodeReceiver mDialerCodeReceiver;
private final BroadcastReceiver mUserSwitchedReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Log.startSession("TSSwR.oR");
try {
int userHandleId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
UserHandle currentUserHandle = new UserHandle(userHandleId);
mPhoneAccountRegistrar.setCurrentUserHandle(currentUserHandle);
mCallsManager.onUserSwitch(currentUserHandle);
} finally {
Log.endSession();
}
}
};
private final BroadcastReceiver mUserStartingReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Log.startSession("TSStR.oR");
try {
int userHandleId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
UserHandle addingUserHandle = new UserHandle(userHandleId);
mCallsManager.onUserStarting(addingUserHandle);
} finally {
Log.endSession();
}
}
};
public static TelecomSystem getInstance() {
return INSTANCE;
}
public static void setInstance(TelecomSystem instance) {
if (INSTANCE != null) {
throw new RuntimeException("Attempt to set TelecomSystem.INSTANCE twice");
}
Log.i(TelecomSystem.class, "TelecomSystem.INSTANCE being set");
INSTANCE = instance;
}
public TelecomSystem(
Context context,
MissedCallNotifierImplFactory missedCallNotifierImplFactory,
CallerInfoAsyncQueryFactory callerInfoAsyncQueryFactory,
HeadsetMediaButtonFactory headsetMediaButtonFactory,
ProximitySensorManagerFactory proximitySensorManagerFactory,
InCallWakeLockControllerFactory inCallWakeLockControllerFactory,
AudioServiceFactory audioServiceFactory,
BluetoothPhoneServiceImplFactory
bluetoothPhoneServiceImplFactory,
Timeouts.Adapter timeoutsAdapter,
AsyncRingtonePlayer asyncRingtonePlayer,
PhoneNumberUtilsAdapter phoneNumberUtilsAdapter) {
mContext = context.getApplicationContext();
Log.setContext(mContext);
Log.initMd5Sum();
Log.startSession("TS.init");
mPhoneAccountRegistrar = new PhoneAccountRegistrar(mContext);
mContactsAsyncHelper = new ContactsAsyncHelper(
new ContactsAsyncHelper.ContentResolverAdapter() {
@Override
public InputStream openInputStream(Context context, Uri uri)
throws FileNotFoundException {
return context.getContentResolver().openInputStream(uri);
}
});
BluetoothManager bluetoothManager = new BluetoothManager(mContext,
new BluetoothAdapterProxy());
WiredHeadsetManager wiredHeadsetManager = new WiredHeadsetManager(mContext);
SystemStateProvider systemStateProvider = new SystemStateProvider(mContext);
mMissedCallNotifier = missedCallNotifierImplFactory
.makeMissedCallNotifierImpl(mContext, mPhoneAccountRegistrar,
phoneNumberUtilsAdapter);
DefaultDialerManagerAdapter defaultDialerAdapter =
new TelecomServiceImpl.DefaultDialerManagerAdapterImpl();
mCallsManager = new CallsManager(
mContext,
mLock,
mContactsAsyncHelper,
callerInfoAsyncQueryFactory,
mMissedCallNotifier,
mPhoneAccountRegistrar,
headsetMediaButtonFactory,
proximitySensorManagerFactory,
inCallWakeLockControllerFactory,
audioServiceFactory,
bluetoothManager,
wiredHeadsetManager,
systemStateProvider,
defaultDialerAdapter,
timeoutsAdapter,
asyncRingtonePlayer,
phoneNumberUtilsAdapter);
mRespondViaSmsManager = new RespondViaSmsManager(mCallsManager, mLock);
mCallsManager.setRespondViaSmsManager(mRespondViaSmsManager);
mContext.registerReceiver(mUserSwitchedReceiver, USER_SWITCHED_FILTER);
mContext.registerReceiver(mUserStartingReceiver, USER_STARTING_FILTER);
mBluetoothPhoneServiceImpl = bluetoothPhoneServiceImplFactory.makeBluetoothPhoneServiceImpl(
mContext, mLock, mCallsManager, mPhoneAccountRegistrar);
mCallIntentProcessor = new CallIntentProcessor(mContext, mCallsManager);
mTelecomBroadcastIntentProcessor = new TelecomBroadcastIntentProcessor(
mContext, mCallsManager);
// Register the receiver for the dialer secret codes, used to enable extended logging.
mDialerCodeReceiver = new DialerCodeReceiver(mCallsManager);
mContext.registerReceiver(mDialerCodeReceiver, DIALER_SECRET_CODE_FILTER,
Manifest.permission.CONTROL_INCALL_EXPERIENCE, null);
mTelecomServiceImpl = new TelecomServiceImpl(
mContext, mCallsManager, mPhoneAccountRegistrar,
new CallIntentProcessor.AdapterImpl(),
new UserCallIntentProcessorFactory() {
@Override
public UserCallIntentProcessor create(Context context, UserHandle userHandle) {
return new UserCallIntentProcessor(context, userHandle);
}
},
defaultDialerAdapter,
new TelecomServiceImpl.SubscriptionManagerAdapterImpl(),
mLock);
Log.endSession();
}
@VisibleForTesting
public PhoneAccountRegistrar getPhoneAccountRegistrar() {
return mPhoneAccountRegistrar;
}
@VisibleForTesting
public CallsManager getCallsManager() {
return mCallsManager;
}
public BluetoothPhoneServiceImpl getBluetoothPhoneServiceImpl() {
return mBluetoothPhoneServiceImpl;
}
public CallIntentProcessor getCallIntentProcessor() {
return mCallIntentProcessor;
}
public TelecomBroadcastIntentProcessor getTelecomBroadcastIntentProcessor() {
return mTelecomBroadcastIntentProcessor;
}
public TelecomServiceImpl getTelecomServiceImpl() {
return mTelecomServiceImpl;
}
public Object getLock() {
return mLock;
}
}