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 17 package android.app.servertransaction; 18 19 import static android.app.ActivityThread.DEBUG_ORDER; 20 21 import android.annotation.NonNull; 22 import android.annotation.Nullable; 23 import android.app.ActivityThread.ActivityClientRecord; 24 import android.app.ClientTransactionHandler; 25 import android.app.ResultInfo; 26 import android.os.IBinder; 27 import android.os.Parcel; 28 import android.os.Trace; 29 import android.util.MergedConfiguration; 30 import android.util.Slog; 31 32 import com.android.internal.content.ReferrerIntent; 33 34 import java.util.List; 35 import java.util.Objects; 36 37 /** 38 * Activity relaunch callback. 39 * @hide 40 */ 41 public class ActivityRelaunchItem extends ActivityTransactionItem { 42 43 private static final String TAG = "ActivityRelaunchItem"; 44 45 private List<ResultInfo> mPendingResults; 46 private List<ReferrerIntent> mPendingNewIntents; 47 private int mConfigChanges; 48 private MergedConfiguration mConfig; 49 private boolean mPreserveWindow; 50 51 /** 52 * A record that was properly configured for relaunch. Execution will be cancelled if not 53 * initialized after {@link #preExecute(ClientTransactionHandler, IBinder)}. 54 */ 55 private ActivityClientRecord mActivityClientRecord; 56 57 @Override preExecute(ClientTransactionHandler client, IBinder token)58 public void preExecute(ClientTransactionHandler client, IBinder token) { 59 mActivityClientRecord = client.prepareRelaunchActivity(token, mPendingResults, 60 mPendingNewIntents, mConfigChanges, mConfig, mPreserveWindow); 61 } 62 63 @Override execute(ClientTransactionHandler client, ActivityClientRecord r, PendingTransactionActions pendingActions)64 public void execute(ClientTransactionHandler client, ActivityClientRecord r, 65 PendingTransactionActions pendingActions) { 66 if (mActivityClientRecord == null) { 67 if (DEBUG_ORDER) Slog.d(TAG, "Activity relaunch cancelled"); 68 return; 69 } 70 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart"); 71 client.handleRelaunchActivity(mActivityClientRecord, pendingActions); 72 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 73 } 74 75 @Override postExecute(ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions)76 public void postExecute(ClientTransactionHandler client, IBinder token, 77 PendingTransactionActions pendingActions) { 78 final ActivityClientRecord r = getActivityClientRecord(client, token); 79 client.reportRelaunch(r, pendingActions); 80 } 81 82 // ObjectPoolItem implementation 83 ActivityRelaunchItem()84 private ActivityRelaunchItem() {} 85 86 /** Obtain an instance initialized with provided params. */ obtain(List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, int configChanges, MergedConfiguration config, boolean preserveWindow)87 public static ActivityRelaunchItem obtain(List<ResultInfo> pendingResults, 88 List<ReferrerIntent> pendingNewIntents, int configChanges, MergedConfiguration config, 89 boolean preserveWindow) { 90 ActivityRelaunchItem instance = ObjectPool.obtain(ActivityRelaunchItem.class); 91 if (instance == null) { 92 instance = new ActivityRelaunchItem(); 93 } 94 instance.mPendingResults = pendingResults; 95 instance.mPendingNewIntents = pendingNewIntents; 96 instance.mConfigChanges = configChanges; 97 instance.mConfig = config; 98 instance.mPreserveWindow = preserveWindow; 99 100 return instance; 101 } 102 103 @Override recycle()104 public void recycle() { 105 mPendingResults = null; 106 mPendingNewIntents = null; 107 mConfigChanges = 0; 108 mConfig = null; 109 mPreserveWindow = false; 110 mActivityClientRecord = null; 111 ObjectPool.recycle(this); 112 } 113 114 115 // Parcelable implementation 116 117 /** Write to Parcel. */ 118 @Override writeToParcel(Parcel dest, int flags)119 public void writeToParcel(Parcel dest, int flags) { 120 dest.writeTypedList(mPendingResults, flags); 121 dest.writeTypedList(mPendingNewIntents, flags); 122 dest.writeInt(mConfigChanges); 123 dest.writeTypedObject(mConfig, flags); 124 dest.writeBoolean(mPreserveWindow); 125 } 126 127 /** Read from Parcel. */ ActivityRelaunchItem(Parcel in)128 private ActivityRelaunchItem(Parcel in) { 129 mPendingResults = in.createTypedArrayList(ResultInfo.CREATOR); 130 mPendingNewIntents = in.createTypedArrayList(ReferrerIntent.CREATOR); 131 mConfigChanges = in.readInt(); 132 mConfig = in.readTypedObject(MergedConfiguration.CREATOR); 133 mPreserveWindow = in.readBoolean(); 134 } 135 136 public static final @NonNull Creator<ActivityRelaunchItem> CREATOR = 137 new Creator<ActivityRelaunchItem>() { 138 public ActivityRelaunchItem createFromParcel(Parcel in) { 139 return new ActivityRelaunchItem(in); 140 } 141 142 public ActivityRelaunchItem[] newArray(int size) { 143 return new ActivityRelaunchItem[size]; 144 } 145 }; 146 147 @Override equals(@ullable Object o)148 public boolean equals(@Nullable Object o) { 149 if (this == o) { 150 return true; 151 } 152 if (o == null || getClass() != o.getClass()) { 153 return false; 154 } 155 final ActivityRelaunchItem other = (ActivityRelaunchItem) o; 156 return Objects.equals(mPendingResults, other.mPendingResults) 157 && Objects.equals(mPendingNewIntents, other.mPendingNewIntents) 158 && mConfigChanges == other.mConfigChanges && Objects.equals(mConfig, other.mConfig) 159 && mPreserveWindow == other.mPreserveWindow; 160 } 161 162 @Override hashCode()163 public int hashCode() { 164 int result = 17; 165 result = 31 * result + Objects.hashCode(mPendingResults); 166 result = 31 * result + Objects.hashCode(mPendingNewIntents); 167 result = 31 * result + mConfigChanges; 168 result = 31 * result + Objects.hashCode(mConfig); 169 result = 31 * result + (mPreserveWindow ? 1 : 0); 170 return result; 171 } 172 173 @Override toString()174 public String toString() { 175 return "ActivityRelaunchItem{pendingResults=" + mPendingResults 176 + ",pendingNewIntents=" + mPendingNewIntents + ",configChanges=" + mConfigChanges 177 + ",config=" + mConfig + ",preserveWindow" + mPreserveWindow + "}"; 178 } 179 } 180