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