1 /*
2  * Copyright (C) 2020 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 android.app;
18 
19 import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
20 import static android.os.UserHandle.getCallingUserId;
21 
22 import android.annotation.Nullable;
23 import android.annotation.RequiresPermission;
24 import android.content.ComponentName;
25 import android.content.ContentProvider;
26 import android.content.Intent;
27 import android.content.res.Configuration;
28 import android.content.res.Resources;
29 import android.net.Uri;
30 import android.os.Bundle;
31 import android.os.IBinder;
32 import android.os.IRemoteCallback;
33 import android.os.PersistableBundle;
34 import android.os.RemoteException;
35 import android.util.Singleton;
36 import android.view.RemoteAnimationDefinition;
37 import android.window.SizeConfigurationBuckets;
38 
39 import com.android.internal.policy.IKeyguardDismissCallback;
40 
41 /**
42  * Provides the activity associated operations that communicate with system.
43  *
44  * @hide
45  */
46 public class ActivityClient {
ActivityClient()47     private ActivityClient() {}
48 
49     /** Reports the main thread is idle after the activity is resumed. */
activityIdle(IBinder token, Configuration config, boolean stopProfiling)50     public void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
51         try {
52             getActivityClientController().activityIdle(token, config, stopProfiling);
53         } catch (RemoteException e) {
54             e.rethrowFromSystemServer();
55         }
56     }
57 
58     /** Reports {@link Activity#onResume()} is done. */
activityResumed(IBinder token, boolean handleSplashScreenExit)59     public void activityResumed(IBinder token, boolean handleSplashScreenExit) {
60         try {
61             getActivityClientController().activityResumed(token, handleSplashScreenExit);
62         } catch (RemoteException e) {
63             e.rethrowFromSystemServer();
64         }
65     }
66 
67     /** Reports {@link android.app.servertransaction.RefreshCallbackItem} is executed. */
activityRefreshed(IBinder token)68     public void activityRefreshed(IBinder token) {
69         try {
70             getActivityClientController().activityRefreshed(token);
71         } catch (RemoteException e) {
72             e.rethrowFromSystemServer();
73         }
74     }
75 
76     /**
77      * Reports after {@link Activity#onTopResumedActivityChanged(boolean)} is called for losing the
78      * top most position.
79      */
activityTopResumedStateLost()80     public void activityTopResumedStateLost() {
81         try {
82             getActivityClientController().activityTopResumedStateLost();
83         } catch (RemoteException e) {
84             e.rethrowFromSystemServer();
85         }
86     }
87 
88     /** Reports {@link Activity#onPause()} is done. */
activityPaused(IBinder token)89     public void activityPaused(IBinder token) {
90         try {
91             getActivityClientController().activityPaused(token);
92         } catch (RemoteException e) {
93             e.rethrowFromSystemServer();
94         }
95     }
96 
97     /** Reports {@link Activity#onStop()} is done. */
activityStopped(IBinder token, Bundle state, PersistableBundle persistentState, CharSequence description)98     public void activityStopped(IBinder token, Bundle state, PersistableBundle persistentState,
99             CharSequence description) {
100         try {
101             getActivityClientController().activityStopped(token, state, persistentState,
102                     description);
103         } catch (RemoteException e) {
104             e.rethrowFromSystemServer();
105         }
106     }
107 
108     /** Reports {@link Activity#onDestroy()} is done. */
activityDestroyed(IBinder token)109     public void activityDestroyed(IBinder token) {
110         try {
111             getActivityClientController().activityDestroyed(token);
112         } catch (RemoteException e) {
113             e.rethrowFromSystemServer();
114         }
115     }
116 
117     /** Reports the activity starts local relaunch. */
activityLocalRelaunch(IBinder token)118     public void activityLocalRelaunch(IBinder token) {
119         try {
120             getActivityClientController().activityLocalRelaunch(token);
121         } catch (RemoteException e) {
122             e.rethrowFromSystemServer();
123         }
124     }
125 
126     /** Reports the activity has completed relaunched. */
activityRelaunched(IBinder token)127     public void activityRelaunched(IBinder token) {
128         try {
129             getActivityClientController().activityRelaunched(token);
130         } catch (RemoteException e) {
131             e.rethrowFromSystemServer();
132         }
133     }
134 
reportSizeConfigurations(IBinder token, SizeConfigurationBuckets sizeConfigurations)135     void reportSizeConfigurations(IBinder token, SizeConfigurationBuckets sizeConfigurations) {
136         try {
137             getActivityClientController().reportSizeConfigurations(token, sizeConfigurations);
138         } catch (RemoteException e) {
139             e.rethrowFromSystemServer();
140         }
141     }
142 
moveActivityTaskToBack(IBinder token, boolean nonRoot)143     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
144         try {
145             return getActivityClientController().moveActivityTaskToBack(token, nonRoot);
146         } catch (RemoteException e) {
147             throw e.rethrowFromSystemServer();
148         }
149     }
150 
shouldUpRecreateTask(IBinder token, String destAffinity)151     boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
152         try {
153             return getActivityClientController().shouldUpRecreateTask(token, destAffinity);
154         } catch (RemoteException e) {
155             throw e.rethrowFromSystemServer();
156         }
157     }
158 
navigateUpTo(IBinder token, Intent destIntent, String resolvedType, int resultCode, Intent resultData)159     boolean navigateUpTo(IBinder token, Intent destIntent, String resolvedType, int resultCode,
160             Intent resultData) {
161         try {
162             return getActivityClientController().navigateUpTo(token, destIntent, resolvedType,
163                     resultCode, resultData);
164         } catch (RemoteException e) {
165             throw e.rethrowFromSystemServer();
166         }
167     }
168 
releaseActivityInstance(IBinder token)169     boolean releaseActivityInstance(IBinder token) {
170         try {
171             return getActivityClientController().releaseActivityInstance(token);
172         } catch (RemoteException e) {
173             throw e.rethrowFromSystemServer();
174         }
175     }
176 
finishActivity(IBinder token, int resultCode, Intent resultData, int finishTask)177     public boolean finishActivity(IBinder token, int resultCode, Intent resultData,
178             int finishTask) {
179         try {
180             return getActivityClientController().finishActivity(token, resultCode, resultData,
181                     finishTask);
182         } catch (RemoteException e) {
183             throw e.rethrowFromSystemServer();
184         }
185     }
186 
finishActivityAffinity(IBinder token)187     boolean finishActivityAffinity(IBinder token) {
188         try {
189             return getActivityClientController().finishActivityAffinity(token);
190         } catch (RemoteException e) {
191             throw e.rethrowFromSystemServer();
192         }
193     }
194 
finishSubActivity(IBinder token, String resultWho, int requestCode)195     void finishSubActivity(IBinder token, String resultWho, int requestCode) {
196         try {
197             getActivityClientController().finishSubActivity(token, resultWho, requestCode);
198         } catch (RemoteException e) {
199             e.rethrowFromSystemServer();
200         }
201     }
202 
203     @RequiresPermission(android.Manifest.permission.MANAGE_MEDIA_PROJECTION)
setForceSendResultForMediaProjection(IBinder token)204     void setForceSendResultForMediaProjection(IBinder token) {
205         try {
206             getActivityClientController().setForceSendResultForMediaProjection(token);
207         } catch (RemoteException e) {
208             throw e.rethrowFromSystemServer();
209         }
210     }
211 
isTopOfTask(IBinder token)212     public boolean isTopOfTask(IBinder token) {
213         try {
214             return getActivityClientController().isTopOfTask(token);
215         } catch (RemoteException e) {
216             throw e.rethrowFromSystemServer();
217         }
218     }
219 
willActivityBeVisible(IBinder token)220     boolean willActivityBeVisible(IBinder token) {
221         try {
222             return getActivityClientController().willActivityBeVisible(token);
223         } catch (RemoteException e) {
224             throw e.rethrowFromSystemServer();
225         }
226     }
227 
getDisplayId(IBinder token)228     public int getDisplayId(IBinder token) {
229         try {
230             return getActivityClientController().getDisplayId(token);
231         } catch (RemoteException e) {
232             throw e.rethrowFromSystemServer();
233         }
234     }
235 
getTaskForActivity(IBinder token, boolean onlyRoot)236     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
237         try {
238             return getActivityClientController().getTaskForActivity(token, onlyRoot);
239         } catch (RemoteException e) {
240             throw e.rethrowFromSystemServer();
241         }
242     }
243 
244     /**
245      * Returns the {@link Configuration} of the task which hosts the Activity, or {@code null} if
246      * the task {@link Configuration} cannot be obtained.
247      */
248     @Nullable
getTaskConfiguration(IBinder activityToken)249     public Configuration getTaskConfiguration(IBinder activityToken) {
250         try {
251             return getActivityClientController().getTaskConfiguration(activityToken);
252         } catch (RemoteException e) {
253             throw e.rethrowFromSystemServer();
254         }
255     }
256 
257     /**
258      * Returns the non-finishing activity token below in the same task if it belongs to the same
259      * process.
260      */
261     @Nullable
getActivityTokenBelow(IBinder activityToken)262     public IBinder getActivityTokenBelow(IBinder activityToken) {
263         try {
264             return getActivityClientController().getActivityTokenBelow(activityToken);
265         } catch (RemoteException e) {
266             throw e.rethrowFromSystemServer();
267         }
268     }
269 
getCallingActivity(IBinder token)270     ComponentName getCallingActivity(IBinder token) {
271         try {
272             return getActivityClientController().getCallingActivity(token);
273         } catch (RemoteException e) {
274             throw e.rethrowFromSystemServer();
275         }
276     }
277 
getCallingPackage(IBinder token)278     String getCallingPackage(IBinder token) {
279         try {
280             return getActivityClientController().getCallingPackage(token);
281         } catch (RemoteException e) {
282             throw e.rethrowFromSystemServer();
283         }
284     }
285 
getLaunchedFromUid(IBinder token)286     public int getLaunchedFromUid(IBinder token) {
287         try {
288             return getActivityClientController().getLaunchedFromUid(token);
289         } catch (RemoteException e) {
290             throw e.rethrowFromSystemServer();
291         }
292     }
293 
getLaunchedFromPackage(IBinder token)294     public String getLaunchedFromPackage(IBinder token) {
295         try {
296             return getActivityClientController().getLaunchedFromPackage(token);
297         } catch (RemoteException e) {
298             throw e.rethrowFromSystemServer();
299         }
300     }
301 
302     /** Returns the uid of the app that launched the activity. */
getActivityCallerUid(IBinder activityToken, IBinder callerToken)303     public int getActivityCallerUid(IBinder activityToken, IBinder callerToken) {
304         try {
305             return getActivityClientController().getActivityCallerUid(activityToken,
306                     callerToken);
307         } catch (RemoteException e) {
308             throw e.rethrowFromSystemServer();
309         }
310     }
311 
312     /** Returns the package of the app that launched the activity. */
getActivityCallerPackage(IBinder activityToken, IBinder callerToken)313     public String getActivityCallerPackage(IBinder activityToken, IBinder callerToken) {
314         try {
315             return getActivityClientController().getActivityCallerPackage(activityToken,
316                     callerToken);
317         } catch (RemoteException e) {
318             throw e.rethrowFromSystemServer();
319         }
320     }
321 
322     /** Checks if the app that launched the activity has access to the URI. */
checkActivityCallerContentUriPermission(IBinder activityToken, IBinder callerToken, Uri uri, int modeFlags)323     public int checkActivityCallerContentUriPermission(IBinder activityToken, IBinder callerToken,
324             Uri uri, int modeFlags) {
325         try {
326             return getActivityClientController().checkActivityCallerContentUriPermission(
327                     activityToken, callerToken, ContentProvider.getUriWithoutUserId(uri), modeFlags,
328                     ContentProvider.getUserIdFromUri(uri, getCallingUserId()));
329         } catch (RemoteException e) {
330             throw e.rethrowFromSystemServer();
331         }
332     }
333 
setRequestedOrientation(IBinder token, int requestedOrientation)334     public void setRequestedOrientation(IBinder token, int requestedOrientation) {
335         try {
336             getActivityClientController().setRequestedOrientation(token, requestedOrientation);
337         } catch (RemoteException e) {
338             e.rethrowFromSystemServer();
339         }
340     }
341 
getRequestedOrientation(IBinder token)342     int getRequestedOrientation(IBinder token) {
343         try {
344             return getActivityClientController().getRequestedOrientation(token);
345         } catch (RemoteException e) {
346             throw e.rethrowFromSystemServer();
347         }
348     }
349 
convertFromTranslucent(IBinder token)350     boolean convertFromTranslucent(IBinder token) {
351         try {
352             return getActivityClientController().convertFromTranslucent(token);
353         } catch (RemoteException e) {
354             throw e.rethrowFromSystemServer();
355         }
356     }
357 
convertToTranslucent(IBinder token, Bundle options)358     boolean convertToTranslucent(IBinder token, Bundle options) {
359         try {
360             return getActivityClientController().convertToTranslucent(token, options);
361         } catch (RemoteException e) {
362             throw e.rethrowFromSystemServer();
363         }
364     }
365 
reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle)366     void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
367         try {
368             getActivityClientController().reportActivityFullyDrawn(token, restoredFromBundle);
369         } catch (RemoteException e) {
370             e.rethrowFromSystemServer();
371         }
372     }
373 
isImmersive(IBinder token)374     boolean isImmersive(IBinder token) {
375         try {
376             return getActivityClientController().isImmersive(token);
377         } catch (RemoteException e) {
378             throw e.rethrowFromSystemServer();
379         }
380     }
381 
setImmersive(IBinder token, boolean immersive)382     void setImmersive(IBinder token, boolean immersive) {
383         try {
384             getActivityClientController().setImmersive(token, immersive);
385         } catch (RemoteException e) {
386             e.rethrowFromSystemServer();
387         }
388     }
389 
enterPictureInPictureMode(IBinder token, PictureInPictureParams params)390     boolean enterPictureInPictureMode(IBinder token, PictureInPictureParams params) {
391         try {
392             return getActivityClientController().enterPictureInPictureMode(token, params);
393         } catch (RemoteException e) {
394             throw e.rethrowFromSystemServer();
395         }
396     }
397 
setPictureInPictureParams(IBinder token, PictureInPictureParams params)398     void setPictureInPictureParams(IBinder token, PictureInPictureParams params) {
399         try {
400             getActivityClientController().setPictureInPictureParams(token, params);
401         } catch (RemoteException e) {
402             e.rethrowFromSystemServer();
403         }
404     }
405 
setShouldDockBigOverlays(IBinder token, boolean shouldDockBigOverlays)406     void setShouldDockBigOverlays(IBinder token, boolean shouldDockBigOverlays) {
407         try {
408             getActivityClientController().setShouldDockBigOverlays(token, shouldDockBigOverlays);
409         } catch (RemoteException e) {
410             e.rethrowFromSystemServer();
411         }
412     }
413 
toggleFreeformWindowingMode(IBinder token)414     void toggleFreeformWindowingMode(IBinder token) {
415         try {
416             getActivityClientController().toggleFreeformWindowingMode(token);
417         } catch (RemoteException e) {
418             e.rethrowFromSystemServer();
419         }
420     }
421 
requestMultiwindowFullscreen(IBinder token, int request, IRemoteCallback callback)422     void requestMultiwindowFullscreen(IBinder token, int request, IRemoteCallback callback) {
423         try {
424             getActivityClientController().requestMultiwindowFullscreen(token, request, callback);
425         } catch (RemoteException e) {
426             e.rethrowFromSystemServer();
427         }
428     }
429 
startLockTaskModeByToken(IBinder token)430     void startLockTaskModeByToken(IBinder token) {
431         try {
432             getActivityClientController().startLockTaskModeByToken(token);
433         } catch (RemoteException e) {
434             e.rethrowFromSystemServer();
435         }
436     }
437 
stopLockTaskModeByToken(IBinder token)438     void stopLockTaskModeByToken(IBinder token) {
439         try {
440             getActivityClientController().stopLockTaskModeByToken(token);
441         } catch (RemoteException e) {
442             e.rethrowFromSystemServer();
443         }
444     }
445 
showLockTaskEscapeMessage(IBinder token)446     void showLockTaskEscapeMessage(IBinder token) {
447         try {
448             getActivityClientController().showLockTaskEscapeMessage(token);
449         } catch (RemoteException e) {
450             e.rethrowFromSystemServer();
451         }
452     }
453 
setTaskDescription(IBinder token, ActivityManager.TaskDescription td)454     void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
455         try {
456             getActivityClientController().setTaskDescription(token, td);
457         } catch (RemoteException e) {
458             e.rethrowFromSystemServer();
459         }
460     }
461 
showAssistFromActivity(IBinder token, Bundle args)462     boolean showAssistFromActivity(IBinder token, Bundle args) {
463         try {
464             return getActivityClientController().showAssistFromActivity(token, args);
465         } catch (RemoteException e) {
466             throw e.rethrowFromSystemServer();
467         }
468     }
469 
isRootVoiceInteraction(IBinder token)470     boolean isRootVoiceInteraction(IBinder token) {
471         try {
472             return getActivityClientController().isRootVoiceInteraction(token);
473         } catch (RemoteException e) {
474             throw e.rethrowFromSystemServer();
475         }
476     }
477 
startLocalVoiceInteraction(IBinder callingActivity, Bundle options)478     void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) {
479         try {
480             getActivityClientController().startLocalVoiceInteraction(callingActivity, options);
481         } catch (RemoteException e) {
482             e.rethrowFromSystemServer();
483         }
484     }
485 
stopLocalVoiceInteraction(IBinder callingActivity)486     void stopLocalVoiceInteraction(IBinder callingActivity) {
487         try {
488             getActivityClientController().stopLocalVoiceInteraction(callingActivity);
489         } catch (RemoteException e) {
490             e.rethrowFromSystemServer();
491         }
492     }
493 
setShowWhenLocked(IBinder token, boolean showWhenLocked)494     void setShowWhenLocked(IBinder token, boolean showWhenLocked) {
495         try {
496             getActivityClientController().setShowWhenLocked(token, showWhenLocked);
497         } catch (RemoteException e) {
498             e.rethrowFromSystemServer();
499         }
500     }
501 
setInheritShowWhenLocked(IBinder token, boolean inheritShowWhenLocked)502     void setInheritShowWhenLocked(IBinder token, boolean inheritShowWhenLocked) {
503         try {
504             getActivityClientController().setInheritShowWhenLocked(token, inheritShowWhenLocked);
505         } catch (RemoteException e) {
506             e.rethrowFromSystemServer();
507         }
508     }
509 
setTurnScreenOn(IBinder token, boolean turnScreenOn)510     void setTurnScreenOn(IBinder token, boolean turnScreenOn) {
511         try {
512             getActivityClientController().setTurnScreenOn(token, turnScreenOn);
513         } catch (RemoteException e) {
514             e.rethrowFromSystemServer();
515         }
516     }
517 
setAllowCrossUidActivitySwitchFromBelow(IBinder token, boolean allowed)518     void setAllowCrossUidActivitySwitchFromBelow(IBinder token, boolean allowed) {
519         try {
520             getActivityClientController().setAllowCrossUidActivitySwitchFromBelow(token, allowed);
521         } catch (RemoteException e) {
522             e.rethrowFromSystemServer();
523         }
524     }
525 
setVrMode(IBinder token, boolean enabled, ComponentName packageName)526     int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
527         try {
528             return getActivityClientController().setVrMode(token, enabled, packageName);
529         } catch (RemoteException e) {
530             throw e.rethrowFromSystemServer();
531         }
532     }
533 
overrideActivityTransition(IBinder token, boolean open, int enterAnim, int exitAnim, int backgroundColor)534     void overrideActivityTransition(IBinder token, boolean open, int enterAnim, int exitAnim,
535             int backgroundColor) {
536         try {
537             getActivityClientController().overrideActivityTransition(
538                     token, open, enterAnim, exitAnim, backgroundColor);
539         } catch (RemoteException e) {
540             e.rethrowFromSystemServer();
541         }
542     }
543 
clearOverrideActivityTransition(IBinder token, boolean open)544     void clearOverrideActivityTransition(IBinder token, boolean open) {
545         try {
546             getActivityClientController().clearOverrideActivityTransition(token, open);
547         } catch (RemoteException e) {
548             e.rethrowFromSystemServer();
549         }
550     }
551 
overridePendingTransition(IBinder token, String packageName, int enterAnim, int exitAnim, int backgroundColor)552     void overridePendingTransition(IBinder token, String packageName, int enterAnim, int exitAnim,
553             int backgroundColor) {
554         try {
555             getActivityClientController().overridePendingTransition(token, packageName,
556                     enterAnim, exitAnim, backgroundColor);
557         } catch (RemoteException e) {
558             e.rethrowFromSystemServer();
559         }
560     }
561 
setRecentsScreenshotEnabled(IBinder token, boolean enabled)562     void setRecentsScreenshotEnabled(IBinder token, boolean enabled) {
563         try {
564             getActivityClientController().setRecentsScreenshotEnabled(token, enabled);
565         } catch (RemoteException e) {
566             e.rethrowFromSystemServer();
567         }
568     }
569 
570     /**
571      * Removes the outdated snapshot of the home task.
572      *
573      * @param homeToken The token of the home task, or null if you have the
574      *                  {@link android.Manifest.permission#MANAGE_ACTIVITY_TASKS} permission and
575      *                  want us to find the home task token for you.
576      */
invalidateHomeTaskSnapshot(IBinder homeToken)577     public void invalidateHomeTaskSnapshot(IBinder homeToken) {
578         try {
579             getActivityClientController().invalidateHomeTaskSnapshot(homeToken);
580         } catch (RemoteException e) {
581             e.rethrowFromSystemServer();
582         }
583     }
584 
dismissKeyguard(IBinder token, IKeyguardDismissCallback callback, CharSequence message)585     void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
586             CharSequence message) {
587         try {
588             getActivityClientController().dismissKeyguard(token, callback, message);
589         } catch (RemoteException e) {
590             e.rethrowFromSystemServer();
591         }
592     }
593 
registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition)594     void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition) {
595         try {
596             getActivityClientController().registerRemoteAnimations(token, definition);
597         } catch (RemoteException e) {
598             e.rethrowFromSystemServer();
599         }
600     }
601 
unregisterRemoteAnimations(IBinder token)602     void unregisterRemoteAnimations(IBinder token) {
603         try {
604             getActivityClientController().unregisterRemoteAnimations(token);
605         } catch (RemoteException e) {
606             e.rethrowFromSystemServer();
607         }
608     }
609 
onBackPressed(IBinder token, IRequestFinishCallback callback)610     void onBackPressed(IBinder token, IRequestFinishCallback callback) {
611         try {
612             getActivityClientController().onBackPressed(token, callback);
613         } catch (RemoteException e) {
614             e.rethrowFromSystemServer();
615         }
616     }
617 
618     /**
619      * Reports the splash screen view has attached to client.
620      */
reportSplashScreenAttached(IBinder token)621     void reportSplashScreenAttached(IBinder token) {
622         try {
623             getActivityClientController().splashScreenAttached(token);
624         } catch (RemoteException e) {
625             e.rethrowFromSystemServer();
626         }
627     }
628 
enableTaskLocaleOverride(IBinder token)629     void enableTaskLocaleOverride(IBinder token) {
630         try {
631             getActivityClientController().enableTaskLocaleOverride(token);
632         } catch (RemoteException e) {
633             e.rethrowFromSystemServer();
634         }
635     }
636 
637     /**
638      * Returns {@code true} if the activity was explicitly requested to be launched in the
639      * TaskFragment.
640      *
641      * @param activityToken The token of the Activity.
642      * @param taskFragmentToken The token of the TaskFragment.
643      */
isRequestedToLaunchInTaskFragment(IBinder activityToken, IBinder taskFragmentToken)644     public boolean isRequestedToLaunchInTaskFragment(IBinder activityToken,
645             IBinder taskFragmentToken) {
646         try {
647             return getActivityClientController().isRequestedToLaunchInTaskFragment(activityToken,
648                     taskFragmentToken);
649         } catch (RemoteException e) {
650             throw e.rethrowFromSystemServer();
651         }
652     }
653 
654     @RequiresPermission(INTERNAL_SYSTEM_WINDOW)
setActivityRecordInputSinkEnabled(IBinder activityToken, boolean enabled)655     void setActivityRecordInputSinkEnabled(IBinder activityToken, boolean enabled) {
656         try {
657             getActivityClientController().setActivityRecordInputSinkEnabled(activityToken, enabled);
658         } catch (RemoteException e) {
659             e.rethrowFromSystemServer();
660         }
661     }
662 
663     /**
664      * Shows or hides a Camera app compat toggle for stretched issues with the requested state.
665      *
666      * @param token The token for the window that needs a control.
667      * @param showControl Whether the control should be shown or hidden.
668      * @param transformationApplied Whether the treatment is already applied.
669      * @param callback The callback executed when the user clicks on a control.
670      */
requestCompatCameraControl(Resources res, IBinder token, boolean showControl, boolean transformationApplied, ICompatCameraControlCallback callback)671     void requestCompatCameraControl(Resources res, IBinder token, boolean showControl,
672             boolean transformationApplied, ICompatCameraControlCallback callback) {
673         if (!res.getBoolean(com.android.internal.R.bool
674                 .config_isCameraCompatControlForStretchedIssuesEnabled)) {
675             return;
676         }
677         try {
678             getActivityClientController().requestCompatCameraControl(
679                     token, showControl, transformationApplied, callback);
680         } catch (RemoteException e) {
681             e.rethrowFromSystemServer();
682         }
683     }
684 
getInstance()685     public static ActivityClient getInstance() {
686         return sInstance.get();
687     }
688 
689     /**
690      * If system server has passed the controller interface, store it so the subsequent access can
691      * speed up.
692      */
setActivityClientController( IActivityClientController activityClientController)693     public static IActivityClientController setActivityClientController(
694             IActivityClientController activityClientController) {
695         // No lock because it is no harm to encounter race condition. The thread safe Singleton#get
696         // will take over that case.
697         return INTERFACE_SINGLETON.mKnownInstance = activityClientController;
698     }
699 
getActivityClientController()700     private static IActivityClientController getActivityClientController() {
701         final IActivityClientController controller = INTERFACE_SINGLETON.mKnownInstance;
702         return controller != null ? controller : INTERFACE_SINGLETON.get();
703     }
704 
705     private static final Singleton<ActivityClient> sInstance = new Singleton<ActivityClient>() {
706         @Override
707         protected ActivityClient create() {
708             return new ActivityClient();
709         }
710     };
711 
712     private static final ActivityClientControllerSingleton INTERFACE_SINGLETON =
713             new ActivityClientControllerSingleton();
714 
715     private static class ActivityClientControllerSingleton
716             extends Singleton<IActivityClientController> {
717         /**
718          * A quick look up to reduce potential extra binder transactions. E.g. getting activity
719          * task manager from service manager and controller from activity task manager.
720          */
721         IActivityClientController mKnownInstance;
722 
723         @Override
create()724         protected IActivityClientController create() {
725             try {
726                 return ActivityTaskManager.getService().getActivityClientController();
727             } catch (RemoteException e) {
728                 throw e.rethrowFromSystemServer();
729             }
730         }
731     }
732 }
733