Merge "Always use TypedArray to obtain manifest values" into rvc-dev am: 644d25d4c4

Change-Id: I90d78ebe8ee4cbcc3f55ca07d1a9a8641e9f166b
This commit is contained in:
TreeHugger Robot
2020-03-27 17:45:10 +00:00
committed by Automerger Merge Worker
11 changed files with 276 additions and 20 deletions

View File

@@ -1837,6 +1837,12 @@ public class PackageParser {
pkg.coreApp = parser.getAttributeBooleanValue(null, "coreApp", false);
final boolean isolatedSplits = sa.getBoolean(
com.android.internal.R.styleable.AndroidManifest_isolatedSplits, false);
if (isolatedSplits) {
pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_ISOLATED_SPLIT_LOADING;
}
pkg.mCompileSdkVersion = sa.getInteger(
com.android.internal.R.styleable.AndroidManifest_compileSdkVersion, 0);
pkg.applicationInfo.compileSdkVersion = pkg.mCompileSdkVersion;
@@ -1912,10 +1918,6 @@ public class PackageParser {
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_EXTERNAL_STORAGE;
}
if (sa.getBoolean(com.android.internal.R.styleable.AndroidManifest_isolatedSplits, false)) {
pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_ISOLATED_SPLIT_LOADING;
}
// Resource boolean are -1, so 1 means we don't know the value.
int supportsSmallScreens = 1;
int supportsNormalScreens = 1;

View File

@@ -433,6 +433,10 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable {
R.styleable.AndroidManifest_compileSdkVersion, 0));
setCompileSdkVersionCodename(manifestArray.getNonConfigurationString(
R.styleable.AndroidManifest_compileSdkVersionCodename, 0));
setIsolatedSplitLoading(manifestArray.getBoolean(
R.styleable.AndroidManifest_isolatedSplits, false));
}
}

View File

@@ -386,15 +386,14 @@ public class ParsingPackageUtils {
return input.error(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME);
}
TypedArray manifestArray = res.obtainAttributes(parser, R.styleable.AndroidManifest);
final TypedArray manifestArray = res.obtainAttributes(parser, R.styleable.AndroidManifest);
try {
boolean isCoreApp = parser.getAttributeBooleanValue(null, "coreApp", false);
ParsingPackage pkg = mCallback.startParsingPackage(pkgName, apkPath, codePath,
manifestArray, isCoreApp);
ParseResult<ParsingPackage> result = parseBaseApkTags(input, pkg, manifestArray,
res, parser, flags);
final boolean isCoreApp =
parser.getAttributeBooleanValue(null, "coreApp", false);
final ParsingPackage pkg = mCallback.startParsingPackage(
pkgName, apkPath, codePath, manifestArray, isCoreApp);
final ParseResult<ParsingPackage> result =
parseBaseApkTags(input, pkg, manifestArray, res, parser, flags);
if (result.isError()) {
return result;
}
@@ -620,14 +619,12 @@ public class ParsingPackageUtils {
return sharedUserResult;
}
pkg.setInstallLocation(anInt(PackageParser.PARSE_DEFAULT_INSTALL_LOCATION,
pkg.setInstallLocation(anInteger(PackageParser.PARSE_DEFAULT_INSTALL_LOCATION,
R.styleable.AndroidManifest_installLocation, sa))
.setTargetSandboxVersion(anInt(PackageParser.PARSE_DEFAULT_TARGET_SANDBOX,
.setTargetSandboxVersion(anInteger(PackageParser.PARSE_DEFAULT_TARGET_SANDBOX,
R.styleable.AndroidManifest_targetSandboxVersion, sa))
/* Set the global "on SD card" flag */
.setExternalStorage((flags & PackageParser.PARSE_EXTERNAL_STORAGE) != 0)
.setIsolatedSplitLoading(
bool(false, R.styleable.AndroidManifest_isolatedSplits, sa));
.setExternalStorage((flags & PackageParser.PARSE_EXTERNAL_STORAGE) != 0);
boolean foundApp = false;
final int depth = parser.getDepth();
@@ -2658,6 +2655,10 @@ public class ParsingPackageUtils {
return sa.getInt(attribute, defaultValue);
}
private static int anInteger(int defaultValue, @StyleableRes int attribute, TypedArray sa) {
return sa.getInteger(attribute, defaultValue);
}
private static int anInt(@StyleableRes int attribute, TypedArray sa) {
return sa.getInt(attribute, 0);
}
@@ -2688,6 +2689,6 @@ public class ParsingPackageUtils {
boolean hasFeature(String feature);
ParsingPackage startParsingPackage(String packageName, String baseCodePath, String codePath,
TypedArray manifestArray, boolean isCoreApp);
@NonNull TypedArray manifestArray, boolean isCoreApp);
}
}

View File

@@ -91,7 +91,15 @@ android_test {
enabled: false,
},
data: [":JobTestApp"],
data: [
":JobTestApp",
],
java_resources: [
":PackageParserTestApp1",
":PackageParserTestApp2",
":PackageParserTestApp3",
],
resource_zips: [":FrameworksServicesTests_apks_as_resources"],
}

View File

@@ -17,11 +17,15 @@ package com.android.server.pm;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
import android.annotation.NonNull;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.ConfigurationInfo;
@@ -30,7 +34,6 @@ import android.content.pm.FeatureInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageParser;
import android.content.pm.PackageUserState;
import android.content.pm.ProviderInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.Signature;
import android.content.pm.parsing.ParsingPackage;
@@ -49,6 +52,7 @@ import android.util.ArraySet;
import android.util.DisplayMetrics;
import androidx.annotation.Nullable;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.MediumTest;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
@@ -69,9 +73,11 @@ import org.junit.runner.RunWith;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
@@ -90,6 +96,9 @@ public class PackageParserTest {
private File mTmpDir;
private static final File FRAMEWORK = new File("/system/framework/framework-res.apk");
private static final String TEST_APP1_APK = "PackageParserTestApp1.apk";
private static final String TEST_APP2_APK = "PackageParserTestApp2.apk";
private static final String TEST_APP3_APK = "PackageParserTestApp3.apk";
@Before
public void setUp() throws IOException {
@@ -209,6 +218,61 @@ public class PackageParserTest {
assertSame(deserialized.getSharedUserId(), deserialized2.getSharedUserId());
}
private static PackageParser2 makeParser() {
return new PackageParser2(null, false, null, null, null);
}
private File extractFile(String filename) throws Exception {
final Context context = InstrumentationRegistry.getTargetContext();
final File tmpFile = File.createTempFile(filename, ".apk");
try (InputStream inputStream = context.getAssets().openNonAsset(filename)) {
Files.copy(inputStream, tmpFile.toPath(), REPLACE_EXISTING);
}
return tmpFile;
}
/**
* Tests AndroidManifest.xml with no android:isolatedSplits attribute.
*/
@Test
public void testParseIsolatedSplitsDefault() throws Exception {
final File testFile = extractFile(TEST_APP1_APK);
try {
final ParsedPackage pkg = makeParser().parsePackage(testFile, 0, false);
assertFalse("isolatedSplits", pkg.isIsolatedSplitLoading());
} finally {
testFile.delete();
}
}
/**
* Tests AndroidManifest.xml with an android:isolatedSplits attribute set to a constant.
*/
@Test
public void testParseIsolatedSplitsConstant() throws Exception {
final File testFile = extractFile(TEST_APP2_APK);
try {
final ParsedPackage pkg = makeParser().parsePackage(testFile, 0, false);
assertTrue("isolatedSplits", pkg.isIsolatedSplitLoading());
} finally {
testFile.delete();
}
}
/**
* Tests AndroidManifest.xml with an android:isolatedSplits attribute set to a resource.
*/
@Test
public void testParseIsolatedSplitsResource() throws Exception {
final File testFile = extractFile(TEST_APP3_APK);
try {
final ParsedPackage pkg = makeParser().parsePackage(testFile, 0, false);
assertTrue("isolatedSplits", pkg.isIsolatedSplitLoading());
} finally {
testFile.delete();
}
}
/**
* A trivial subclass of package parser that only caches the package name, and throws away
* all other information.

View File

@@ -0,0 +1,53 @@
// 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.
android_test_helper_app {
name: "PackageParserTestApp1",
sdk_version: "current",
srcs: ["**/*.java"],
dex_preopt: {
enabled: false,
},
optimize: {
enabled: false,
},
manifest: "AndroidManifestApp1.xml",
}
android_test_helper_app {
name: "PackageParserTestApp2",
sdk_version: "current",
srcs: ["**/*.java"],
dex_preopt: {
enabled: false,
},
optimize: {
enabled: false,
},
manifest: "AndroidManifestApp2.xml",
}
android_test_helper_app {
name: "PackageParserTestApp3",
sdk_version: "current",
srcs: ["**/*.java"],
dex_preopt: {
enabled: false,
},
optimize: {
enabled: false,
},
resource_dirs: ["res"],
manifest: "AndroidManifestApp3.xml",
}

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.servicestests.apps.packageparserapp" >
<application>
<activity android:name=".TestActivity"
android:exported="true" />
</application>
</manifest>

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.servicestests.apps.packageparserapp"
android:isolatedSplits="true" >
<application>
<activity android:name=".TestActivity"
android:exported="true" />
</application>
</manifest>

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.servicestests.apps.packageparserapp"
android:isolatedSplits="@bool/config_isIsolated" >
<application>
<activity android:name=".TestActivity"
android:exported="true" />
</application>
</manifest>

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<bool name="config_isIsolated">true</bool>
</resources>

View File

@@ -0,0 +1,28 @@
/*
* 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 com.android.servicestests.apps.packageparserapp;
import android.app.Activity;
import android.os.Bundle;
public class TestActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
finish();
}
}