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