Andrii Kulian | 446e824 | 2017-10-26 15:17:29 -0700 | [diff] [blame] | 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.os.Trace.TRACE_TAG_ACTIVITY_MANAGER; |
| 20 | |
Mathew Inwood | 98e9ad1 | 2018-08-30 13:11:50 +0100 | [diff] [blame] | 21 | import android.annotation.UnsupportedAppUsage; |
Andrii Kulian | 88e05cb | 2017-12-05 17:21:10 -0800 | [diff] [blame] | 22 | import android.app.ActivityThread.ActivityClientRecord; |
Andrii Kulian | 446e824 | 2017-10-26 15:17:29 -0700 | [diff] [blame] | 23 | import android.app.ClientTransactionHandler; |
| 24 | import android.app.ProfilerInfo; |
| 25 | import android.app.ResultInfo; |
| 26 | import android.content.Intent; |
| 27 | import android.content.pm.ActivityInfo; |
| 28 | import android.content.res.CompatibilityInfo; |
| 29 | import android.content.res.Configuration; |
Andrii Kulian | 6b9d3a1 | 2017-11-16 14:36:36 -0800 | [diff] [blame] | 30 | import android.os.BaseBundle; |
Andrii Kulian | 446e824 | 2017-10-26 15:17:29 -0700 | [diff] [blame] | 31 | import android.os.Bundle; |
| 32 | import android.os.IBinder; |
| 33 | import android.os.Parcel; |
| 34 | import android.os.PersistableBundle; |
| 35 | import android.os.Trace; |
| 36 | |
| 37 | import com.android.internal.app.IVoiceInteractor; |
| 38 | import com.android.internal.content.ReferrerIntent; |
| 39 | |
| 40 | import java.util.List; |
Andrii Kulian | 6b9d3a1 | 2017-11-16 14:36:36 -0800 | [diff] [blame] | 41 | import java.util.Objects; |
Andrii Kulian | 446e824 | 2017-10-26 15:17:29 -0700 | [diff] [blame] | 42 | |
| 43 | /** |
| 44 | * Request to launch an activity. |
| 45 | * @hide |
| 46 | */ |
Andrii Kulian | 88e05cb | 2017-12-05 17:21:10 -0800 | [diff] [blame] | 47 | public class LaunchActivityItem extends ClientTransactionItem { |
Andrii Kulian | 446e824 | 2017-10-26 15:17:29 -0700 | [diff] [blame] | 48 | |
Mathew Inwood | 98e9ad1 | 2018-08-30 13:11:50 +0100 | [diff] [blame] | 49 | @UnsupportedAppUsage |
Andrii Kulian | 9c5ea9c | 2017-12-07 09:31:01 -0800 | [diff] [blame] | 50 | private Intent mIntent; |
| 51 | private int mIdent; |
Mathew Inwood | 98e9ad1 | 2018-08-30 13:11:50 +0100 | [diff] [blame] | 52 | @UnsupportedAppUsage |
Andrii Kulian | 9c5ea9c | 2017-12-07 09:31:01 -0800 | [diff] [blame] | 53 | 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 Kulian | 446e824 | 2017-10-26 15:17:29 -0700 | [diff] [blame] | 66 | |
| 67 | @Override |
Andrii Kulian | 88e05cb | 2017-12-05 17:21:10 -0800 | [diff] [blame] | 68 | public void preExecute(ClientTransactionHandler client, IBinder token) { |
Andrii Kulian | 446e824 | 2017-10-26 15:17:29 -0700 | [diff] [blame] | 69 | client.updateProcessState(mProcState, false); |
| 70 | client.updatePendingConfiguration(mCurConfig); |
| 71 | } |
| 72 | |
| 73 | @Override |
Andrii Kulian | 88e05cb | 2017-12-05 17:21:10 -0800 | [diff] [blame] | 74 | public void execute(ClientTransactionHandler client, IBinder token, |
| 75 | PendingTransactionActions pendingActions) { |
Andrii Kulian | 446e824 | 2017-10-26 15:17:29 -0700 | [diff] [blame] | 76 | Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart"); |
Andrii Kulian | 88e05cb | 2017-12-05 17:21:10 -0800 | [diff] [blame] | 77 | ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo, |
| 78 | mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState, |
| 79 | mPendingResults, mPendingNewIntents, mIsForward, |
| 80 | mProfilerInfo, client); |
Andrii Kulian | 770c403 | 2018-05-02 18:40:59 -0700 | [diff] [blame] | 81 | client.handleLaunchActivity(r, pendingActions, null /* customIntent */); |
Andrii Kulian | 446e824 | 2017-10-26 15:17:29 -0700 | [diff] [blame] | 82 | Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); |
| 83 | } |
| 84 | |
Andrii Kulian | 446e824 | 2017-10-26 15:17:29 -0700 | [diff] [blame] | 85 | |
Andrii Kulian | 9c5ea9c | 2017-12-07 09:31:01 -0800 | [diff] [blame] | 86 | // 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 Kulian | 446e824 | 2017-10-26 15:17:29 -0700 | [diff] [blame] | 115 | // 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 Kulian | 9c5ea9c | 2017-12-07 09:31:01 -0800 | [diff] [blame] | 127 | dest.writeStrongInterface(mVoiceInteractor); |
Andrii Kulian | 446e824 | 2017-10-26 15:17:29 -0700 | [diff] [blame] | 128 | dest.writeInt(mProcState); |
| 129 | dest.writeBundle(mState); |
| 130 | dest.writePersistableBundle(mPersistentState); |
| 131 | dest.writeTypedList(mPendingResults, flags); |
| 132 | dest.writeTypedList(mPendingNewIntents, flags); |
Andrii Kulian | 446e824 | 2017-10-26 15:17:29 -0700 | [diff] [blame] | 133 | dest.writeBoolean(mIsForward); |
| 134 | dest.writeTypedObject(mProfilerInfo, flags); |
| 135 | } |
| 136 | |
| 137 | /** Read from Parcel. */ |
| 138 | private LaunchActivityItem(Parcel in) { |
Andrii Kulian | 9c5ea9c | 2017-12-07 09:31:01 -0800 | [diff] [blame] | 139 | 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 Kulian | 446e824 | 2017-10-26 15:17:29 -0700 | [diff] [blame] | 149 | } |
| 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 Kulian | 6b9d3a1 | 2017-11-16 14:36:36 -0800 | [diff] [blame] | 161 | |
| 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 Kulian | 9c5ea9c | 2017-12-07 09:31:01 -0800 | [diff] [blame] | 171 | final boolean intentsEqual = (mIntent == null && other.mIntent == null) |
| 172 | || (mIntent != null && mIntent.filterEquals(other.mIntent)); |
| 173 | return intentsEqual && mIdent == other.mIdent |
Andrii Kulian | 6b9d3a1 | 2017-11-16 14:36:36 -0800 | [diff] [blame] | 174 | && 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 Kulian | 88e05cb | 2017-12-05 17:21:10 -0800 | [diff] [blame] | 182 | && mIsForward == other.mIsForward |
Andrii Kulian | 6b9d3a1 | 2017-11-16 14:36:36 -0800 | [diff] [blame] | 183 | && 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 Kulian | 6b9d3a1 | 2017-11-16 14:36:36 -0800 | [diff] [blame] | 200 | 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 Kulian | 9c5ea9c | 2017-12-07 09:31:01 -0800 | [diff] [blame] | 206 | if (mInfo == null) { |
| 207 | return other == null; |
| 208 | } |
| 209 | return other != null && mInfo.flags == other.flags |
| 210 | && mInfo.maxAspectRatio == other.maxAspectRatio |
Andrii Kulian | 6b9d3a1 | 2017-11-16 14:36:36 -0800 | [diff] [blame] | 211 | && 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 Kulian | 88e05cb | 2017-12-05 17:21:10 -0800 | [diff] [blame] | 235 | |
| 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 Kulian | 9c5ea9c | 2017-12-07 09:31:01 -0800 | [diff] [blame] | 245 | |
| 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 Kulian | 446e824 | 2017-10-26 15:17:29 -0700 | [diff] [blame] | 269 | } |