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.components; 18 19 import android.app.Service; 20 import android.app.role.RoleManager; 21 import android.bluetooth.BluetoothAdapter; 22 import android.content.Context; 23 import android.content.Intent; 24 import android.media.IAudioService; 25 import android.media.ToneGenerator; 26 import android.os.IBinder; 27 import android.os.PowerManager; 28 import android.os.ServiceManager; 29 import android.os.SystemClock; 30 import android.telecom.Log; 31 32 import android.telecom.CallerInfoAsyncQuery; 33 import com.android.server.telecom.AsyncRingtonePlayer; 34 import com.android.server.telecom.BluetoothAdapterProxy; 35 import com.android.server.telecom.BluetoothPhoneServiceImpl; 36 import com.android.server.telecom.CallAudioModeStateMachine; 37 import com.android.server.telecom.CallAudioRouteStateMachine; 38 import com.android.server.telecom.CallerInfoAsyncQueryFactory; 39 import com.android.server.telecom.CallsManager; 40 import com.android.server.telecom.ClockProxy; 41 import com.android.server.telecom.ConnectionServiceFocusManager; 42 import com.android.server.telecom.ContactsAsyncHelper; 43 import com.android.server.telecom.DefaultDialerCache; 44 import com.android.server.telecom.HeadsetMediaButton; 45 import com.android.server.telecom.HeadsetMediaButtonFactory; 46 import com.android.server.telecom.InCallWakeLockControllerFactory; 47 import com.android.server.telecom.CallAudioManager; 48 import com.android.server.telecom.PhoneAccountRegistrar; 49 import com.android.server.telecom.PhoneNumberUtilsAdapterImpl; 50 import com.android.server.telecom.ProximitySensorManagerFactory; 51 import com.android.server.telecom.InCallWakeLockController; 52 import com.android.server.telecom.ProximitySensorManager; 53 import com.android.server.telecom.R; 54 import com.android.server.telecom.RoleManagerAdapterImpl; 55 import com.android.server.telecom.TelecomSystem; 56 import com.android.server.telecom.TelecomWakeLock; 57 import com.android.server.telecom.Timeouts; 58 import com.android.server.telecom.callfiltering.IncomingCallFilter; 59 import com.android.server.telecom.ui.IncomingCallNotifier; 60 import com.android.server.telecom.ui.MissedCallNotifierImpl; 61 import com.android.server.telecom.ui.NotificationChannelManager; 62 63 /** 64 * Implementation of the ITelecom interface. 65 */ 66 public class TelecomService extends Service implements TelecomSystem.Component { 67 68 @Override onBind(Intent intent)69 public IBinder onBind(Intent intent) { 70 Log.d(this, "onBind"); 71 initializeTelecomSystem(this); 72 synchronized (getTelecomSystem().getLock()) { 73 return getTelecomSystem().getTelecomServiceImpl().getBinder(); 74 } 75 } 76 77 /** 78 * This method is to be called by components (Activitys, Services, ...) to initialize the 79 * Telecom singleton. It should only be called on the main thread. As such, it is atomic 80 * and needs no synchronization -- it will either perform its initialization, after which 81 * the {@link TelecomSystem#getInstance()} will be initialized, or some other invocation of 82 * this method on the main thread will have happened strictly prior to it, and this method 83 * will be a benign no-op. 84 * 85 * @param context 86 */ initializeTelecomSystem(Context context)87 static void initializeTelecomSystem(Context context) { 88 if (TelecomSystem.getInstance() == null) { 89 NotificationChannelManager notificationChannelManager = 90 new NotificationChannelManager(); 91 notificationChannelManager.createChannels(context); 92 93 TelecomSystem.setInstance( 94 new TelecomSystem( 95 context, 96 new MissedCallNotifierImpl.MissedCallNotifierImplFactory() { 97 @Override 98 public MissedCallNotifierImpl makeMissedCallNotifierImpl( 99 Context context, 100 PhoneAccountRegistrar phoneAccountRegistrar, 101 DefaultDialerCache defaultDialerCache) { 102 return new MissedCallNotifierImpl(context, 103 phoneAccountRegistrar, defaultDialerCache); 104 } 105 }, 106 new CallerInfoAsyncQueryFactory() { 107 @Override 108 public CallerInfoAsyncQuery startQuery( 109 int token, 110 Context context, 111 String number, 112 CallerInfoAsyncQuery.OnQueryCompleteListener listener, 113 Object cookie) { 114 Log.i(TelecomSystem.getInstance(), 115 "CallerInfoAsyncQuery.startQuery number=%s cookie=%s", 116 Log.pii(number), cookie); 117 return CallerInfoAsyncQuery.startQuery( 118 token, context, number, listener, cookie); 119 } 120 }, 121 new HeadsetMediaButtonFactory() { 122 @Override 123 public HeadsetMediaButton create( 124 Context context, 125 CallsManager callsManager, 126 TelecomSystem.SyncRoot lock) { 127 return new HeadsetMediaButton(context, callsManager, lock); 128 } 129 }, 130 new ProximitySensorManagerFactory() { 131 @Override 132 public ProximitySensorManager create( 133 Context context, 134 CallsManager callsManager) { 135 return new ProximitySensorManager( 136 new TelecomWakeLock( 137 context, 138 PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, 139 ProximitySensorManager.class.getSimpleName()), 140 callsManager); 141 } 142 }, 143 new InCallWakeLockControllerFactory() { 144 @Override 145 public InCallWakeLockController create(Context context, 146 CallsManager callsManager) { 147 return new InCallWakeLockController( 148 new TelecomWakeLock(context, 149 PowerManager.FULL_WAKE_LOCK, 150 InCallWakeLockController.class.getSimpleName()), 151 callsManager); 152 } 153 }, 154 new CallAudioManager.AudioServiceFactory() { 155 @Override 156 public IAudioService getAudioService() { 157 return IAudioService.Stub.asInterface( 158 ServiceManager.getService(Context.AUDIO_SERVICE)); 159 } 160 }, 161 new BluetoothPhoneServiceImpl.BluetoothPhoneServiceImplFactory() { 162 @Override 163 public BluetoothPhoneServiceImpl makeBluetoothPhoneServiceImpl( 164 Context context, TelecomSystem.SyncRoot lock, 165 CallsManager callsManager, 166 PhoneAccountRegistrar phoneAccountRegistrar) { 167 return new BluetoothPhoneServiceImpl(context, lock, 168 callsManager, new BluetoothAdapterProxy(), 169 phoneAccountRegistrar); 170 } 171 }, 172 ConnectionServiceFocusManager::new, 173 new Timeouts.Adapter(), 174 new AsyncRingtonePlayer(), 175 new PhoneNumberUtilsAdapterImpl(), 176 new IncomingCallNotifier(context), 177 ToneGenerator::new, 178 new CallAudioRouteStateMachine.Factory(), 179 new CallAudioModeStateMachine.Factory(), 180 new ClockProxy() { 181 @Override 182 public long currentTimeMillis() { 183 return System.currentTimeMillis(); 184 } 185 186 @Override 187 public long elapsedRealtime() { 188 return SystemClock.elapsedRealtime(); 189 } 190 }, 191 new RoleManagerAdapterImpl(context, 192 (RoleManager) context.getSystemService(Context.ROLE_SERVICE)), 193 new IncomingCallFilter.Factory(), 194 new ContactsAsyncHelper.Factory())); 195 } 196 if (BluetoothAdapter.getDefaultAdapter() != null) { 197 context.startService(new Intent(context, BluetoothPhoneService.class)); 198 } 199 } 200 201 @Override getTelecomSystem()202 public TelecomSystem getTelecomSystem() { 203 return TelecomSystem.getInstance(); 204 } 205 } 206