Merge "Define a new manifest attribute targetDisplayCategory in <activity> tag and parse into ActivityInfo through string validation"
This commit is contained in:
@@ -1492,6 +1492,7 @@ package android {
|
||||
field public static final int targetCellWidth = 16844340; // 0x1010634
|
||||
field public static final int targetClass = 16842799; // 0x101002f
|
||||
field @Deprecated public static final int targetDescriptions = 16843680; // 0x10103a0
|
||||
field public static final int targetDisplayCategory;
|
||||
field public static final int targetId = 16843740; // 0x10103dc
|
||||
field public static final int targetName = 16843853; // 0x101044d
|
||||
field public static final int targetPackage = 16842785; // 0x1010021
|
||||
@@ -11138,6 +11139,7 @@ package android.content.pm {
|
||||
field public int screenOrientation;
|
||||
field public int softInputMode;
|
||||
field public String targetActivity;
|
||||
field @Nullable public String targetDisplayCategory;
|
||||
field public String taskAffinity;
|
||||
field public int theme;
|
||||
field public int uiOptions;
|
||||
|
||||
@@ -220,6 +220,23 @@ public class ActivityInfo extends ComponentInfo implements Parcelable {
|
||||
*/
|
||||
public String launchToken;
|
||||
|
||||
/**
|
||||
* Specifies the category of the target display the activity is expected to run on. Set from
|
||||
* the {@link android.R.attr#targetDisplayCategory} attribute. Upon creation, a virtual display
|
||||
* can specify which display categories it supports and one of the category must be present in
|
||||
* the activity's manifest to allow this activity to run. The default value is {@code null},
|
||||
* which indicates the activity does not belong to a restricted display category and thus can
|
||||
* only run on a display that didn't specify any display categories. Each activity can only
|
||||
* specify one category it targets to but a virtual display can support multiple restricted
|
||||
* categories.
|
||||
*
|
||||
* This field should be formatted as a Java-language-style free form string(for example,
|
||||
* com.google.automotive_entertainment), which may contain uppercase or lowercase letters ('A'
|
||||
* through 'Z'), numbers, and underscores ('_') but may only start with letters.
|
||||
*/
|
||||
@Nullable
|
||||
public String targetDisplayCategory;
|
||||
|
||||
/**
|
||||
* Activity can not be resized and always occupies the fullscreen area with all windows fully
|
||||
* visible.
|
||||
@@ -1313,6 +1330,7 @@ public class ActivityInfo extends ComponentInfo implements Parcelable {
|
||||
mMaxAspectRatio = orig.mMaxAspectRatio;
|
||||
mMinAspectRatio = orig.mMinAspectRatio;
|
||||
supportsSizeChanges = orig.supportsSizeChanges;
|
||||
targetDisplayCategory = orig.targetDisplayCategory;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1651,6 +1669,9 @@ public class ActivityInfo extends ComponentInfo implements Parcelable {
|
||||
if (mKnownActivityEmbeddingCerts != null) {
|
||||
pw.println(prefix + "knownActivityEmbeddingCerts=" + mKnownActivityEmbeddingCerts);
|
||||
}
|
||||
if (targetDisplayCategory != null) {
|
||||
pw.println(prefix + "targetDisplayCategory=" + targetDisplayCategory);
|
||||
}
|
||||
super.dumpBack(pw, prefix, dumpFlags);
|
||||
}
|
||||
|
||||
@@ -1697,6 +1718,7 @@ public class ActivityInfo extends ComponentInfo implements Parcelable {
|
||||
dest.writeFloat(mMinAspectRatio);
|
||||
dest.writeBoolean(supportsSizeChanges);
|
||||
sForStringSet.parcel(mKnownActivityEmbeddingCerts, dest, flags);
|
||||
dest.writeString8(targetDisplayCategory);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1822,6 +1844,7 @@ public class ActivityInfo extends ComponentInfo implements Parcelable {
|
||||
if (mKnownActivityEmbeddingCerts.isEmpty()) {
|
||||
mKnownActivityEmbeddingCerts = null;
|
||||
}
|
||||
targetDisplayCategory = source.readString8();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3062,6 +3062,20 @@
|
||||
<attr name="canDisplayOnRemoteDevices" format="boolean"/>
|
||||
<attr name="allowUntrustedActivityEmbedding" />
|
||||
<attr name="knownActivityEmbeddingCerts" />
|
||||
<!-- Specifies the category of the target display the activity is expected to run on. Upon
|
||||
creation, a virtual display can specify which display categories it supports and one of
|
||||
the category must be present in the activity's manifest to allow this activity to run.
|
||||
The default value is {@code null}, which indicates the activity does not belong to a
|
||||
restricted display category and thus can only run on a display that didn't specify any
|
||||
display categories. Each activity can only specify one category it targets to but a
|
||||
virtual display can accommodate multiple restricted categories.
|
||||
|
||||
<p> This field should be formatted as a Java-language-style free form string(for
|
||||
example, com.google.automotive_entertainment), which may contain uppercase or lowercase
|
||||
letters ('A' through 'Z'), numbers, and underscores ('_') but may only start with
|
||||
letters.
|
||||
-->
|
||||
<attr name="targetDisplayCategory" format="string"/>
|
||||
</declare-styleable>
|
||||
|
||||
<!-- The <code>activity-alias</code> tag declares a new
|
||||
|
||||
@@ -116,6 +116,7 @@
|
||||
<public name="handwritingBoundsOffsetBottom" />
|
||||
<public name="accessibilityDataPrivate" />
|
||||
<public name="enableTextStylingShortcuts" />
|
||||
<public name="targetDisplayCategory"/>
|
||||
</staging-public-group>
|
||||
|
||||
<staging-public-group type="id" first-id="0x01cd0000">
|
||||
|
||||
@@ -570,6 +570,7 @@ public class PackageInfoUtils {
|
||||
ai.metaData = null;
|
||||
}
|
||||
ai.applicationInfo = applicationInfo;
|
||||
ai.targetDisplayCategory = a.getTargetDisplayCategory();
|
||||
ai.setKnownActivityEmbeddingCerts(a.getKnownActivityEmbeddingCerts());
|
||||
assignFieldsComponentInfoParsedMainComponent(ai, a, pkgSetting, userId);
|
||||
return ai;
|
||||
|
||||
@@ -96,4 +96,10 @@ public interface ParsedActivity extends ParsedMainComponent {
|
||||
ActivityInfo.WindowLayout getWindowLayout();
|
||||
|
||||
boolean isSupportsSizeChanges();
|
||||
|
||||
/**
|
||||
* Gets the category of the target display this activity is supposed to run on.
|
||||
*/
|
||||
@Nullable
|
||||
String getTargetDisplayCategory();
|
||||
}
|
||||
|
||||
@@ -96,6 +96,9 @@ public class ParsedActivityImpl extends ParsedMainComponentImpl implements Parse
|
||||
@Nullable
|
||||
private ActivityInfo.WindowLayout windowLayout;
|
||||
|
||||
@Nullable
|
||||
private String mTargetDisplayCategory;
|
||||
|
||||
public ParsedActivityImpl(ParsedActivityImpl other) {
|
||||
super(other);
|
||||
this.theme = other.theme;
|
||||
@@ -122,6 +125,7 @@ public class ParsedActivityImpl extends ParsedMainComponentImpl implements Parse
|
||||
this.colorMode = other.colorMode;
|
||||
this.windowLayout = other.windowLayout;
|
||||
this.mKnownActivityEmbeddingCerts = other.mKnownActivityEmbeddingCerts;
|
||||
this.mTargetDisplayCategory = other.mTargetDisplayCategory;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -189,6 +193,7 @@ public class ParsedActivityImpl extends ParsedMainComponentImpl implements Parse
|
||||
alias.requestedVrComponent = target.getRequestedVrComponent();
|
||||
alias.setDirectBootAware(target.isDirectBootAware());
|
||||
alias.setProcessName(target.getProcessName());
|
||||
alias.setTargetDisplayCategory(target.getTargetDisplayCategory());
|
||||
return alias;
|
||||
|
||||
// Not all attributes from the target ParsedActivity are copied to the alias.
|
||||
@@ -316,6 +321,7 @@ public class ParsedActivityImpl extends ParsedMainComponentImpl implements Parse
|
||||
dest.writeBoolean(false);
|
||||
}
|
||||
sForStringSet.parcel(this.mKnownActivityEmbeddingCerts, dest, flags);
|
||||
dest.writeString8(this.mTargetDisplayCategory);
|
||||
}
|
||||
|
||||
public ParsedActivityImpl() {
|
||||
@@ -350,6 +356,7 @@ public class ParsedActivityImpl extends ParsedMainComponentImpl implements Parse
|
||||
windowLayout = new ActivityInfo.WindowLayout(in);
|
||||
}
|
||||
this.mKnownActivityEmbeddingCerts = sForStringSet.unparcel(in);
|
||||
this.mTargetDisplayCategory = in.readString8();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@@ -406,7 +413,8 @@ public class ParsedActivityImpl extends ParsedMainComponentImpl implements Parse
|
||||
@Nullable String requestedVrComponent,
|
||||
int rotationAnimation,
|
||||
int colorMode,
|
||||
@Nullable ActivityInfo.WindowLayout windowLayout) {
|
||||
@Nullable ActivityInfo.WindowLayout windowLayout,
|
||||
@Nullable String targetDisplayCategory) {
|
||||
this.theme = theme;
|
||||
this.uiOptions = uiOptions;
|
||||
this.targetActivity = targetActivity;
|
||||
@@ -431,6 +439,7 @@ public class ParsedActivityImpl extends ParsedMainComponentImpl implements Parse
|
||||
this.rotationAnimation = rotationAnimation;
|
||||
this.colorMode = colorMode;
|
||||
this.windowLayout = windowLayout;
|
||||
this.mTargetDisplayCategory = targetDisplayCategory;
|
||||
|
||||
// onConstructed(); // You can define this method to get a callback
|
||||
}
|
||||
@@ -550,6 +559,11 @@ public class ParsedActivityImpl extends ParsedMainComponentImpl implements Parse
|
||||
return windowLayout;
|
||||
}
|
||||
|
||||
@DataClass.Generated.Member
|
||||
public @Nullable String getTargetDisplayCategory() {
|
||||
return mTargetDisplayCategory;
|
||||
}
|
||||
|
||||
@DataClass.Generated.Member
|
||||
public @NonNull ParsedActivityImpl setTheme( int value) {
|
||||
theme = value;
|
||||
@@ -676,11 +690,17 @@ public class ParsedActivityImpl extends ParsedMainComponentImpl implements Parse
|
||||
return this;
|
||||
}
|
||||
|
||||
@DataClass.Generated.Member
|
||||
public @NonNull ParsedActivityImpl setTargetDisplayCategory(@NonNull String value) {
|
||||
mTargetDisplayCategory = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
@DataClass.Generated(
|
||||
time = 1644372875433L,
|
||||
time = 1664805688714L,
|
||||
codegenVersion = "1.0.23",
|
||||
sourceFile = "frameworks/base/services/core/java/com/android/server/pm/pkg/component/ParsedActivityImpl.java",
|
||||
inputSignatures = "private int theme\nprivate int uiOptions\nprivate @android.annotation.Nullable @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedString.class) java.lang.String targetActivity\nprivate @android.annotation.Nullable @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedString.class) java.lang.String parentActivityName\nprivate @android.annotation.Nullable java.lang.String taskAffinity\nprivate int privateFlags\nprivate @android.annotation.Nullable @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedString.class) java.lang.String permission\nprivate @android.annotation.Nullable java.util.Set<java.lang.String> mKnownActivityEmbeddingCerts\nprivate int launchMode\nprivate int documentLaunchMode\nprivate int maxRecents\nprivate int configChanges\nprivate int softInputMode\nprivate int persistableMode\nprivate int lockTaskLaunchMode\nprivate int screenOrientation\nprivate int resizeMode\nprivate float maxAspectRatio\nprivate float minAspectRatio\nprivate boolean supportsSizeChanges\nprivate @android.annotation.Nullable java.lang.String requestedVrComponent\nprivate int rotationAnimation\nprivate int colorMode\nprivate @android.annotation.Nullable android.content.pm.ActivityInfo.WindowLayout windowLayout\npublic static final @android.annotation.NonNull android.os.Parcelable.Creator<com.android.server.pm.pkg.component.ParsedActivityImpl> CREATOR\nstatic @android.annotation.NonNull com.android.server.pm.pkg.component.ParsedActivityImpl makeAppDetailsActivity(java.lang.String,java.lang.String,int,java.lang.String,boolean)\nstatic @android.annotation.NonNull com.android.server.pm.pkg.component.ParsedActivityImpl makeAlias(java.lang.String,com.android.server.pm.pkg.component.ParsedActivity)\npublic com.android.server.pm.pkg.component.ParsedActivityImpl setMaxAspectRatio(int,float)\npublic com.android.server.pm.pkg.component.ParsedActivityImpl setMinAspectRatio(int,float)\npublic com.android.server.pm.pkg.component.ParsedActivityImpl setTargetActivity(java.lang.String)\npublic com.android.server.pm.pkg.component.ParsedActivityImpl setPermission(java.lang.String)\npublic @android.annotation.NonNull @java.lang.Override java.util.Set<java.lang.String> getKnownActivityEmbeddingCerts()\npublic void setKnownActivityEmbeddingCerts(java.util.Set<java.lang.String>)\npublic java.lang.String toString()\npublic @java.lang.Override int describeContents()\npublic @java.lang.Override void writeToParcel(android.os.Parcel,int)\nclass ParsedActivityImpl extends com.android.server.pm.pkg.component.ParsedMainComponentImpl implements [com.android.server.pm.pkg.component.ParsedActivity, android.os.Parcelable]\n@com.android.internal.util.DataClass(genGetters=true, genSetters=true, genBuilder=false, genParcelable=false)")
|
||||
inputSignatures = "private int theme\nprivate int uiOptions\nprivate @android.annotation.Nullable @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedString.class) java.lang.String targetActivity\nprivate @android.annotation.Nullable @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedString.class) java.lang.String parentActivityName\nprivate @android.annotation.Nullable java.lang.String taskAffinity\nprivate int privateFlags\nprivate @android.annotation.Nullable @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedString.class) java.lang.String permission\nprivate @android.annotation.Nullable java.util.Set<java.lang.String> mKnownActivityEmbeddingCerts\nprivate int launchMode\nprivate int documentLaunchMode\nprivate int maxRecents\nprivate int configChanges\nprivate int softInputMode\nprivate int persistableMode\nprivate int lockTaskLaunchMode\nprivate int screenOrientation\nprivate int resizeMode\nprivate float maxAspectRatio\nprivate float minAspectRatio\nprivate boolean supportsSizeChanges\nprivate @android.annotation.Nullable java.lang.String requestedVrComponent\nprivate int rotationAnimation\nprivate int colorMode\nprivate @android.annotation.Nullable android.content.pm.ActivityInfo.WindowLayout windowLayout\nprivate @android.annotation.Nullable java.lang.String mTargetDisplayCategory\npublic static final @android.annotation.NonNull android.os.Parcelable.Creator<com.android.server.pm.pkg.component.ParsedActivityImpl> CREATOR\nstatic @android.annotation.NonNull com.android.server.pm.pkg.component.ParsedActivityImpl makeAppDetailsActivity(java.lang.String,java.lang.String,int,java.lang.String,boolean)\nstatic @android.annotation.NonNull com.android.server.pm.pkg.component.ParsedActivityImpl makeAlias(java.lang.String,com.android.server.pm.pkg.component.ParsedActivity)\npublic com.android.server.pm.pkg.component.ParsedActivityImpl setMaxAspectRatio(int,float)\npublic com.android.server.pm.pkg.component.ParsedActivityImpl setMinAspectRatio(int,float)\npublic com.android.server.pm.pkg.component.ParsedActivityImpl setTargetActivity(java.lang.String)\npublic com.android.server.pm.pkg.component.ParsedActivityImpl setPermission(java.lang.String)\npublic @android.annotation.NonNull @java.lang.Override java.util.Set<java.lang.String> getKnownActivityEmbeddingCerts()\npublic void setKnownActivityEmbeddingCerts(java.util.Set<java.lang.String>)\npublic java.lang.String toString()\npublic @java.lang.Override int describeContents()\npublic @java.lang.Override void writeToParcel(android.os.Parcel,int)\nclass ParsedActivityImpl extends com.android.server.pm.pkg.component.ParsedMainComponentImpl implements [com.android.server.pm.pkg.component.ParsedActivity, android.os.Parcelable]\n@com.android.internal.util.DataClass(genGetters=true, genSetters=true, genBuilder=false, genParcelable=false)")
|
||||
@Deprecated
|
||||
private void __metadata() {}
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ import android.app.ActivityTaskManager;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.parsing.FrameworkParsingPackageUtils;
|
||||
import android.content.pm.parsing.result.ParseInput;
|
||||
import android.content.pm.parsing.result.ParseInput.DeferredError;
|
||||
import android.content.pm.parsing.result.ParseResult;
|
||||
@@ -219,6 +220,18 @@ public class ParsedActivityUtils {
|
||||
pkg.setVisibleToInstantApps(true);
|
||||
}
|
||||
|
||||
String targetDisplayCategory = sa.getNonConfigurationString(
|
||||
R.styleable.AndroidManifestActivity_targetDisplayCategory, 0);
|
||||
|
||||
if (targetDisplayCategory != null
|
||||
&& FrameworkParsingPackageUtils.validateName(targetDisplayCategory,
|
||||
false /* requireSeparator */, false /* requireFilename */) != null) {
|
||||
return input.error("targetDisplayCategory attribute can only consists of "
|
||||
+ "alphanumeric characters, '_', and '.'");
|
||||
}
|
||||
|
||||
activity.setTargetDisplayCategory(targetDisplayCategory);
|
||||
|
||||
return parseActivityOrAlias(activity, pkg, tag, parser, res, sa, receiver,
|
||||
false /*isAlias*/, visibleToEphemeral, input,
|
||||
R.styleable.AndroidManifestActivity_parentActivityName,
|
||||
|
||||
@@ -53,7 +53,8 @@ class ParsedActivityTest : ParsedMainComponentTest(
|
||||
ParsedActivity::getTaskAffinity,
|
||||
ParsedActivity::getTheme,
|
||||
ParsedActivity::getUiOptions,
|
||||
ParsedActivity::isSupportsSizeChanges
|
||||
ParsedActivity::isSupportsSizeChanges,
|
||||
ParsedActivity::getTargetDisplayCategory
|
||||
)
|
||||
|
||||
override fun mainComponentSubclassExtraParams() = listOf(
|
||||
|
||||
@@ -123,6 +123,7 @@ android_test {
|
||||
":PackageParserTestApp3",
|
||||
":PackageParserTestApp4",
|
||||
":PackageParserTestApp5",
|
||||
":PackageParserTestApp6",
|
||||
":apex.test",
|
||||
":test.rebootless_apex_v1",
|
||||
":test.rebootless_apex_v2",
|
||||
|
||||
@@ -23,6 +23,7 @@ import static com.google.common.truth.Truth.assertWithMessage;
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
@@ -127,6 +128,7 @@ public class PackageParserTest {
|
||||
private static final String TEST_APP3_APK = "PackageParserTestApp3.apk";
|
||||
private static final String TEST_APP4_APK = "PackageParserTestApp4.apk";
|
||||
private static final String TEST_APP5_APK = "PackageParserTestApp5.apk";
|
||||
private static final String TEST_APP6_APK = "PackageParserTestApp6.apk";
|
||||
private static final String PACKAGE_NAME = "com.android.servicestests.apps.packageparserapp";
|
||||
|
||||
@Before
|
||||
@@ -331,6 +333,46 @@ public class PackageParserTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseActivityTargetDisplayCategoryValid() throws Exception {
|
||||
final File testFile = extractFile(TEST_APP4_APK);
|
||||
String actualDisplayCategory = null;
|
||||
try {
|
||||
final ParsedPackage pkg = new TestPackageParser2().parsePackage(testFile, 0, false);
|
||||
final List<ParsedActivity> activities = pkg.getActivities();
|
||||
for (ParsedActivity activity : activities) {
|
||||
if ((PACKAGE_NAME + ".MyActivity").equals(activity.getName())) {
|
||||
actualDisplayCategory = activity.getTargetDisplayCategory();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
testFile.delete();
|
||||
}
|
||||
assertEquals("automotive", actualDisplayCategory);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseActivityTargetDisplayCategoryInvalid() throws Exception {
|
||||
final File testFile = extractFile(TEST_APP6_APK);
|
||||
String actualDisplayCategory = null;
|
||||
try {
|
||||
final ParsedPackage pkg = new TestPackageParser2().parsePackage(testFile, 0, false);
|
||||
final List<ParsedActivity> activities = pkg.getActivities();
|
||||
for (ParsedActivity activity : activities) {
|
||||
if ((PACKAGE_NAME + ".MyActivity").equals(activity.getName())) {
|
||||
actualDisplayCategory = activity.getTargetDisplayCategory();
|
||||
}
|
||||
}
|
||||
} catch (PackageManagerException e) {
|
||||
assertThat(e.getMessage()).contains(
|
||||
"targetDisplayCategory attribute can only consists"
|
||||
+ " of alphanumeric characters, '_', and '.'");
|
||||
} finally {
|
||||
testFile.delete();
|
||||
}
|
||||
assertNotEquals("$automotive", actualDisplayCategory);
|
||||
}
|
||||
|
||||
private static final int PROPERTY_TYPE_BOOLEAN = 1;
|
||||
private static final int PROPERTY_TYPE_FLOAT = 2;
|
||||
private static final int PROPERTY_TYPE_INTEGER = 3;
|
||||
|
||||
@@ -88,3 +88,17 @@ android_test_helper_app {
|
||||
resource_dirs: ["res"],
|
||||
manifest: "AndroidManifestApp5.xml",
|
||||
}
|
||||
|
||||
android_test_helper_app {
|
||||
name: "PackageParserTestApp6",
|
||||
sdk_version: "current",
|
||||
srcs: ["**/*.java"],
|
||||
dex_preopt: {
|
||||
enabled: false,
|
||||
},
|
||||
optimize: {
|
||||
enabled: false,
|
||||
},
|
||||
resource_dirs: ["res"],
|
||||
manifest: "AndroidManifestApp6.xml",
|
||||
}
|
||||
|
||||
@@ -31,7 +31,8 @@
|
||||
<property android:name="android.cts.PROPERTY_STRING_VIA_RESOURCE" android:value="@string/string_property" />
|
||||
|
||||
<activity android:name="com.android.servicestests.apps.packageparserapp.MyActivity"
|
||||
android:exported="true" >
|
||||
android:exported="true"
|
||||
android:targetDisplayCategory="automotive">
|
||||
<property android:name="android.cts.PROPERTY_ACTIVITY" android:value="@integer/integer_property" />
|
||||
<property android:name="android.cts.PROPERTY_COMPONENT" android:value="@integer/integer_property" />
|
||||
<property android:name="android.cts.PROPERTY_STRING" android:value="koala activity" />
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--
|
||||
~ Copyright (C) 2022 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.
|
||||
-->
|
||||
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.android.servicestests.apps.packageparserapp" >
|
||||
<application>
|
||||
<activity android:name="com.android.servicestests.apps.packageparserapp.MyActivity"
|
||||
android:exported="true"
|
||||
android:targetDisplayCategory="$automotive">
|
||||
</activity>
|
||||
</application>
|
||||
</manifest>
|
||||
Reference in New Issue
Block a user