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