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