blob: ed793bfae41adf691d2e5f996e3567ee60ca4674 [file] [log] [blame]
Andrii Kulian446e8242017-10-26 15:17:29 -07001/*
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
Mathew Inwood98e9ad12018-08-30 13:11:50 +010021import android.annotation.UnsupportedAppUsage;
Andrii Kulian88e05cb2017-12-05 17:21:10 -080022import android.app.ActivityThread.ActivityClientRecord;
Andrii Kulian446e8242017-10-26 15:17:29 -070023import android.app.ClientTransactionHandler;
24import android.app.ProfilerInfo;
25import android.app.ResultInfo;
26import android.content.Intent;
27import android.content.pm.ActivityInfo;
28import android.content.res.CompatibilityInfo;
29import android.content.res.Configuration;
Andrii Kulian6b9d3a12017-11-16 14:36:36 -080030import android.os.BaseBundle;
Andrii Kulian446e8242017-10-26 15:17:29 -070031import android.os.Bundle;
32import android.os.IBinder;
33import android.os.Parcel;
34import android.os.PersistableBundle;
35import android.os.Trace;
36
37import com.android.internal.app.IVoiceInteractor;
38import com.android.internal.content.ReferrerIntent;
39
40import java.util.List;
Andrii Kulian6b9d3a12017-11-16 14:36:36 -080041import java.util.Objects;
Andrii Kulian446e8242017-10-26 15:17:29 -070042
43/**
44 * Request to launch an activity.
45 * @hide
46 */
Andrii Kulian88e05cb2017-12-05 17:21:10 -080047public class LaunchActivityItem extends ClientTransactionItem {
Andrii Kulian446e8242017-10-26 15:17:29 -070048
Mathew Inwood98e9ad12018-08-30 13:11:50 +010049 @UnsupportedAppUsage
Andrii Kulian9c5ea9c2017-12-07 09:31:01 -080050 private Intent mIntent;
51 private int mIdent;
Mathew Inwood98e9ad12018-08-30 13:11:50 +010052 @UnsupportedAppUsage
Andrii Kulian9c5ea9c2017-12-07 09:31:01 -080053 private ActivityInfo mInfo;
54 private Configuration mCurConfig;
55 private Configuration mOverrideConfig;
56 private CompatibilityInfo mCompatInfo;
57 private String mReferrer;
58 private IVoiceInteractor mVoiceInteractor;
59 private int mProcState;
60 private Bundle mState;
61 private PersistableBundle mPersistentState;
62 private List<ResultInfo> mPendingResults;
63 private List<ReferrerIntent> mPendingNewIntents;
64 private boolean mIsForward;
65 private ProfilerInfo mProfilerInfo;
Andrii Kulian446e8242017-10-26 15:17:29 -070066
67 @Override
Andrii Kulian88e05cb2017-12-05 17:21:10 -080068 public void preExecute(ClientTransactionHandler client, IBinder token) {
Andrii Kulian446e8242017-10-26 15:17:29 -070069 client.updateProcessState(mProcState, false);
70 client.updatePendingConfiguration(mCurConfig);
71 }
72
73 @Override
Andrii Kulian88e05cb2017-12-05 17:21:10 -080074 public void execute(ClientTransactionHandler client, IBinder token,
75 PendingTransactionActions pendingActions) {
Andrii Kulian446e8242017-10-26 15:17:29 -070076 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
Andrii Kulian88e05cb2017-12-05 17:21:10 -080077 ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
78 mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
79 mPendingResults, mPendingNewIntents, mIsForward,
80 mProfilerInfo, client);
Andrii Kulian770c4032018-05-02 18:40:59 -070081 client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
Andrii Kulian446e8242017-10-26 15:17:29 -070082 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
83 }
84
Andrii Kulian446e8242017-10-26 15:17:29 -070085
Andrii Kulian9c5ea9c2017-12-07 09:31:01 -080086 // ObjectPoolItem implementation
87
88 private LaunchActivityItem() {}
89
90 /** Obtain an instance initialized with provided params. */
91 public static LaunchActivityItem obtain(Intent intent, int ident, ActivityInfo info,
92 Configuration curConfig, Configuration overrideConfig, CompatibilityInfo compatInfo,
93 String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state,
94 PersistableBundle persistentState, List<ResultInfo> pendingResults,
95 List<ReferrerIntent> pendingNewIntents, boolean isForward, ProfilerInfo profilerInfo) {
96 LaunchActivityItem instance = ObjectPool.obtain(LaunchActivityItem.class);
97 if (instance == null) {
98 instance = new LaunchActivityItem();
99 }
100 setValues(instance, intent, ident, info, curConfig, overrideConfig, compatInfo, referrer,
101 voiceInteractor, procState, state, persistentState, pendingResults,
102 pendingNewIntents, isForward, profilerInfo);
103
104 return instance;
105 }
106
107 @Override
108 public void recycle() {
109 setValues(this, null, 0, null, null, null, null, null, null, 0, null, null, null, null,
110 false, null);
111 ObjectPool.recycle(this);
112 }
113
114
Andrii Kulian446e8242017-10-26 15:17:29 -0700115 // Parcelable implementation
116
117 /** Write from Parcel. */
118 @Override
119 public void writeToParcel(Parcel dest, int flags) {
120 dest.writeTypedObject(mIntent, flags);
121 dest.writeInt(mIdent);
122 dest.writeTypedObject(mInfo, flags);
123 dest.writeTypedObject(mCurConfig, flags);
124 dest.writeTypedObject(mOverrideConfig, flags);
125 dest.writeTypedObject(mCompatInfo, flags);
126 dest.writeString(mReferrer);
Andrii Kulian9c5ea9c2017-12-07 09:31:01 -0800127 dest.writeStrongInterface(mVoiceInteractor);
Andrii Kulian446e8242017-10-26 15:17:29 -0700128 dest.writeInt(mProcState);
129 dest.writeBundle(mState);
130 dest.writePersistableBundle(mPersistentState);
131 dest.writeTypedList(mPendingResults, flags);
132 dest.writeTypedList(mPendingNewIntents, flags);
Andrii Kulian446e8242017-10-26 15:17:29 -0700133 dest.writeBoolean(mIsForward);
134 dest.writeTypedObject(mProfilerInfo, flags);
135 }
136
137 /** Read from Parcel. */
138 private LaunchActivityItem(Parcel in) {
Andrii Kulian9c5ea9c2017-12-07 09:31:01 -0800139 setValues(this, in.readTypedObject(Intent.CREATOR), in.readInt(),
140 in.readTypedObject(ActivityInfo.CREATOR), in.readTypedObject(Configuration.CREATOR),
141 in.readTypedObject(Configuration.CREATOR),
142 in.readTypedObject(CompatibilityInfo.CREATOR), in.readString(),
143 IVoiceInteractor.Stub.asInterface(in.readStrongBinder()), in.readInt(),
144 in.readBundle(getClass().getClassLoader()),
145 in.readPersistableBundle(getClass().getClassLoader()),
146 in.createTypedArrayList(ResultInfo.CREATOR),
147 in.createTypedArrayList(ReferrerIntent.CREATOR), in.readBoolean(),
148 in.readTypedObject(ProfilerInfo.CREATOR));
Andrii Kulian446e8242017-10-26 15:17:29 -0700149 }
150
151 public static final Creator<LaunchActivityItem> CREATOR =
152 new Creator<LaunchActivityItem>() {
153 public LaunchActivityItem createFromParcel(Parcel in) {
154 return new LaunchActivityItem(in);
155 }
156
157 public LaunchActivityItem[] newArray(int size) {
158 return new LaunchActivityItem[size];
159 }
160 };
Andrii Kulian6b9d3a12017-11-16 14:36:36 -0800161
162 @Override
163 public boolean equals(Object o) {
164 if (this == o) {
165 return true;
166 }
167 if (o == null || getClass() != o.getClass()) {
168 return false;
169 }
170 final LaunchActivityItem other = (LaunchActivityItem) o;
Andrii Kulian9c5ea9c2017-12-07 09:31:01 -0800171 final boolean intentsEqual = (mIntent == null && other.mIntent == null)
172 || (mIntent != null && mIntent.filterEquals(other.mIntent));
173 return intentsEqual && mIdent == other.mIdent
Andrii Kulian6b9d3a12017-11-16 14:36:36 -0800174 && activityInfoEqual(other.mInfo) && Objects.equals(mCurConfig, other.mCurConfig)
175 && Objects.equals(mOverrideConfig, other.mOverrideConfig)
176 && Objects.equals(mCompatInfo, other.mCompatInfo)
177 && Objects.equals(mReferrer, other.mReferrer)
178 && mProcState == other.mProcState && areBundlesEqual(mState, other.mState)
179 && areBundlesEqual(mPersistentState, other.mPersistentState)
180 && Objects.equals(mPendingResults, other.mPendingResults)
181 && Objects.equals(mPendingNewIntents, other.mPendingNewIntents)
Andrii Kulian88e05cb2017-12-05 17:21:10 -0800182 && mIsForward == other.mIsForward
Andrii Kulian6b9d3a12017-11-16 14:36:36 -0800183 && Objects.equals(mProfilerInfo, other.mProfilerInfo);
184 }
185
186 @Override
187 public int hashCode() {
188 int result = 17;
189 result = 31 * result + mIntent.filterHashCode();
190 result = 31 * result + mIdent;
191 result = 31 * result + Objects.hashCode(mCurConfig);
192 result = 31 * result + Objects.hashCode(mOverrideConfig);
193 result = 31 * result + Objects.hashCode(mCompatInfo);
194 result = 31 * result + Objects.hashCode(mReferrer);
195 result = 31 * result + Objects.hashCode(mProcState);
196 result = 31 * result + (mState != null ? mState.size() : 0);
197 result = 31 * result + (mPersistentState != null ? mPersistentState.size() : 0);
198 result = 31 * result + Objects.hashCode(mPendingResults);
199 result = 31 * result + Objects.hashCode(mPendingNewIntents);
Andrii Kulian6b9d3a12017-11-16 14:36:36 -0800200 result = 31 * result + (mIsForward ? 1 : 0);
201 result = 31 * result + Objects.hashCode(mProfilerInfo);
202 return result;
203 }
204
205 private boolean activityInfoEqual(ActivityInfo other) {
Andrii Kulian9c5ea9c2017-12-07 09:31:01 -0800206 if (mInfo == null) {
207 return other == null;
208 }
209 return other != null && mInfo.flags == other.flags
210 && mInfo.maxAspectRatio == other.maxAspectRatio
Andrii Kulian6b9d3a12017-11-16 14:36:36 -0800211 && Objects.equals(mInfo.launchToken, other.launchToken)
212 && Objects.equals(mInfo.getComponentName(), other.getComponentName());
213 }
214
215 private static boolean areBundlesEqual(BaseBundle extras, BaseBundle newExtras) {
216 if (extras == null || newExtras == null) {
217 return extras == newExtras;
218 }
219
220 if (extras.size() != newExtras.size()) {
221 return false;
222 }
223
224 for (String key : extras.keySet()) {
225 if (key != null) {
226 final Object value = extras.get(key);
227 final Object newValue = newExtras.get(key);
228 if (!Objects.equals(value, newValue)) {
229 return false;
230 }
231 }
232 }
233 return true;
234 }
Andrii Kulian88e05cb2017-12-05 17:21:10 -0800235
236 @Override
237 public String toString() {
238 return "LaunchActivityItem{intent=" + mIntent + ",ident=" + mIdent + ",info=" + mInfo
239 + ",curConfig=" + mCurConfig + ",overrideConfig=" + mOverrideConfig
240 + ",referrer=" + mReferrer + ",procState=" + mProcState + ",state=" + mState
241 + ",persistentState=" + mPersistentState + ",pendingResults=" + mPendingResults
242 + ",pendingNewIntents=" + mPendingNewIntents + ",profilerInfo=" + mProfilerInfo
243 + "}";
244 }
Andrii Kulian9c5ea9c2017-12-07 09:31:01 -0800245
246 // Using the same method to set and clear values to make sure we don't forget anything
247 private static void setValues(LaunchActivityItem instance, Intent intent, int ident,
248 ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
249 CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
250 int procState, Bundle state, PersistableBundle persistentState,
251 List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
252 boolean isForward, ProfilerInfo profilerInfo) {
253 instance.mIntent = intent;
254 instance.mIdent = ident;
255 instance.mInfo = info;
256 instance.mCurConfig = curConfig;
257 instance.mOverrideConfig = overrideConfig;
258 instance.mCompatInfo = compatInfo;
259 instance.mReferrer = referrer;
260 instance.mVoiceInteractor = voiceInteractor;
261 instance.mProcState = procState;
262 instance.mState = state;
263 instance.mPersistentState = persistentState;
264 instance.mPendingResults = pendingResults;
265 instance.mPendingNewIntents = pendingNewIntents;
266 instance.mIsForward = isForward;
267 instance.mProfilerInfo = profilerInfo;
268 }
Andrii Kulian446e8242017-10-26 15:17:29 -0700269}