Home | History | Annotate | Download | only in telecom
      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 
     17 package com.android.server.telecom;
     18 
     19 import com.android.internal.annotations.VisibleForTesting;
     20 import com.android.server.telecom.bluetooth.BluetoothDeviceManager;
     21 import com.android.server.telecom.bluetooth.BluetoothRouteManager;
     22 import com.android.server.telecom.components.UserCallIntentProcessor;
     23 import com.android.server.telecom.components.UserCallIntentProcessorFactory;
     24 import com.android.server.telecom.ui.IncomingCallNotifier;
     25 import com.android.server.telecom.ui.IncomingCallNotifier.IncomingCallNotifierFactory;
     26 import com.android.server.telecom.ui.MissedCallNotifierImpl.MissedCallNotifierImplFactory;
     27 import com.android.server.telecom.BluetoothPhoneServiceImpl.BluetoothPhoneServiceImplFactory;
     28 import com.android.server.telecom.CallAudioManager.AudioServiceFactory;
     29 import com.android.server.telecom.DefaultDialerCache.DefaultDialerManagerAdapter;
     30 
     31 import android.Manifest;
     32 import android.content.BroadcastReceiver;
     33 import android.content.Context;
     34 import android.content.Intent;
     35 import android.content.IntentFilter;
     36 import android.content.pm.ApplicationInfo;
     37 import android.content.pm.PackageManager;
     38 import android.net.Uri;
     39 import android.os.UserHandle;
     40 import android.telecom.Log;
     41 import android.telecom.PhoneAccountHandle;
     42 
     43 import java.io.FileNotFoundException;
     44 import java.io.InputStream;
     45 
     46 /**
     47  * Top-level Application class for Telecom.
     48  */
     49 public class TelecomSystem {
     50 
     51     /**
     52      * This interface is implemented by system-instantiated components (e.g., Services and
     53      * Activity-s) that wish to use the TelecomSystem but would like to be testable. Such a
     54      * component should implement the getTelecomSystem() method to return the global singleton,
     55      * and use its own method. Tests can subclass the component to return a non-singleton.
     56      *
     57      * A refactoring goal for Telecom is to limit use of the TelecomSystem singleton to those
     58      * system-instantiated components, and have all other parts of the system just take all their
     59      * dependencies as explicit arguments to their constructor or other methods.
     60      */
     61     public interface Component {
     62         TelecomSystem getTelecomSystem();
     63     }
     64 
     65 
     66     /**
     67      * Tagging interface for the object used for synchronizing multi-threaded operations in
     68      * the Telecom system.
     69      */
     70     public interface SyncRoot {
     71     }
     72 
     73     private static final IntentFilter USER_SWITCHED_FILTER =
     74             new IntentFilter(Intent.ACTION_USER_SWITCHED);
     75 
     76     private static final IntentFilter USER_STARTING_FILTER =
     77             new IntentFilter(Intent.ACTION_USER_STARTING);
     78 
     79     private static final IntentFilter BOOT_COMPLETE_FILTER =
     80             new IntentFilter(Intent.ACTION_BOOT_COMPLETED);
     81 
     82     /** Intent filter for dialer secret codes. */
     83     private static final IntentFilter DIALER_SECRET_CODE_FILTER;
     84 
     85     /**
     86      * Initializes the dialer secret code intent filter.  Setup to handle the various secret codes
     87      * which can be dialed (e.g. in format *#*#code#*#*) to trigger various behavior in Telecom.
     88      */
     89     static {
     90         DIALER_SECRET_CODE_FILTER = new IntentFilter(
     91                 "android.provider.Telephony.SECRET_CODE");
     92         DIALER_SECRET_CODE_FILTER.addDataScheme("android_secret_code");
     93         DIALER_SECRET_CODE_FILTER
     94                 .addDataAuthority(DialerCodeReceiver.TELECOM_SECRET_CODE_DEBUG_ON, null);
     95         DIALER_SECRET_CODE_FILTER
     96                 .addDataAuthority(DialerCodeReceiver.TELECOM_SECRET_CODE_DEBUG_OFF, null);
     97         DIALER_SECRET_CODE_FILTER
     98                 .addDataAuthority(DialerCodeReceiver.TELECOM_SECRET_CODE_MARK, null);
     99     }
    100 
    101     private static TelecomSystem INSTANCE = null;
    102 
    103     private final SyncRoot mLock = new SyncRoot() { };
    104     private final MissedCallNotifier mMissedCallNotifier;
    105     private final IncomingCallNotifier mIncomingCallNotifier;
    106     private final PhoneAccountRegistrar mPhoneAccountRegistrar;
    107     private final CallsManager mCallsManager;
    108     private final RespondViaSmsManager mRespondViaSmsManager;
    109     private final Context mContext;
    110     private final BluetoothPhoneServiceImpl mBluetoothPhoneServiceImpl;
    111     private final CallIntentProcessor mCallIntentProcessor;
    112     private final TelecomBroadcastIntentProcessor mTelecomBroadcastIntentProcessor;
    113     private final TelecomServiceImpl mTelecomServiceImpl;
    114     private final ContactsAsyncHelper mContactsAsyncHelper;
    115     private final DialerCodeReceiver mDialerCodeReceiver;
    116 
    117     private boolean mIsBootComplete = false;
    118 
    119     private final BroadcastReceiver mUserSwitchedReceiver = new BroadcastReceiver() {
    120         @Override
    121         public void onReceive(Context context, Intent intent) {
    122             Log.startSession("TSSwR.oR");
    123             try {
    124                 synchronized (mLock) {
    125                     int userHandleId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
    126                     UserHandle currentUserHandle = new UserHandle(userHandleId);
    127                     mPhoneAccountRegistrar.setCurrentUserHandle(currentUserHandle);
    128                     mCallsManager.onUserSwitch(currentUserHandle);
    129                 }
    130             } finally {
    131                 Log.endSession();
    132             }
    133         }
    134     };
    135 
    136     private final BroadcastReceiver mUserStartingReceiver = new BroadcastReceiver() {
    137         @Override
    138         public void onReceive(Context context, Intent intent) {
    139             Log.startSession("TSStR.oR");
    140             try {
    141                 synchronized (mLock) {
    142                     int userHandleId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
    143                     UserHandle addingUserHandle = new UserHandle(userHandleId);
    144                     mCallsManager.onUserStarting(addingUserHandle);
    145                 }
    146             } finally {
    147                 Log.endSession();
    148             }
    149         }
    150     };
    151 
    152     private final BroadcastReceiver mBootCompletedReceiver = new BroadcastReceiver() {
    153         @Override
    154         public void onReceive(Context context, Intent intent) {
    155             Log.startSession("TSBCR.oR");
    156             try {
    157                 synchronized (mLock) {
    158                     mIsBootComplete = true;
    159                     mCallsManager.onBootCompleted();
    160                 }
    161             } finally {
    162                 Log.endSession();
    163             }
    164         }
    165     };
    166 
    167     public static TelecomSystem getInstance() {
    168         return INSTANCE;
    169     }
    170 
    171     public static void setInstance(TelecomSystem instance) {
    172         if (INSTANCE != null) {
    173             Log.w("TelecomSystem", "Attempt to set TelecomSystem.INSTANCE twice");
    174         }
    175         Log.i(TelecomSystem.class, "TelecomSystem.INSTANCE being set");
    176         INSTANCE = instance;
    177     }
    178 
    179     public TelecomSystem(
    180             Context context,
    181             MissedCallNotifierImplFactory missedCallNotifierImplFactory,
    182             CallerInfoAsyncQueryFactory callerInfoAsyncQueryFactory,
    183             HeadsetMediaButtonFactory headsetMediaButtonFactory,
    184             ProximitySensorManagerFactory proximitySensorManagerFactory,
    185             InCallWakeLockControllerFactory inCallWakeLockControllerFactory,
    186             AudioServiceFactory audioServiceFactory,
    187             BluetoothPhoneServiceImplFactory
    188                     bluetoothPhoneServiceImplFactory,
    189             Timeouts.Adapter timeoutsAdapter,
    190             AsyncRingtonePlayer asyncRingtonePlayer,
    191             PhoneNumberUtilsAdapter phoneNumberUtilsAdapter,
    192             IncomingCallNotifier incomingCallNotifier) {
    193         mContext = context.getApplicationContext();
    194         LogUtils.initLogging(mContext);
    195         DefaultDialerManagerAdapter defaultDialerAdapter =
    196                 new DefaultDialerCache.DefaultDialerManagerAdapterImpl();
    197 
    198         DefaultDialerCache defaultDialerCache = new DefaultDialerCache(mContext,
    199                 defaultDialerAdapter, mLock);
    200 
    201         Log.startSession("TS.init");
    202         mPhoneAccountRegistrar = new PhoneAccountRegistrar(mContext, defaultDialerCache,
    203                 new PhoneAccountRegistrar.AppLabelProxy() {
    204                     @Override
    205                     public CharSequence getAppLabel(String packageName) {
    206                         PackageManager pm = mContext.getPackageManager();
    207                         try {
    208                             ApplicationInfo info = pm.getApplicationInfo(packageName, 0);
    209                             return pm.getApplicationLabel(info);
    210                         } catch (PackageManager.NameNotFoundException nnfe) {
    211                             Log.w(this, "Could not determine package name.");
    212                         }
    213 
    214                         return null;
    215                     }
    216                 });
    217         mContactsAsyncHelper = new ContactsAsyncHelper(
    218                 new ContactsAsyncHelper.ContentResolverAdapter() {
    219                     @Override
    220                     public InputStream openInputStream(Context context, Uri uri)
    221                             throws FileNotFoundException {
    222                         return context.getContentResolver().openInputStream(uri);
    223                     }
    224                 });
    225         BluetoothDeviceManager bluetoothDeviceManager = new BluetoothDeviceManager(mContext,
    226                 new BluetoothAdapterProxy(), mLock);
    227         BluetoothRouteManager bluetoothRouteManager = new BluetoothRouteManager(mContext, mLock,
    228                 bluetoothDeviceManager, new Timeouts.Adapter());
    229         WiredHeadsetManager wiredHeadsetManager = new WiredHeadsetManager(mContext);
    230         SystemStateProvider systemStateProvider = new SystemStateProvider(mContext);
    231 
    232         mMissedCallNotifier = missedCallNotifierImplFactory
    233                 .makeMissedCallNotifierImpl(mContext, mPhoneAccountRegistrar, defaultDialerCache);
    234 
    235         EmergencyCallHelper emergencyCallHelper = new EmergencyCallHelper(mContext,
    236                 mContext.getResources().getString(R.string.ui_default_package), timeoutsAdapter);
    237 
    238         mCallsManager = new CallsManager(
    239                 mContext,
    240                 mLock,
    241                 mContactsAsyncHelper,
    242                 callerInfoAsyncQueryFactory,
    243                 mMissedCallNotifier,
    244                 mPhoneAccountRegistrar,
    245                 headsetMediaButtonFactory,
    246                 proximitySensorManagerFactory,
    247                 inCallWakeLockControllerFactory,
    248                 audioServiceFactory,
    249                 bluetoothRouteManager,
    250                 wiredHeadsetManager,
    251                 systemStateProvider,
    252                 defaultDialerCache,
    253                 timeoutsAdapter,
    254                 asyncRingtonePlayer,
    255                 phoneNumberUtilsAdapter,
    256                 emergencyCallHelper);
    257 
    258         mIncomingCallNotifier = incomingCallNotifier;
    259         incomingCallNotifier.setCallsManagerProxy(new IncomingCallNotifier.CallsManagerProxy() {
    260             @Override
    261             public boolean hasCallsForOtherPhoneAccount(PhoneAccountHandle phoneAccountHandle) {
    262                 return mCallsManager.hasCallsForOtherPhoneAccount(phoneAccountHandle);
    263             }
    264 
    265             @Override
    266             public int getNumCallsForOtherPhoneAccount(PhoneAccountHandle phoneAccountHandle) {
    267                 return mCallsManager.getNumCallsForOtherPhoneAccount(phoneAccountHandle);
    268             }
    269 
    270             @Override
    271             public Call getActiveCall() {
    272                 return mCallsManager.getActiveCall();
    273             }
    274         });
    275         mCallsManager.setIncomingCallNotifier(mIncomingCallNotifier);
    276 
    277         mRespondViaSmsManager = new RespondViaSmsManager(mCallsManager, mLock);
    278         mCallsManager.setRespondViaSmsManager(mRespondViaSmsManager);
    279 
    280         mContext.registerReceiver(mUserSwitchedReceiver, USER_SWITCHED_FILTER);
    281         mContext.registerReceiver(mUserStartingReceiver, USER_STARTING_FILTER);
    282         mContext.registerReceiver(mBootCompletedReceiver, BOOT_COMPLETE_FILTER);
    283 
    284         mBluetoothPhoneServiceImpl = bluetoothPhoneServiceImplFactory.makeBluetoothPhoneServiceImpl(
    285                 mContext, mLock, mCallsManager, mPhoneAccountRegistrar);
    286         mCallIntentProcessor = new CallIntentProcessor(mContext, mCallsManager);
    287         mTelecomBroadcastIntentProcessor = new TelecomBroadcastIntentProcessor(
    288                 mContext, mCallsManager);
    289 
    290         // Register the receiver for the dialer secret codes, used to enable extended logging.
    291         mDialerCodeReceiver = new DialerCodeReceiver(mCallsManager);
    292         mContext.registerReceiver(mDialerCodeReceiver, DIALER_SECRET_CODE_FILTER,
    293                 Manifest.permission.CONTROL_INCALL_EXPERIENCE, null);
    294 
    295         mTelecomServiceImpl = new TelecomServiceImpl(
    296                 mContext, mCallsManager, mPhoneAccountRegistrar,
    297                 new CallIntentProcessor.AdapterImpl(),
    298                 new UserCallIntentProcessorFactory() {
    299                     @Override
    300                     public UserCallIntentProcessor create(Context context, UserHandle userHandle) {
    301                         return new UserCallIntentProcessor(context, userHandle);
    302                     }
    303                 },
    304                 defaultDialerCache,
    305                 new TelecomServiceImpl.SubscriptionManagerAdapterImpl(),
    306                 mLock);
    307         Log.endSession();
    308     }
    309 
    310     @VisibleForTesting
    311     public PhoneAccountRegistrar getPhoneAccountRegistrar() {
    312         return mPhoneAccountRegistrar;
    313     }
    314 
    315     @VisibleForTesting
    316     public CallsManager getCallsManager() {
    317         return mCallsManager;
    318     }
    319 
    320     public BluetoothPhoneServiceImpl getBluetoothPhoneServiceImpl() {
    321         return mBluetoothPhoneServiceImpl;
    322     }
    323 
    324     public CallIntentProcessor getCallIntentProcessor() {
    325         return mCallIntentProcessor;
    326     }
    327 
    328     public TelecomBroadcastIntentProcessor getTelecomBroadcastIntentProcessor() {
    329         return mTelecomBroadcastIntentProcessor;
    330     }
    331 
    332     public TelecomServiceImpl getTelecomServiceImpl() {
    333         return mTelecomServiceImpl;
    334     }
    335 
    336     public Object getLock() {
    337         return mLock;
    338     }
    339 
    340     public boolean isBootComplete() {
    341         return mIsBootComplete;
    342     }
    343 }
    344