blob: 417ebac8ea201fceddad1cddf7908b09cad7493d [file] [log] [blame]
/*
* Copyright 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.app.servertransaction;
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
import android.app.ClientTransactionHandler;
import android.app.ProfilerInfo;
import android.app.ResultInfo;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.os.BaseBundle;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Parcel;
import android.os.PersistableBundle;
import android.os.Trace;
import com.android.internal.app.IVoiceInteractor;
import com.android.internal.content.ReferrerIntent;
import java.util.List;
import java.util.Objects;
/**
* Request to launch an activity.
* @hide
*/
public class LaunchActivityItem extends ActivityLifecycleItem {
private final Intent mIntent;
private final int mIdent;
private final ActivityInfo mInfo;
private final Configuration mCurConfig;
private final Configuration mOverrideConfig;
private final CompatibilityInfo mCompatInfo;
private final String mReferrer;
private final IVoiceInteractor mVoiceInteractor;
private final int mProcState;
private final Bundle mState;
private final PersistableBundle mPersistentState;
private final List<ResultInfo> mPendingResults;
private final List<ReferrerIntent> mPendingNewIntents;
// TODO(lifecycler): use lifecycle request instead of this param.
private final boolean mNotResumed;
private final boolean mIsForward;
private final ProfilerInfo mProfilerInfo;
public LaunchActivityItem(Intent intent, int ident, ActivityInfo info,
Configuration curConfig, Configuration overrideConfig, CompatibilityInfo compatInfo,
String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state,
PersistableBundle persistentState, List<ResultInfo> pendingResults,
List<ReferrerIntent> pendingNewIntents, boolean notResumed, boolean isForward,
ProfilerInfo profilerInfo) {
mIntent = intent;
mIdent = ident;
mInfo = info;
mCurConfig = curConfig;
mOverrideConfig = overrideConfig;
mCompatInfo = compatInfo;
mReferrer = referrer;
mVoiceInteractor = voiceInteractor;
mProcState = procState;
mState = state;
mPersistentState = persistentState;
mPendingResults = pendingResults;
mPendingNewIntents = pendingNewIntents;
mNotResumed = notResumed;
mIsForward = isForward;
mProfilerInfo = profilerInfo;
}
@Override
public void prepare(ClientTransactionHandler client, IBinder token) {
client.updateProcessState(mProcState, false);
client.updatePendingConfiguration(mCurConfig);
}
@Override
public void execute(ClientTransactionHandler client, IBinder token) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
client.handleLaunchActivity(token, mIntent, mIdent, mInfo, mOverrideConfig, mCompatInfo,
mReferrer, mVoiceInteractor, mState, mPersistentState, mPendingResults,
mPendingNewIntents, mNotResumed, mIsForward, mProfilerInfo);
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
@Override
public int getTargetState() {
return mNotResumed ? PAUSED : RESUMED;
}
// Parcelable implementation
/** Write from Parcel. */
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeTypedObject(mIntent, flags);
dest.writeInt(mIdent);
dest.writeTypedObject(mInfo, flags);
dest.writeTypedObject(mCurConfig, flags);
dest.writeTypedObject(mOverrideConfig, flags);
dest.writeTypedObject(mCompatInfo, flags);
dest.writeString(mReferrer);
dest.writeStrongBinder(mVoiceInteractor != null ? mVoiceInteractor.asBinder() : null);
dest.writeInt(mProcState);
dest.writeBundle(mState);
dest.writePersistableBundle(mPersistentState);
dest.writeTypedList(mPendingResults, flags);
dest.writeTypedList(mPendingNewIntents, flags);
dest.writeBoolean(mNotResumed);
dest.writeBoolean(mIsForward);
dest.writeTypedObject(mProfilerInfo, flags);
}
/** Read from Parcel. */
private LaunchActivityItem(Parcel in) {
mIntent = in.readTypedObject(Intent.CREATOR);
mIdent = in.readInt();
mInfo = in.readTypedObject(ActivityInfo.CREATOR);
mCurConfig = in.readTypedObject(Configuration.CREATOR);
mOverrideConfig = in.readTypedObject(Configuration.CREATOR);
mCompatInfo = in.readTypedObject(CompatibilityInfo.CREATOR);
mReferrer = in.readString();
mVoiceInteractor = (IVoiceInteractor) in.readStrongBinder();
mProcState = in.readInt();
mState = in.readBundle(getClass().getClassLoader());
mPersistentState = in.readPersistableBundle(getClass().getClassLoader());
mPendingResults = in.createTypedArrayList(ResultInfo.CREATOR);
mPendingNewIntents = in.createTypedArrayList(ReferrerIntent.CREATOR);
mNotResumed = in.readBoolean();
mIsForward = in.readBoolean();
mProfilerInfo = in.readTypedObject(ProfilerInfo.CREATOR);
}
public static final Creator<LaunchActivityItem> CREATOR =
new Creator<LaunchActivityItem>() {
public LaunchActivityItem createFromParcel(Parcel in) {
return new LaunchActivityItem(in);
}
public LaunchActivityItem[] newArray(int size) {
return new LaunchActivityItem[size];
}
};
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final LaunchActivityItem other = (LaunchActivityItem) o;
return mIntent.filterEquals(other.mIntent) && mIdent == other.mIdent
&& activityInfoEqual(other.mInfo) && Objects.equals(mCurConfig, other.mCurConfig)
&& Objects.equals(mOverrideConfig, other.mOverrideConfig)
&& Objects.equals(mCompatInfo, other.mCompatInfo)
&& Objects.equals(mReferrer, other.mReferrer)
&& mProcState == other.mProcState && areBundlesEqual(mState, other.mState)
&& areBundlesEqual(mPersistentState, other.mPersistentState)
&& Objects.equals(mPendingResults, other.mPendingResults)
&& Objects.equals(mPendingNewIntents, other.mPendingNewIntents)
&& mNotResumed == other.mNotResumed && mIsForward == other.mIsForward
&& Objects.equals(mProfilerInfo, other.mProfilerInfo);
}
@Override
public int hashCode() {
int result = 17;
result = 31 * result + mIntent.filterHashCode();
result = 31 * result + mIdent;
result = 31 * result + Objects.hashCode(mCurConfig);
result = 31 * result + Objects.hashCode(mOverrideConfig);
result = 31 * result + Objects.hashCode(mCompatInfo);
result = 31 * result + Objects.hashCode(mReferrer);
result = 31 * result + Objects.hashCode(mProcState);
result = 31 * result + (mState != null ? mState.size() : 0);
result = 31 * result + (mPersistentState != null ? mPersistentState.size() : 0);
result = 31 * result + Objects.hashCode(mPendingResults);
result = 31 * result + Objects.hashCode(mPendingNewIntents);
result = 31 * result + (mNotResumed ? 1 : 0);
result = 31 * result + (mIsForward ? 1 : 0);
result = 31 * result + Objects.hashCode(mProfilerInfo);
return result;
}
private boolean activityInfoEqual(ActivityInfo other) {
return mInfo.flags == other.flags && mInfo.maxAspectRatio == other.maxAspectRatio
&& Objects.equals(mInfo.launchToken, other.launchToken)
&& Objects.equals(mInfo.getComponentName(), other.getComponentName());
}
private static boolean areBundlesEqual(BaseBundle extras, BaseBundle newExtras) {
if (extras == null || newExtras == null) {
return extras == newExtras;
}
if (extras.size() != newExtras.size()) {
return false;
}
for (String key : extras.keySet()) {
if (key != null) {
final Object value = extras.get(key);
final Object newValue = newExtras.get(key);
if (!Objects.equals(value, newValue)) {
return false;
}
}
}
return true;
}
}