LaunchActivityItem.java revision 770c4030691f11ca36ef0028a336a27eda2049ef
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 17package android.app.servertransaction; 18 19import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER; 20 21import android.app.ActivityThread.ActivityClientRecord; 22import android.app.ClientTransactionHandler; 23import android.app.ProfilerInfo; 24import android.app.ResultInfo; 25import android.content.Intent; 26import android.content.pm.ActivityInfo; 27import android.content.res.CompatibilityInfo; 28import android.content.res.Configuration; 29import android.os.BaseBundle; 30import android.os.Bundle; 31import android.os.IBinder; 32import android.os.Parcel; 33import android.os.PersistableBundle; 34import android.os.Trace; 35 36import com.android.internal.app.IVoiceInteractor; 37import com.android.internal.content.ReferrerIntent; 38 39import java.util.List; 40import java.util.Objects; 41 42/** 43 * Request to launch an activity. 44 * @hide 45 */ 46public class LaunchActivityItem extends ClientTransactionItem { 47 48 private Intent mIntent; 49 private int mIdent; 50 private ActivityInfo mInfo; 51 private Configuration mCurConfig; 52 private Configuration mOverrideConfig; 53 private CompatibilityInfo mCompatInfo; 54 private String mReferrer; 55 private IVoiceInteractor mVoiceInteractor; 56 private int mProcState; 57 private Bundle mState; 58 private PersistableBundle mPersistentState; 59 private List<ResultInfo> mPendingResults; 60 private List<ReferrerIntent> mPendingNewIntents; 61 private boolean mIsForward; 62 private ProfilerInfo mProfilerInfo; 63 64 @Override 65 public void preExecute(ClientTransactionHandler client, IBinder token) { 66 client.updateProcessState(mProcState, false); 67 client.updatePendingConfiguration(mCurConfig); 68 } 69 70 @Override 71 public void execute(ClientTransactionHandler client, IBinder token, 72 PendingTransactionActions pendingActions) { 73 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart"); 74 ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo, 75 mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState, 76 mPendingResults, mPendingNewIntents, mIsForward, 77 mProfilerInfo, client); 78 client.handleLaunchActivity(r, pendingActions, null /* customIntent */); 79 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); 80 } 81 82 83 // ObjectPoolItem implementation 84 85 private LaunchActivityItem() {} 86 87 /** Obtain an instance initialized with provided params. */ 88 public static LaunchActivityItem obtain(Intent intent, int ident, ActivityInfo info, 89 Configuration curConfig, Configuration overrideConfig, CompatibilityInfo compatInfo, 90 String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state, 91 PersistableBundle persistentState, List<ResultInfo> pendingResults, 92 List<ReferrerIntent> pendingNewIntents, boolean isForward, ProfilerInfo profilerInfo) { 93 LaunchActivityItem instance = ObjectPool.obtain(LaunchActivityItem.class); 94 if (instance == null) { 95 instance = new LaunchActivityItem(); 96 } 97 setValues(instance, intent, ident, info, curConfig, overrideConfig, compatInfo, referrer, 98 voiceInteractor, procState, state, persistentState, pendingResults, 99 pendingNewIntents, isForward, profilerInfo); 100 101 return instance; 102 } 103 104 @Override 105 public void recycle() { 106 setValues(this, null, 0, null, null, null, null, null, null, 0, null, null, null, null, 107 false, null); 108 ObjectPool.recycle(this); 109 } 110 111 112 // Parcelable implementation 113 114 /** Write from Parcel. */ 115 @Override 116 public void writeToParcel(Parcel dest, int flags) { 117 dest.writeTypedObject(mIntent, flags); 118 dest.writeInt(mIdent); 119 dest.writeTypedObject(mInfo, flags); 120 dest.writeTypedObject(mCurConfig, flags); 121 dest.writeTypedObject(mOverrideConfig, flags); 122 dest.writeTypedObject(mCompatInfo, flags); 123 dest.writeString(mReferrer); 124 dest.writeStrongInterface(mVoiceInteractor); 125 dest.writeInt(mProcState); 126 dest.writeBundle(mState); 127 dest.writePersistableBundle(mPersistentState); 128 dest.writeTypedList(mPendingResults, flags); 129 dest.writeTypedList(mPendingNewIntents, flags); 130 dest.writeBoolean(mIsForward); 131 dest.writeTypedObject(mProfilerInfo, flags); 132 } 133 134 /** Read from Parcel. */ 135 private LaunchActivityItem(Parcel in) { 136 setValues(this, in.readTypedObject(Intent.CREATOR), in.readInt(), 137 in.readTypedObject(ActivityInfo.CREATOR), in.readTypedObject(Configuration.CREATOR), 138 in.readTypedObject(Configuration.CREATOR), 139 in.readTypedObject(CompatibilityInfo.CREATOR), in.readString(), 140 IVoiceInteractor.Stub.asInterface(in.readStrongBinder()), in.readInt(), 141 in.readBundle(getClass().getClassLoader()), 142 in.readPersistableBundle(getClass().getClassLoader()), 143 in.createTypedArrayList(ResultInfo.CREATOR), 144 in.createTypedArrayList(ReferrerIntent.CREATOR), in.readBoolean(), 145 in.readTypedObject(ProfilerInfo.CREATOR)); 146 } 147 148 public static final Creator<LaunchActivityItem> CREATOR = 149 new Creator<LaunchActivityItem>() { 150 public LaunchActivityItem createFromParcel(Parcel in) { 151 return new LaunchActivityItem(in); 152 } 153 154 public LaunchActivityItem[] newArray(int size) { 155 return new LaunchActivityItem[size]; 156 } 157 }; 158 159 @Override 160 public boolean equals(Object o) { 161 if (this == o) { 162 return true; 163 } 164 if (o == null || getClass() != o.getClass()) { 165 return false; 166 } 167 final LaunchActivityItem other = (LaunchActivityItem) o; 168 final boolean intentsEqual = (mIntent == null && other.mIntent == null) 169 || (mIntent != null && mIntent.filterEquals(other.mIntent)); 170 return intentsEqual && mIdent == other.mIdent 171 && activityInfoEqual(other.mInfo) && Objects.equals(mCurConfig, other.mCurConfig) 172 && Objects.equals(mOverrideConfig, other.mOverrideConfig) 173 && Objects.equals(mCompatInfo, other.mCompatInfo) 174 && Objects.equals(mReferrer, other.mReferrer) 175 && mProcState == other.mProcState && areBundlesEqual(mState, other.mState) 176 && areBundlesEqual(mPersistentState, other.mPersistentState) 177 && Objects.equals(mPendingResults, other.mPendingResults) 178 && Objects.equals(mPendingNewIntents, other.mPendingNewIntents) 179 && mIsForward == other.mIsForward 180 && Objects.equals(mProfilerInfo, other.mProfilerInfo); 181 } 182 183 @Override 184 public int hashCode() { 185 int result = 17; 186 result = 31 * result + mIntent.filterHashCode(); 187 result = 31 * result + mIdent; 188 result = 31 * result + Objects.hashCode(mCurConfig); 189 result = 31 * result + Objects.hashCode(mOverrideConfig); 190 result = 31 * result + Objects.hashCode(mCompatInfo); 191 result = 31 * result + Objects.hashCode(mReferrer); 192 result = 31 * result + Objects.hashCode(mProcState); 193 result = 31 * result + (mState != null ? mState.size() : 0); 194 result = 31 * result + (mPersistentState != null ? mPersistentState.size() : 0); 195 result = 31 * result + Objects.hashCode(mPendingResults); 196 result = 31 * result + Objects.hashCode(mPendingNewIntents); 197 result = 31 * result + (mIsForward ? 1 : 0); 198 result = 31 * result + Objects.hashCode(mProfilerInfo); 199 return result; 200 } 201 202 private boolean activityInfoEqual(ActivityInfo other) { 203 if (mInfo == null) { 204 return other == null; 205 } 206 return other != null && mInfo.flags == other.flags 207 && mInfo.maxAspectRatio == other.maxAspectRatio 208 && Objects.equals(mInfo.launchToken, other.launchToken) 209 && Objects.equals(mInfo.getComponentName(), other.getComponentName()); 210 } 211 212 private static boolean areBundlesEqual(BaseBundle extras, BaseBundle newExtras) { 213 if (extras == null || newExtras == null) { 214 return extras == newExtras; 215 } 216 217 if (extras.size() != newExtras.size()) { 218 return false; 219 } 220 221 for (String key : extras.keySet()) { 222 if (key != null) { 223 final Object value = extras.get(key); 224 final Object newValue = newExtras.get(key); 225 if (!Objects.equals(value, newValue)) { 226 return false; 227 } 228 } 229 } 230 return true; 231 } 232 233 @Override 234 public String toString() { 235 return "LaunchActivityItem{intent=" + mIntent + ",ident=" + mIdent + ",info=" + mInfo 236 + ",curConfig=" + mCurConfig + ",overrideConfig=" + mOverrideConfig 237 + ",referrer=" + mReferrer + ",procState=" + mProcState + ",state=" + mState 238 + ",persistentState=" + mPersistentState + ",pendingResults=" + mPendingResults 239 + ",pendingNewIntents=" + mPendingNewIntents + ",profilerInfo=" + mProfilerInfo 240 + "}"; 241 } 242 243 // Using the same method to set and clear values to make sure we don't forget anything 244 private static void setValues(LaunchActivityItem instance, Intent intent, int ident, 245 ActivityInfo info, Configuration curConfig, Configuration overrideConfig, 246 CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor, 247 int procState, Bundle state, PersistableBundle persistentState, 248 List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, 249 boolean isForward, ProfilerInfo profilerInfo) { 250 instance.mIntent = intent; 251 instance.mIdent = ident; 252 instance.mInfo = info; 253 instance.mCurConfig = curConfig; 254 instance.mOverrideConfig = overrideConfig; 255 instance.mCompatInfo = compatInfo; 256 instance.mReferrer = referrer; 257 instance.mVoiceInteractor = voiceInteractor; 258 instance.mProcState = procState; 259 instance.mState = state; 260 instance.mPersistentState = persistentState; 261 instance.mPendingResults = pendingResults; 262 instance.mPendingNewIntents = pendingNewIntents; 263 instance.mIsForward = isForward; 264 instance.mProfilerInfo = profilerInfo; 265 } 266} 267