blob: 4c93d09503884faf6266dcfe0eefee88c5f030c9 [file] [log] [blame]
/*
* Copyright (C) 2020 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.content.pm.parsing.component;
import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE;
import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.content.pm.parsing.ParsingPackageImpl.sForInternedString;
import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_UNSPECIFIED;
import android.annotation.Nullable;
import android.app.ActivityTaskManager;
import android.content.ComponentName;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageParser;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import com.android.internal.util.DataClass;
import com.android.internal.util.Parcelling.BuiltIn.ForInternedString;
/** @hide **/
public class ParsedActivity extends ParsedMainComponent {
int theme;
int uiOptions;
@Nullable
@DataClass.ParcelWith(ForInternedString.class)
private String targetActivity;
@Nullable
@DataClass.ParcelWith(ForInternedString.class)
private String parentActivityName;
@Nullable
String taskAffinity;
int privateFlags;
@Nullable
@DataClass.ParcelWith(ForInternedString.class)
private String permission;
int launchMode;
int documentLaunchMode;
int maxRecents;
int configChanges;
int softInputMode;
int persistableMode;
int lockTaskLaunchMode;
int screenOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
int resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
@Nullable
private Float maxAspectRatio;
@Nullable
private Float minAspectRatio;
@Nullable
String requestedVrComponent;
int rotationAnimation = -1;
int colorMode;
@Nullable
ActivityInfo.WindowLayout windowLayout;
public ParsedActivity(ParsedActivity other) {
super(other);
this.theme = other.theme;
this.uiOptions = other.uiOptions;
this.targetActivity = other.targetActivity;
this.parentActivityName = other.parentActivityName;
this.taskAffinity = other.taskAffinity;
this.privateFlags = other.privateFlags;
this.permission = other.permission;
this.launchMode = other.launchMode;
this.documentLaunchMode = other.documentLaunchMode;
this.maxRecents = other.maxRecents;
this.configChanges = other.configChanges;
this.softInputMode = other.softInputMode;
this.persistableMode = other.persistableMode;
this.lockTaskLaunchMode = other.lockTaskLaunchMode;
this.screenOrientation = other.screenOrientation;
this.resizeMode = other.resizeMode;
this.maxAspectRatio = other.maxAspectRatio;
this.minAspectRatio = other.minAspectRatio;
this.requestedVrComponent = other.requestedVrComponent;
this.rotationAnimation = other.rotationAnimation;
this.colorMode = other.colorMode;
this.windowLayout = other.windowLayout;
}
/**
* Generate activity object that forwards user to App Details page automatically.
* This activity should be invisible to user and user should not know or see it.
*/
public static ParsedActivity makeAppDetailsActivity(String packageName, String processName,
int uiOptions, String taskAffinity, boolean hardwareAccelerated) {
ParsedActivity activity = new ParsedActivity();
activity.setPackageName(packageName);
activity.theme = android.R.style.Theme_NoDisplay;
activity.exported = true;
activity.setName(PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME);
activity.setProcessName(processName);
activity.uiOptions = uiOptions;
activity.taskAffinity = taskAffinity;
activity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
activity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NONE;
activity.maxRecents = ActivityTaskManager.getDefaultAppRecentsLimitStatic();
activity.configChanges = PackageParser.getActivityConfigChanges(0, 0);
activity.softInputMode = 0;
activity.persistableMode = ActivityInfo.PERSIST_NEVER;
activity.screenOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
activity.resizeMode = RESIZE_MODE_FORCE_RESIZEABLE;
activity.lockTaskLaunchMode = 0;
activity.setDirectBootAware(false);
activity.rotationAnimation = ROTATION_ANIMATION_UNSPECIFIED;
activity.colorMode = ActivityInfo.COLOR_MODE_DEFAULT;
if (hardwareAccelerated) {
activity.setFlags(activity.getFlags() | ActivityInfo.FLAG_HARDWARE_ACCELERATED);
}
return activity;
}
static ParsedActivity makeAlias(String targetActivityName, ParsedActivity target) {
ParsedActivity alias = new ParsedActivity();
alias.setPackageName(target.getPackageName());
alias.setTargetActivity(targetActivityName);
alias.configChanges = target.configChanges;
alias.flags = target.flags;
alias.privateFlags = target.privateFlags;
alias.icon = target.icon;
alias.logo = target.logo;
alias.banner = target.banner;
alias.labelRes = target.labelRes;
alias.nonLocalizedLabel = target.nonLocalizedLabel;
alias.launchMode = target.launchMode;
alias.lockTaskLaunchMode = target.lockTaskLaunchMode;
alias.descriptionRes = target.descriptionRes;
alias.screenOrientation = target.screenOrientation;
alias.taskAffinity = target.taskAffinity;
alias.theme = target.theme;
alias.softInputMode = target.softInputMode;
alias.uiOptions = target.uiOptions;
alias.parentActivityName = target.parentActivityName;
alias.maxRecents = target.maxRecents;
alias.windowLayout = target.windowLayout;
alias.resizeMode = target.resizeMode;
alias.maxAspectRatio = target.maxAspectRatio;
alias.minAspectRatio = target.minAspectRatio;
alias.requestedVrComponent = target.requestedVrComponent;
alias.directBootAware = target.directBootAware;
alias.setProcessName(target.getProcessName());
return alias;
// Not all attributes from the target ParsedActivity are copied to the alias.
// Careful when adding an attribute and determine whether or not it should be copied.
// alias.enabled = target.enabled;
// alias.exported = target.exported;
// alias.permission = target.permission;
// alias.splitName = target.splitName;
// alias.documentLaunchMode = target.documentLaunchMode;
// alias.persistableMode = target.persistableMode;
// alias.rotationAnimation = target.rotationAnimation;
// alias.colorMode = target.colorMode;
// alias.intents.addAll(target.intents);
// alias.order = target.order;
// alias.metaData = target.metaData;
}
public ParsedActivity setMaxAspectRatio(int resizeMode, float maxAspectRatio) {
if (resizeMode == ActivityInfo.RESIZE_MODE_RESIZEABLE
|| resizeMode == ActivityInfo.RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION) {
// Resizeable activities can be put in any aspect ratio.
return this;
}
if (maxAspectRatio < 1.0f && maxAspectRatio != 0) {
// Ignore any value lesser than 1.0.
return this;
}
this.maxAspectRatio = maxAspectRatio;
return this;
}
public ParsedActivity setMinAspectRatio(int resizeMode, float minAspectRatio) {
if (resizeMode == RESIZE_MODE_RESIZEABLE
|| resizeMode == RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION) {
// Resizeable activities can be put in any aspect ratio.
return this;
}
if (minAspectRatio < 1.0f && minAspectRatio != 0) {
// Ignore any value lesser than 1.0.
return this;
}
this.minAspectRatio = minAspectRatio;
return this;
}
public ParsedActivity setFlags(int flags) {
this.flags = flags;
return this;
}
public ParsedActivity setResizeMode(int resizeMode) {
this.resizeMode = resizeMode;
return this;
}
public ParsedActivity setTargetActivity(String targetActivity) {
this.targetActivity = TextUtils.safeIntern(targetActivity);
return this;
}
public ParsedActivity setParentActivity(String parentActivity) {
this.parentActivityName = TextUtils.safeIntern(parentActivity);
return this;
}
public ParsedActivity setPermission(String permission) {
// Empty string must be converted to null
this.permission = TextUtils.isEmpty(permission) ? null : permission.intern();
return this;
}
public String toString() {
StringBuilder sb = new StringBuilder(128);
sb.append("Activity{");
sb.append(Integer.toHexString(System.identityHashCode(this)));
sb.append(' ');
ComponentName.appendShortString(sb, getPackageName(), getName());
sb.append('}');
return sb.toString();
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeInt(this.theme);
dest.writeInt(this.uiOptions);
dest.writeString(this.targetActivity);
dest.writeString(this.parentActivityName);
dest.writeString(this.taskAffinity);
dest.writeInt(this.privateFlags);
sForInternedString.parcel(this.permission, dest, flags);
dest.writeInt(this.launchMode);
dest.writeInt(this.documentLaunchMode);
dest.writeInt(this.maxRecents);
dest.writeInt(this.configChanges);
dest.writeInt(this.softInputMode);
dest.writeInt(this.persistableMode);
dest.writeInt(this.lockTaskLaunchMode);
dest.writeInt(this.screenOrientation);
dest.writeInt(this.resizeMode);
dest.writeValue(this.maxAspectRatio);
dest.writeValue(this.minAspectRatio);
dest.writeString(this.requestedVrComponent);
dest.writeInt(this.rotationAnimation);
dest.writeInt(this.colorMode);
dest.writeBundle(this.metaData);
if (windowLayout != null) {
dest.writeInt(1);
windowLayout.writeToParcel(dest);
} else {
dest.writeBoolean(false);
}
}
public ParsedActivity() {
}
protected ParsedActivity(Parcel in) {
super(in);
this.theme = in.readInt();
this.uiOptions = in.readInt();
this.targetActivity = in.readString();
this.parentActivityName = in.readString();
this.taskAffinity = in.readString();
this.privateFlags = in.readInt();
this.permission = sForInternedString.unparcel(in);
this.launchMode = in.readInt();
this.documentLaunchMode = in.readInt();
this.maxRecents = in.readInt();
this.configChanges = in.readInt();
this.softInputMode = in.readInt();
this.persistableMode = in.readInt();
this.lockTaskLaunchMode = in.readInt();
this.screenOrientation = in.readInt();
this.resizeMode = in.readInt();
this.maxAspectRatio = (Float) in.readValue(Float.class.getClassLoader());
this.minAspectRatio = (Float) in.readValue(Float.class.getClassLoader());
this.requestedVrComponent = in.readString();
this.rotationAnimation = in.readInt();
this.colorMode = in.readInt();
this.metaData = in.readBundle();
if (in.readBoolean()) {
windowLayout = new ActivityInfo.WindowLayout(in);
}
}
public static final Parcelable.Creator<ParsedActivity> CREATOR = new Creator<ParsedActivity>() {
@Override
public ParsedActivity createFromParcel(Parcel source) {
return new ParsedActivity(source);
}
@Override
public ParsedActivity[] newArray(int size) {
return new ParsedActivity[size];
}
};
public int getTheme() {
return theme;
}
public int getUiOptions() {
return uiOptions;
}
@Nullable
public String getTargetActivity() {
return targetActivity;
}
@Nullable
public String getParentActivityName() {
return parentActivityName;
}
@Nullable
public String getTaskAffinity() {
return taskAffinity;
}
public int getPrivateFlags() {
return privateFlags;
}
@Nullable
public String getPermission() {
return permission;
}
public int getLaunchMode() {
return launchMode;
}
public int getDocumentLaunchMode() {
return documentLaunchMode;
}
public int getMaxRecents() {
return maxRecents;
}
public int getConfigChanges() {
return configChanges;
}
public int getSoftInputMode() {
return softInputMode;
}
public int getPersistableMode() {
return persistableMode;
}
public int getLockTaskLaunchMode() {
return lockTaskLaunchMode;
}
public int getScreenOrientation() {
return screenOrientation;
}
public int getResizeMode() {
return resizeMode;
}
@Nullable
public Float getMaxAspectRatio() {
return maxAspectRatio;
}
@Nullable
public Float getMinAspectRatio() {
return minAspectRatio;
}
@Nullable
public String getRequestedVrComponent() {
return requestedVrComponent;
}
public int getRotationAnimation() {
return rotationAnimation;
}
public int getColorMode() {
return colorMode;
}
@Nullable
public ActivityInfo.WindowLayout getWindowLayout() {
return windowLayout;
}
}