1 /*
2  * Copyright 2017 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 package android.app;
17 
18 import android.annotation.NonNull;
19 import android.annotation.Nullable;
20 import android.app.ActivityOptions.SceneTransitionInfo;
21 import android.app.ActivityThread.ActivityClientRecord;
22 import android.app.servertransaction.ClientTransaction;
23 import android.app.servertransaction.DestroyActivityItem;
24 import android.app.servertransaction.PendingTransactionActions;
25 import android.app.servertransaction.TransactionExecutor;
26 import android.content.Intent;
27 import android.content.pm.ApplicationInfo;
28 import android.content.res.Configuration;
29 import android.os.IBinder;
30 import android.util.MergedConfiguration;
31 import android.view.SurfaceControl;
32 import android.window.ActivityWindowInfo;
33 import android.window.SplashScreenView.SplashScreenViewParcelable;
34 import android.window.WindowContextInfo;
35 
36 import com.android.internal.annotations.VisibleForTesting;
37 import com.android.internal.content.ReferrerIntent;
38 
39 import java.util.List;
40 import java.util.Map;
41 
42 /**
43  * Defines operations that a {@link android.app.servertransaction.ClientTransaction} or its items
44  * can perform on client.
45  * @hide
46  */
47 public abstract class ClientTransactionHandler {
48 
49     private boolean mIsExecutingLocalTransaction;
50 
51     // Schedule phase related logic and handlers.
52 
53     /** Prepare and schedule transaction for execution. */
scheduleTransaction(ClientTransaction transaction)54     void scheduleTransaction(ClientTransaction transaction) {
55         transaction.preExecute(this);
56         sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
57     }
58 
59     /**
60      * Execute transaction immediately without scheduling it. This is used for local requests, so
61      * it will also recycle the transaction.
62      */
63     @VisibleForTesting
executeTransaction(ClientTransaction transaction)64     public void executeTransaction(ClientTransaction transaction) {
65         mIsExecutingLocalTransaction = true;
66         try {
67             transaction.preExecute(this);
68             getTransactionExecutor().execute(transaction);
69         } finally {
70             mIsExecutingLocalTransaction = false;
71             transaction.recycle();
72         }
73     }
74 
75     /** Returns {@code true} if the current executing ClientTransaction is from local request. */
isExecutingLocalTransaction()76     public boolean isExecutingLocalTransaction() {
77         return mIsExecutingLocalTransaction;
78     }
79 
80     /**
81      * Get the {@link TransactionExecutor} that will be performing lifecycle transitions and
82      * callbacks for activities.
83      */
getTransactionExecutor()84     abstract TransactionExecutor getTransactionExecutor();
85 
sendMessage(int what, Object obj)86     abstract void sendMessage(int what, Object obj);
87 
88     /** Get activity instance for the token. */
getActivity(IBinder token)89     public abstract Activity getActivity(IBinder token);
90 
91     // Prepare phase related logic and handlers. Methods that inform about about pending changes or
92     // do other internal bookkeeping.
93 
94     /** Set pending config in case it will be updated by other transaction item. */
updatePendingConfiguration(Configuration config)95     public abstract void updatePendingConfiguration(Configuration config);
96 
97     /** Set current process state. */
updateProcessState(int processState, boolean fromIpc)98     public abstract void updateProcessState(int processState, boolean fromIpc);
99 
100     /** Count how many activities are launching. */
countLaunchingActivities(int num)101     public abstract void countLaunchingActivities(int num);
102 
103     // Execute phase related logic and handlers. Methods here execute actual lifecycle transactions
104     // and deliver callbacks.
105 
106     /** Get activity and its corresponding transaction item which are going to destroy. */
getActivitiesToBeDestroyed()107     public abstract Map<IBinder, DestroyActivityItem> getActivitiesToBeDestroyed();
108 
109     /** Destroy the activity. */
handleDestroyActivity(@onNull ActivityClientRecord r, boolean finishing, boolean getNonConfigInstance, String reason)110     public abstract void handleDestroyActivity(@NonNull ActivityClientRecord r, boolean finishing,
111             boolean getNonConfigInstance, String reason);
112 
113     /** Pause the activity. */
handlePauseActivity(@onNull ActivityClientRecord r, boolean finished, boolean userLeaving, boolean autoEnteringPip, PendingTransactionActions pendingActions, String reason)114     public abstract void handlePauseActivity(@NonNull ActivityClientRecord r, boolean finished,
115             boolean userLeaving, boolean autoEnteringPip,
116             PendingTransactionActions pendingActions, String reason);
117 
118     /**
119      * Resume the activity.
120      * @param r Target activity record.
121      * @param finalStateRequest Flag indicating if this call is handling final lifecycle state
122      *                          request for a transaction.
123      * @param isForward Flag indicating if next transition is forward.
124      * @param reason Reason for performing this operation.
125      */
handleResumeActivity(@onNull ActivityClientRecord r, boolean finalStateRequest, boolean isForward, boolean shouldSendCompatFakeFocus, String reason)126     public abstract void handleResumeActivity(@NonNull ActivityClientRecord r,
127             boolean finalStateRequest, boolean isForward, boolean shouldSendCompatFakeFocus,
128             String reason);
129 
130     /**
131      * Notify the activity about top resumed state change.
132      * @param r Target activity record.
133      * @param isTopResumedActivity Current state of the activity, {@code true} if it's the
134      *                             topmost resumed activity in the system, {@code false} otherwise.
135      * @param reason Reason for performing this operation.
136      */
handleTopResumedActivityChanged(@onNull ActivityClientRecord r, boolean isTopResumedActivity, String reason)137     public abstract void handleTopResumedActivityChanged(@NonNull ActivityClientRecord r,
138             boolean isTopResumedActivity, String reason);
139 
140     /**
141      * Stop the activity.
142      * @param r Target activity record.
143      * @param pendingActions Pending actions to be used on this or later stages of activity
144      *                       transaction.
145      * @param finalStateRequest Flag indicating if this call is handling final lifecycle state
146      *                          request for a transaction.
147      * @param reason Reason for performing this operation.
148      */
handleStopActivity(@onNull ActivityClientRecord r, PendingTransactionActions pendingActions, boolean finalStateRequest, String reason)149     public abstract void handleStopActivity(@NonNull ActivityClientRecord r,
150             PendingTransactionActions pendingActions, boolean finalStateRequest, String reason);
151 
152     /** Report that activity was stopped to server. */
reportStop(PendingTransactionActions pendingActions)153     public abstract void reportStop(PendingTransactionActions pendingActions);
154 
155     /** Restart the activity after it was stopped. */
performRestartActivity(@onNull ActivityClientRecord r, boolean start)156     public abstract void performRestartActivity(@NonNull ActivityClientRecord r, boolean start);
157 
158      /** Report that activity was refreshed to server. */
reportRefresh(@onNull ActivityClientRecord r)159     public abstract void reportRefresh(@NonNull ActivityClientRecord r);
160 
161     /** Set pending activity configuration in case it will be updated by other transaction item. */
updatePendingActivityConfiguration(@onNull IBinder token, @NonNull Configuration overrideConfig)162     public abstract void updatePendingActivityConfiguration(@NonNull IBinder token,
163             @NonNull Configuration overrideConfig);
164 
165     /** Deliver activity (override) configuration change. */
handleActivityConfigurationChanged(@onNull ActivityClientRecord r, @NonNull Configuration overrideConfig, int displayId, @NonNull ActivityWindowInfo activityWindowInfo)166     public abstract void handleActivityConfigurationChanged(@NonNull ActivityClientRecord r,
167             @NonNull Configuration overrideConfig, int displayId,
168             @NonNull ActivityWindowInfo activityWindowInfo);
169 
170     /** Deliver {@link android.window.WindowContextInfo} change. */
handleWindowContextInfoChanged(@onNull IBinder clientToken, @NonNull WindowContextInfo info)171     public abstract void handleWindowContextInfoChanged(@NonNull IBinder clientToken,
172             @NonNull WindowContextInfo info);
173 
174     /** Deliver {@link android.window.WindowContext} window removal event. */
handleWindowContextWindowRemoval(@onNull IBinder clientToken)175     public abstract void handleWindowContextWindowRemoval(@NonNull IBinder clientToken);
176 
177     /** Deliver result from another activity. */
handleSendResult( @onNull ActivityClientRecord r, List<ResultInfo> results, String reason)178     public abstract void handleSendResult(
179             @NonNull ActivityClientRecord r, List<ResultInfo> results, String reason);
180 
181     /** Deliver new intent. */
handleNewIntent( @onNull ActivityClientRecord r, List<ReferrerIntent> intents)182     public abstract void handleNewIntent(
183             @NonNull ActivityClientRecord r, List<ReferrerIntent> intents);
184 
185     /** Request that an activity enter picture-in-picture. */
handlePictureInPictureRequested(@onNull ActivityClientRecord r)186     public abstract void handlePictureInPictureRequested(@NonNull ActivityClientRecord r);
187 
188     /** Signal to an activity (that is currently in PiP) of PiP state changes. */
handlePictureInPictureStateChanged(@onNull ActivityClientRecord r, PictureInPictureUiState pipState)189     public abstract void handlePictureInPictureStateChanged(@NonNull ActivityClientRecord r,
190             PictureInPictureUiState pipState);
191 
192     /** Whether the activity want to handle splash screen exit animation */
isHandleSplashScreenExit(@onNull IBinder token)193     public abstract boolean isHandleSplashScreenExit(@NonNull IBinder token);
194 
195     /** Attach a splash screen window view to the top of the activity */
handleAttachSplashScreenView(@onNull ActivityClientRecord r, @NonNull SplashScreenViewParcelable parcelable, @NonNull SurfaceControl startingWindowLeash)196     public abstract void handleAttachSplashScreenView(@NonNull ActivityClientRecord r,
197             @NonNull SplashScreenViewParcelable parcelable,
198             @NonNull SurfaceControl startingWindowLeash);
199 
200     /** Perform activity launch. */
handleLaunchActivity(@onNull ActivityClientRecord r, PendingTransactionActions pendingActions, int deviceId, Intent customIntent)201     public abstract Activity handleLaunchActivity(@NonNull ActivityClientRecord r,
202             PendingTransactionActions pendingActions, int deviceId, Intent customIntent);
203 
204     /** Perform activity start. */
handleStartActivity(@onNull ActivityClientRecord r, PendingTransactionActions pendingActions, SceneTransitionInfo sceneTransitionInfo)205     public abstract void handleStartActivity(@NonNull ActivityClientRecord r,
206             PendingTransactionActions pendingActions, SceneTransitionInfo sceneTransitionInfo);
207 
208     /** Get package info. */
getPackageInfoNoCheck(ApplicationInfo ai)209     public abstract LoadedApk getPackageInfoNoCheck(ApplicationInfo ai);
210 
211     /** Deliver app configuration change notification and device association. */
handleConfigurationChanged(Configuration config, int deviceId)212     public abstract void handleConfigurationChanged(Configuration config, int deviceId);
213 
214     /**
215      * Get {@link android.app.ActivityThread.ActivityClientRecord} instance that corresponds to the
216      * provided token.
217      */
getActivityClient(IBinder token)218     public abstract ActivityClientRecord getActivityClient(IBinder token);
219 
220     /**
221      * Prepare activity relaunch to update internal bookkeeping. This is used to track multiple
222      * relaunch and config update requests.
223      * @param token Activity token.
224      * @param pendingResults Activity results to be delivered.
225      * @param pendingNewIntents New intent messages to be delivered.
226      * @param configChanges Mask of configuration changes that have occurred.
227      * @param config New configuration applied to the activity.
228      * @param preserveWindow Whether the activity should try to reuse the window it created,
229      *                        including the decor view after the relaunch.
230      * @param activityWindowInfo Window information about the relaunched Activity.
231      * @return An initialized instance of {@link ActivityThread.ActivityClientRecord} to use during
232      *         relaunch, or {@code null} if relaunch cancelled.
233      */
prepareRelaunchActivity(@onNull IBinder token, @Nullable List<ResultInfo> pendingResults, @Nullable List<ReferrerIntent> pendingNewIntents, int configChanges, @NonNull MergedConfiguration config, boolean preserveWindow, @NonNull ActivityWindowInfo activityWindowInfo)234     public abstract ActivityClientRecord prepareRelaunchActivity(@NonNull IBinder token,
235             @Nullable List<ResultInfo> pendingResults,
236             @Nullable List<ReferrerIntent> pendingNewIntents, int configChanges,
237             @NonNull MergedConfiguration config, boolean preserveWindow,
238             @NonNull ActivityWindowInfo activityWindowInfo);
239 
240     /**
241      * Perform activity relaunch.
242      * @param r Activity client record prepared for relaunch.
243      * @param pendingActions Pending actions to be used on later stages of activity transaction.
244      * */
handleRelaunchActivity(@onNull ActivityClientRecord r, @NonNull PendingTransactionActions pendingActions)245     public abstract void handleRelaunchActivity(@NonNull ActivityClientRecord r,
246             @NonNull PendingTransactionActions pendingActions);
247 
248     /**
249      * Report that relaunch request was handled.
250      * @param r Target activity record.
251      */
reportRelaunch(@onNull ActivityClientRecord r)252     public abstract void reportRelaunch(@NonNull ActivityClientRecord r);
253 }
254