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.window;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.annotation.RequiresPermission;
22 import android.annotation.SuppressLint;
23 import android.annotation.TestApi;
24 import android.app.ActivityTaskManager;
25 import android.os.IBinder;
26 import android.os.RemoteException;
27 import android.util.Singleton;
28 import android.view.RemoteAnimationAdapter;
29 
30 /**
31  * Base class for organizing specific types of windows like Tasks and DisplayAreas
32  *
33  * @hide
34  */
35 @TestApi
36 public class WindowOrganizer {
37 
38     /**
39      * Apply multiple WindowContainer operations at once.
40      *
41      * Note that using this API requires the caller to hold
42      * {@link android.Manifest.permission#MANAGE_ACTIVITY_TASKS}, unless the caller is using
43      * {@link TaskFragmentOrganizer}, in which case it is allowed to change TaskFragment that is
44      * created by itself.
45      *
46      * @param t The transaction to apply.
47      */
48     @RequiresPermission(value = android.Manifest.permission.MANAGE_ACTIVITY_TASKS,
49             conditional = true)
applyTransaction(@onNull WindowContainerTransaction t)50     public void applyTransaction(@NonNull WindowContainerTransaction t) {
51         try {
52             if (!t.isEmpty()) {
53                 getWindowOrganizerController().applyTransaction(t);
54             }
55         } catch (RemoteException e) {
56             throw e.rethrowFromSystemServer();
57         }
58     }
59 
60     /**
61      * Apply multiple WindowContainer operations at once.
62      *
63      * Note that using this API requires the caller to hold
64      * {@link android.Manifest.permission#MANAGE_ACTIVITY_TASKS}, unless the caller is using
65      * {@link TaskFragmentOrganizer}, in which case it is allowed to change TaskFragment that is
66      * created by itself.
67      *
68      * @param t The transaction to apply.
69      * @param callback This transaction will use the synchronization scheme described in
70      *        BLASTSyncEngine.java. The SurfaceControl transaction containing the effects of this
71      *        WindowContainer transaction will be passed to this callback when ready.
72      * @return An ID for the sync operation which will later be passed to transactionReady callback.
73      *         This lets the caller differentiate overlapping sync operations.
74      */
75     @RequiresPermission(value = android.Manifest.permission.MANAGE_ACTIVITY_TASKS,
76             conditional = true)
applySyncTransaction(@onNull WindowContainerTransaction t, @NonNull WindowContainerTransactionCallback callback)77     public int applySyncTransaction(@NonNull WindowContainerTransaction t,
78             @NonNull WindowContainerTransactionCallback callback) {
79         try {
80             return getWindowOrganizerController().applySyncTransaction(t, callback.mInterface);
81         } catch (RemoteException e) {
82             throw e.rethrowFromSystemServer();
83         }
84     }
85 
86     /**
87      * Start a transition.
88      * @param type The type of the transition. This is ignored if a transitionToken is provided.
89      * @param transitionToken An existing transition to start. If null, a new transition is created.
90      * @param t The set of window operations that are part of this transition.
91      * @return A token identifying the transition. This will be the same as transitionToken if it
92      *         was provided.
93      * @hide
94      */
95     @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
96     @NonNull
startTransition(int type, @Nullable IBinder transitionToken, @Nullable WindowContainerTransaction t)97     public IBinder startTransition(int type, @Nullable IBinder transitionToken,
98             @Nullable WindowContainerTransaction t) {
99         try {
100             return getWindowOrganizerController().startTransition(type, transitionToken, t);
101         } catch (RemoteException e) {
102             throw e.rethrowFromSystemServer();
103         }
104     }
105 
106     /**
107      * Finishes a running transition.
108      * @param transitionToken The transition to finish. Can't be null.
109      * @param t A set of window operations to apply before finishing.
110      * @param callback A sync callback (if provided). See {@link #applySyncTransaction}.
111      * @return An ID for the sync operation if performed. See {@link #applySyncTransaction}.
112      *
113      * @hide
114      */
115     @SuppressLint("ExecutorRegistration")
116     @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
finishTransition(@onNull IBinder transitionToken, @Nullable WindowContainerTransaction t, @Nullable WindowContainerTransactionCallback callback)117     public int finishTransition(@NonNull IBinder transitionToken,
118             @Nullable WindowContainerTransaction t,
119             @Nullable WindowContainerTransactionCallback callback) {
120         try {
121             return getWindowOrganizerController().finishTransition(transitionToken, t,
122                     callback != null ? callback.mInterface : null);
123         } catch (RemoteException e) {
124             throw e.rethrowFromSystemServer();
125         }
126     }
127 
128     /**
129      * Start a legacy transition.
130      * @param type The type of the transition. This is ignored if a transitionToken is provided.
131      * @param adapter An existing transition to start. If null, a new transition is created.
132      * @param t The set of window operations that are part of this transition.
133      * @return true on success, false if a transition was already running.
134      * @hide
135      */
136     @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
137     @NonNull
startLegacyTransition(int type, @NonNull RemoteAnimationAdapter adapter, @NonNull WindowContainerTransactionCallback syncCallback, @NonNull WindowContainerTransaction t)138     public int startLegacyTransition(int type, @NonNull RemoteAnimationAdapter adapter,
139             @NonNull WindowContainerTransactionCallback syncCallback,
140             @NonNull WindowContainerTransaction t) {
141         try {
142             return getWindowOrganizerController().startLegacyTransition(
143                     type, adapter, syncCallback.mInterface, t);
144         } catch (RemoteException e) {
145             throw e.rethrowFromSystemServer();
146         }
147     }
148 
149     /**
150      * Register an ITransitionPlayer to handle transition animations.
151      * @hide
152      */
153     @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
registerTransitionPlayer(@ullable ITransitionPlayer player)154     public void registerTransitionPlayer(@Nullable ITransitionPlayer player) {
155         try {
156             getWindowOrganizerController().registerTransitionPlayer(player);
157         } catch (RemoteException e) {
158             throw e.rethrowFromSystemServer();
159         }
160     }
161 
162     /**
163      * @see TransitionMetrics
164      * @hide
165      */
getTransitionMetricsReporter()166     public static ITransitionMetricsReporter getTransitionMetricsReporter() {
167         try {
168             return getWindowOrganizerController().getTransitionMetricsReporter();
169         } catch (RemoteException e) {
170             throw e.rethrowFromSystemServer();
171         }
172     }
173 
getWindowOrganizerController()174     static IWindowOrganizerController getWindowOrganizerController() {
175         return IWindowOrganizerControllerSingleton.get();
176     }
177 
178     private static final Singleton<IWindowOrganizerController> IWindowOrganizerControllerSingleton =
179             new Singleton<IWindowOrganizerController>() {
180                 @Override
181                 protected IWindowOrganizerController create() {
182                     try {
183                         return ActivityTaskManager.getService().getWindowOrganizerController();
184                     } catch (RemoteException e) {
185                         return null;
186                     }
187                 }
188             };
189 }
190