182f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette/*
282f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette * Copyright (C) 2016 The Android Open Source Project
382f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette *
482f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette * Licensed under the Apache License, Version 2.0 (the "License");
582f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette * you may not use this file except in compliance with the License.
682f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette * You may obtain a copy of the License at
782f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette *
882f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette *      http://www.apache.org/licenses/LICENSE-2.0
982f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette *
1082f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette * Unless required by applicable law or agreed to in writing, software
1182f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette * distributed under the License is distributed on an "AS IS" BASIS,
1282f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1382f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette * See the License for the specific language governing permissions and
1482f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette * limitations under the License.
1582f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette */
1682f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette
1782f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverettepackage android.content.pm;
1882f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette
1982f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viveretteimport static org.junit.Assert.assertEquals;
2082f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viveretteimport static org.junit.Assert.assertNotNull;
2182f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viveretteimport static org.junit.Assert.assertNull;
225213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyerimport static org.junit.Assert.assertTrue;
2382f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette
245213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyerimport android.content.Context;
255213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyerimport android.content.pm.PackageParser.Component;
265213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyerimport android.content.pm.PackageParser.Package;
275213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyerimport android.content.pm.PackageParser.Permission;
2882f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viveretteimport android.os.Build;
294501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onukiimport android.os.Bundle;
305213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyerimport android.os.FileUtils;
3117041530bfa8199414b8480691303739b30126b4Garrett Boyerimport android.os.SystemProperties;
325213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyerimport android.support.test.InstrumentationRegistry;
3382f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viveretteimport android.support.test.runner.AndroidJUnit4;
3482f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viveretteimport android.test.suitebuilder.annotation.SmallTest;
3582f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette
365213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyerimport com.android.frameworks.coretests.R;
375213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer
3882f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viveretteimport org.junit.Test;
3982f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viveretteimport org.junit.runner.RunWith;
4082f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette
415213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyerimport java.io.File;
425213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyerimport java.io.InputStream;
435213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyerimport java.util.Arrays;
444501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onukiimport java.util.function.Function;
455213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer
4682f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette@SmallTest
4782f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette@RunWith(AndroidJUnit4.class)
4882f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverettepublic class PackageParserTest {
4982f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette    private static final String RELEASED = null;
5082f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette    private static final String OLDER_PRE_RELEASE = "A";
5182f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette    private static final String PRE_RELEASE = "B";
5282f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette    private static final String NEWER_PRE_RELEASE = "C";
5382f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette
5482f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette    private static final String[] CODENAMES_RELEASED = { /* empty */ };
5582f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette    private static final String[] CODENAMES_PRE_RELEASE = { PRE_RELEASE };
5682f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette
5782f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette    private static final int OLDER_VERSION = 10;
5882f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette    private static final int PLATFORM_VERSION = 20;
5982f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette    private static final int NEWER_VERSION = 30;
6082f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette
6182f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette    private void verifyComputeMinSdkVersion(int minSdkVersion, String minSdkCodename,
6282f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette            boolean isPlatformReleased, int expectedMinSdk) {
6382f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        final String[] outError = new String[1];
6482f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        final int result = PackageParser.computeMinSdkVersion(
6582f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette                minSdkVersion,
6682f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette                minSdkCodename,
6782f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette                PLATFORM_VERSION,
6882f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette                isPlatformReleased ? CODENAMES_RELEASED : CODENAMES_PRE_RELEASE,
6982f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette                outError);
7082f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette
7182f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        assertEquals(result, expectedMinSdk);
7282f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette
7382f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        if (expectedMinSdk == -1) {
7482f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette            assertNotNull(outError[0]);
7582f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        } else {
7682f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette            assertNull(outError[0]);
7782f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        }
7882f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette    }
7982f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette
8082f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette    @Test
8182f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette    public void testComputeMinSdkVersion_preReleasePlatform() {
8282f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // Do allow older release minSdkVersion on pre-release platform.
8382f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // APP: Released API 10
8482f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // DEV: Pre-release API 20
8582f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        verifyComputeMinSdkVersion(OLDER_VERSION, RELEASED, false, OLDER_VERSION);
8682f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette
8782f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // Do allow same release minSdkVersion on pre-release platform.
8882f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // APP: Released API 20
8982f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // DEV: Pre-release API 20
9082f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        verifyComputeMinSdkVersion(PLATFORM_VERSION, RELEASED, false, PLATFORM_VERSION);
9182f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette
9282f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // Don't allow newer release minSdkVersion on pre-release platform.
9382f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // APP: Released API 30
9482f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // DEV: Pre-release API 20
9582f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        verifyComputeMinSdkVersion(NEWER_VERSION, RELEASED, false, -1);
9682f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette
9782f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // Don't allow older pre-release minSdkVersion on pre-release platform.
9882f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // APP: Pre-release API 10
9982f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // DEV: Pre-release API 20
10082f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        verifyComputeMinSdkVersion(OLDER_VERSION, OLDER_PRE_RELEASE, false, -1);
10182f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette
10282f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // Do allow same pre-release minSdkVersion on pre-release platform,
10382f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // but overwrite the specified version with CUR_DEVELOPMENT.
10482f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // APP: Pre-release API 20
10582f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // DEV: Pre-release API 20
10682f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        verifyComputeMinSdkVersion(PLATFORM_VERSION, PRE_RELEASE, false,
10782f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette                Build.VERSION_CODES.CUR_DEVELOPMENT);
10882f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette
10982f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // Don't allow newer pre-release minSdkVersion on pre-release platform.
11082f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // APP: Pre-release API 30
11182f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // DEV: Pre-release API 20
11282f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        verifyComputeMinSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE, false, -1);
11382f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette    }
11482f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette
11582f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette    @Test
11682f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette    public void testComputeMinSdkVersion_releasedPlatform() {
11782f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // Do allow older release minSdkVersion on released platform.
11882f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // APP: Released API 10
11982f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // DEV: Released API 20
12082f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        verifyComputeMinSdkVersion(OLDER_VERSION, RELEASED, true, OLDER_VERSION);
12182f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette
12282f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // Do allow same release minSdkVersion on released platform.
12382f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // APP: Released API 20
12482f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // DEV: Released API 20
12582f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        verifyComputeMinSdkVersion(PLATFORM_VERSION, RELEASED, true, PLATFORM_VERSION);
12682f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette
12782f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // Don't allow newer release minSdkVersion on released platform.
12882f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // APP: Released API 30
12982f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // DEV: Released API 20
13082f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        verifyComputeMinSdkVersion(NEWER_VERSION, RELEASED, true, -1);
13182f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette
13282f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // Don't allow older pre-release minSdkVersion on released platform.
13382f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // APP: Pre-release API 10
13482f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // DEV: Released API 20
13582f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        verifyComputeMinSdkVersion(OLDER_VERSION, OLDER_PRE_RELEASE, true, -1);
13682f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette
13782f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // Don't allow same pre-release minSdkVersion on released platform.
13882f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // APP: Pre-release API 20
13982f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // DEV: Released API 20
14082f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        verifyComputeMinSdkVersion(PLATFORM_VERSION, PRE_RELEASE, true, -1);
14182f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette
14282f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // Don't allow newer pre-release minSdkVersion on released platform.
14382f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // APP: Pre-release API 30
14482f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // DEV: Released API 20
14582f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        verifyComputeMinSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE, true, -1);
14682f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette    }
14782f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette
14882f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette    private void verifyComputeTargetSdkVersion(int targetSdkVersion, String targetSdkCodename,
149ccb20b8eb6c890eb5278c6693b5ad0a223bb9fa7Patrick Baumann            boolean isPlatformReleased, int expectedTargetSdk, boolean forceCurrentDev) {
15082f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        final String[] outError = new String[1];
15182f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        final int result = PackageParser.computeTargetSdkVersion(
15282f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette                targetSdkVersion,
15382f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette                targetSdkCodename,
15482f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette                isPlatformReleased ? CODENAMES_RELEASED : CODENAMES_PRE_RELEASE,
155ccb20b8eb6c890eb5278c6693b5ad0a223bb9fa7Patrick Baumann                outError,
156ccb20b8eb6c890eb5278c6693b5ad0a223bb9fa7Patrick Baumann                forceCurrentDev);
15782f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette
15882f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        assertEquals(result, expectedTargetSdk);
15982f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette
16082f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        if (expectedTargetSdk == -1) {
16182f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette            assertNotNull(outError[0]);
16282f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        } else {
16382f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette            assertNull(outError[0]);
16482f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        }
16582f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette    }
16682f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette
16782f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette    @Test
16882f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette    public void testComputeTargetSdkVersion_preReleasePlatform() {
16982f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // Do allow older release targetSdkVersion on pre-release platform.
17082f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // APP: Released API 10
17182f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // DEV: Pre-release API 20
172ccb20b8eb6c890eb5278c6693b5ad0a223bb9fa7Patrick Baumann        verifyComputeTargetSdkVersion(OLDER_VERSION, RELEASED, false, OLDER_VERSION,
173ccb20b8eb6c890eb5278c6693b5ad0a223bb9fa7Patrick Baumann                false /* forceCurrentDev */);
17482f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette
17582f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // Do allow same release targetSdkVersion on pre-release platform.
17682f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // APP: Released API 20
17782f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // DEV: Pre-release API 20
178ccb20b8eb6c890eb5278c6693b5ad0a223bb9fa7Patrick Baumann        verifyComputeTargetSdkVersion(PLATFORM_VERSION, RELEASED, false, PLATFORM_VERSION,
179ccb20b8eb6c890eb5278c6693b5ad0a223bb9fa7Patrick Baumann                false /* forceCurrentDev */);
18082f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette
18182f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // Do allow newer release targetSdkVersion on pre-release platform.
18282f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // APP: Released API 30
18382f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // DEV: Pre-release API 20
184ccb20b8eb6c890eb5278c6693b5ad0a223bb9fa7Patrick Baumann        verifyComputeTargetSdkVersion(NEWER_VERSION, RELEASED, false, NEWER_VERSION,
185ccb20b8eb6c890eb5278c6693b5ad0a223bb9fa7Patrick Baumann                false /* forceCurrentDev */);
18682f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette
18782f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // Don't allow older pre-release targetSdkVersion on pre-release platform.
18882f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // APP: Pre-release API 10
18982f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // DEV: Pre-release API 20
190ccb20b8eb6c890eb5278c6693b5ad0a223bb9fa7Patrick Baumann        verifyComputeTargetSdkVersion(OLDER_VERSION, OLDER_PRE_RELEASE, false, -1,
191ccb20b8eb6c890eb5278c6693b5ad0a223bb9fa7Patrick Baumann                false /* forceCurrentDev */);
19282f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette
19382f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // Do allow same pre-release targetSdkVersion on pre-release platform,
19482f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // but overwrite the specified version with CUR_DEVELOPMENT.
19582f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // APP: Pre-release API 20
19682f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // DEV: Pre-release API 20
19782f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        verifyComputeTargetSdkVersion(PLATFORM_VERSION, PRE_RELEASE, false,
198ccb20b8eb6c890eb5278c6693b5ad0a223bb9fa7Patrick Baumann                Build.VERSION_CODES.CUR_DEVELOPMENT, false /* forceCurrentDev */);
19982f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette
20082f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // Don't allow newer pre-release targetSdkVersion on pre-release platform.
20182f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // APP: Pre-release API 30
20282f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // DEV: Pre-release API 20
203ccb20b8eb6c890eb5278c6693b5ad0a223bb9fa7Patrick Baumann        verifyComputeTargetSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE, false, -1,
204ccb20b8eb6c890eb5278c6693b5ad0a223bb9fa7Patrick Baumann                false /* forceCurrentDev */);
205ccb20b8eb6c890eb5278c6693b5ad0a223bb9fa7Patrick Baumann
206ccb20b8eb6c890eb5278c6693b5ad0a223bb9fa7Patrick Baumann        // Force newer pre-release targetSdkVersion to current pre-release platform.
207ccb20b8eb6c890eb5278c6693b5ad0a223bb9fa7Patrick Baumann        // APP: Pre-release API 30
208ccb20b8eb6c890eb5278c6693b5ad0a223bb9fa7Patrick Baumann        // DEV: Pre-release API 20
209ccb20b8eb6c890eb5278c6693b5ad0a223bb9fa7Patrick Baumann        verifyComputeTargetSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE, false,
210ccb20b8eb6c890eb5278c6693b5ad0a223bb9fa7Patrick Baumann                Build.VERSION_CODES.CUR_DEVELOPMENT, true /* forceCurrentDev */);
21182f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette    }
21282f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette
21382f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette    @Test
21482f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette    public void testComputeTargetSdkVersion_releasedPlatform() {
21582f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // Do allow older release targetSdkVersion on released platform.
21682f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // APP: Released API 10
21782f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // DEV: Released API 20
218ccb20b8eb6c890eb5278c6693b5ad0a223bb9fa7Patrick Baumann        verifyComputeTargetSdkVersion(OLDER_VERSION, RELEASED, true, OLDER_VERSION,
219ccb20b8eb6c890eb5278c6693b5ad0a223bb9fa7Patrick Baumann                false /* forceCurrentDev */);
22082f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette
22182f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // Do allow same release targetSdkVersion on released platform.
22282f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // APP: Released API 20
22382f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // DEV: Released API 20
224ccb20b8eb6c890eb5278c6693b5ad0a223bb9fa7Patrick Baumann        verifyComputeTargetSdkVersion(PLATFORM_VERSION, RELEASED, true, PLATFORM_VERSION,
225ccb20b8eb6c890eb5278c6693b5ad0a223bb9fa7Patrick Baumann                false /* forceCurrentDev */);
22682f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette
22782f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // Do allow newer release targetSdkVersion on released platform.
22882f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // APP: Released API 30
22982f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // DEV: Released API 20
230ccb20b8eb6c890eb5278c6693b5ad0a223bb9fa7Patrick Baumann        verifyComputeTargetSdkVersion(NEWER_VERSION, RELEASED, true, NEWER_VERSION,
231ccb20b8eb6c890eb5278c6693b5ad0a223bb9fa7Patrick Baumann                false /* forceCurrentDev */);
23282f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette
23382f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // Don't allow older pre-release targetSdkVersion on released platform.
23482f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // APP: Pre-release API 10
23582f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // DEV: Released API 20
236ccb20b8eb6c890eb5278c6693b5ad0a223bb9fa7Patrick Baumann        verifyComputeTargetSdkVersion(OLDER_VERSION, OLDER_PRE_RELEASE, true, -1,
237ccb20b8eb6c890eb5278c6693b5ad0a223bb9fa7Patrick Baumann                false /* forceCurrentDev */);
23882f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette
23982f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // Don't allow same pre-release targetSdkVersion on released platform.
24082f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // APP: Pre-release API 20
24182f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // DEV: Released API 20
242ccb20b8eb6c890eb5278c6693b5ad0a223bb9fa7Patrick Baumann        verifyComputeTargetSdkVersion(PLATFORM_VERSION, PRE_RELEASE, true, -1,
243ccb20b8eb6c890eb5278c6693b5ad0a223bb9fa7Patrick Baumann                false /* forceCurrentDev */);
24482f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette
24582f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // Don't allow newer pre-release targetSdkVersion on released platform.
24682f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // APP: Pre-release API 30
24782f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette        // DEV: Released API 20
248ccb20b8eb6c890eb5278c6693b5ad0a223bb9fa7Patrick Baumann        verifyComputeTargetSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE, true, -1,
249ccb20b8eb6c890eb5278c6693b5ad0a223bb9fa7Patrick Baumann                false /* forceCurrentDev */);
25082f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette    }
251b6d7695cf2e7cec5c7b24e1b09e1f7d8f1788cb7Holly Jiuyu Sun
252b6d7695cf2e7cec5c7b24e1b09e1f7d8f1788cb7Holly Jiuyu Sun    /**
253b6d7695cf2e7cec5c7b24e1b09e1f7d8f1788cb7Holly Jiuyu Sun     * Unit test for PackageParser.getActivityConfigChanges().
254b6d7695cf2e7cec5c7b24e1b09e1f7d8f1788cb7Holly Jiuyu Sun     * If the bit is 1 in the original configChanges, it is still 1 in the final configChanges.
255b6d7695cf2e7cec5c7b24e1b09e1f7d8f1788cb7Holly Jiuyu Sun     * If the bit is 0 in the original configChanges and the bit is not set to 1 in
256c93c3b9cf378e84b8a6f8fdb519a11c51d748a45Holly Jiuyu Sun     * recreateOnConfigChanges, the bit is changed to 1 in the final configChanges by default.
257b6d7695cf2e7cec5c7b24e1b09e1f7d8f1788cb7Holly Jiuyu Sun     */
258b6d7695cf2e7cec5c7b24e1b09e1f7d8f1788cb7Holly Jiuyu Sun    @Test
259b6d7695cf2e7cec5c7b24e1b09e1f7d8f1788cb7Holly Jiuyu Sun    public void testGetActivityConfigChanges() {
260c93c3b9cf378e84b8a6f8fdb519a11c51d748a45Holly Jiuyu Sun        // Not set in either configChanges or recreateOnConfigChanges.
261b6d7695cf2e7cec5c7b24e1b09e1f7d8f1788cb7Holly Jiuyu Sun        int configChanges = 0x0000; // 00000000.
262c93c3b9cf378e84b8a6f8fdb519a11c51d748a45Holly Jiuyu Sun        int recreateOnConfigChanges = 0x0000; // 00000000.
263b6d7695cf2e7cec5c7b24e1b09e1f7d8f1788cb7Holly Jiuyu Sun        int finalConfigChanges =
264c93c3b9cf378e84b8a6f8fdb519a11c51d748a45Holly Jiuyu Sun                PackageParser.getActivityConfigChanges(configChanges, recreateOnConfigChanges);
265b6d7695cf2e7cec5c7b24e1b09e1f7d8f1788cb7Holly Jiuyu Sun        assertEquals(0x0003, finalConfigChanges); // Should be 00000011.
266b6d7695cf2e7cec5c7b24e1b09e1f7d8f1788cb7Holly Jiuyu Sun
267c93c3b9cf378e84b8a6f8fdb519a11c51d748a45Holly Jiuyu Sun        // Not set in configChanges, but set in recreateOnConfigChanges.
268b6d7695cf2e7cec5c7b24e1b09e1f7d8f1788cb7Holly Jiuyu Sun        configChanges = 0x0000; // 00000000.
269c93c3b9cf378e84b8a6f8fdb519a11c51d748a45Holly Jiuyu Sun        recreateOnConfigChanges = 0x0003; // 00000011.
270b6d7695cf2e7cec5c7b24e1b09e1f7d8f1788cb7Holly Jiuyu Sun        finalConfigChanges =
271c93c3b9cf378e84b8a6f8fdb519a11c51d748a45Holly Jiuyu Sun                PackageParser.getActivityConfigChanges(configChanges, recreateOnConfigChanges);
272b6d7695cf2e7cec5c7b24e1b09e1f7d8f1788cb7Holly Jiuyu Sun        assertEquals(0x0000, finalConfigChanges); // Should be 00000000.
273b6d7695cf2e7cec5c7b24e1b09e1f7d8f1788cb7Holly Jiuyu Sun
274b6d7695cf2e7cec5c7b24e1b09e1f7d8f1788cb7Holly Jiuyu Sun        // Set in configChanges.
275b6d7695cf2e7cec5c7b24e1b09e1f7d8f1788cb7Holly Jiuyu Sun        configChanges = 0x0003; // 00000011.
276c93c3b9cf378e84b8a6f8fdb519a11c51d748a45Holly Jiuyu Sun        recreateOnConfigChanges = 0X0000; // 00000000.
277b6d7695cf2e7cec5c7b24e1b09e1f7d8f1788cb7Holly Jiuyu Sun        finalConfigChanges =
278c93c3b9cf378e84b8a6f8fdb519a11c51d748a45Holly Jiuyu Sun                PackageParser.getActivityConfigChanges(configChanges, recreateOnConfigChanges);
279b6d7695cf2e7cec5c7b24e1b09e1f7d8f1788cb7Holly Jiuyu Sun        assertEquals(0x0003, finalConfigChanges); // Should be 00000011.
280b6d7695cf2e7cec5c7b24e1b09e1f7d8f1788cb7Holly Jiuyu Sun
281c93c3b9cf378e84b8a6f8fdb519a11c51d748a45Holly Jiuyu Sun        recreateOnConfigChanges = 0x0003; // 00000011.
282b6d7695cf2e7cec5c7b24e1b09e1f7d8f1788cb7Holly Jiuyu Sun        finalConfigChanges =
283c93c3b9cf378e84b8a6f8fdb519a11c51d748a45Holly Jiuyu Sun                PackageParser.getActivityConfigChanges(configChanges, recreateOnConfigChanges);
284b6d7695cf2e7cec5c7b24e1b09e1f7d8f1788cb7Holly Jiuyu Sun        assertEquals(0x0003, finalConfigChanges); // Should still be 00000011.
285b6d7695cf2e7cec5c7b24e1b09e1f7d8f1788cb7Holly Jiuyu Sun
286b6d7695cf2e7cec5c7b24e1b09e1f7d8f1788cb7Holly Jiuyu Sun        // Other bit set in configChanges.
287b6d7695cf2e7cec5c7b24e1b09e1f7d8f1788cb7Holly Jiuyu Sun        configChanges = 0x0080; // 10000000, orientation.
288c93c3b9cf378e84b8a6f8fdb519a11c51d748a45Holly Jiuyu Sun        recreateOnConfigChanges = 0x0000; // 00000000.
289b6d7695cf2e7cec5c7b24e1b09e1f7d8f1788cb7Holly Jiuyu Sun        finalConfigChanges =
290c93c3b9cf378e84b8a6f8fdb519a11c51d748a45Holly Jiuyu Sun                PackageParser.getActivityConfigChanges(configChanges, recreateOnConfigChanges);
291b6d7695cf2e7cec5c7b24e1b09e1f7d8f1788cb7Holly Jiuyu Sun        assertEquals(0x0083, finalConfigChanges); // Should be 10000011.
292b6d7695cf2e7cec5c7b24e1b09e1f7d8f1788cb7Holly Jiuyu Sun    }
2935213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer
2944501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki    Package parsePackage(String apkFileName, int apkResourceId) throws Exception {
2954501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki        return parsePackage(apkFileName, apkResourceId, p -> p);
2964501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki    }
2974501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki
2985213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer    /**
2995213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer     * Attempts to parse a package.
3005213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer     *
3015213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer     * APKs are put into coretests/apks/packageparser_*.
3025213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer     *
3034501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki     * @param apkFileName temporary file name to store apk extracted from resources
3045213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer     * @param apkResourceId identifier of the apk as a resource
3055213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer     */
3064501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki    Package parsePackage(String apkFileName, int apkResourceId,
3074501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki            Function<Package, Package> converter) throws Exception {
3085213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        // Copy the resource to a file.
3095213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
3105213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        File outFile = new File(context.getFilesDir(), apkFileName);
3115213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        try {
3125213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer            InputStream is = context.getResources().openRawResource(apkResourceId);
3135213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer            assertTrue(FileUtils.copyToFile(is, outFile));
3144501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki            return converter.apply(new PackageParser().parsePackage(outFile, 0 /* flags */));
3155213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        } finally {
3165213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer            outFile.delete();
3175213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        }
3185213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer    }
3195213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer
3205213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer    /**
3215213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer     * Asserts basic properties about a component.
3225213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer     */
3235213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer    private void assertComponent(String className, String packageName, int numIntents,
3245213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer            Component<?> component) {
3255213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        assertEquals(className, component.className);
3265213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        assertEquals(packageName, component.owner.packageName);
3275213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        assertEquals(numIntents, component.intents.size());
3285213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer    }
3295213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer
3305213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer    /**
3315213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer     * Asserts four regularly-named components of each type: one Activity, one Service, one
3325213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer     * Provider, and one Receiver.
3335213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer     * @param template templated string with %s subbed with Activity, Service, Provider, Receiver
3345213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer     */
3355213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer    private void assertOneComponentOfEachType(String template, Package p) {
3365213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        String packageName = p.packageName;
3375213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer
3385213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        assertEquals(1, p.activities.size());
3395213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        assertComponent(String.format(template, "Activity"),
3405213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer                packageName, 0 /* intents */, p.activities.get(0));
3415213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        assertEquals(1, p.services.size());
3425213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        assertComponent(String.format(template, "Service"),
3435213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer                packageName, 0 /* intents */, p.services.get(0));
3445213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        assertEquals(1, p.providers.size());
3455213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        assertComponent(String.format(template, "Provider"),
3465213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer                packageName, 0 /* intents */, p.providers.get(0));
3475213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        assertEquals(1, p.receivers.size());
3485213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        assertComponent(String.format(template, "Receiver"),
3495213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer                packageName, 0 /* intents */, p.receivers.get(0));
3505213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer    }
3515213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer
3525213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer    private void assertPermission(String name, String packageName, int protectionLevel,
3535213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer            Permission permission) {
3545213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        assertEquals(packageName, permission.owner.packageName);
3555213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        assertEquals(name, permission.info.name);
3565213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        assertEquals(protectionLevel, permission.info.protectionLevel);
3575213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer    }
3585213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer
3594501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki    private void assertMetadata(Bundle b, String... keysAndValues) {
3604501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki        assertTrue("Odd number of elements in keysAndValues", (keysAndValues.length % 2) == 0);
3614501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki
3624501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki        assertNotNull(b);
3634501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki        assertEquals(keysAndValues.length / 2, b.size());
3644501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki
3654501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki        for (int i = 0; i < keysAndValues.length; i += 2) {
3664501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki            final String key = keysAndValues[i];
3674501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki            final String value = keysAndValues[i + 1];
3684501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki
3694501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki            assertEquals(value, b.getString(key));
3704501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki        }
3714501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki    }
3724501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki
3734501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki    // TODO Add a "_cached" test for testMultiPackageComponents() too, after fixing b/64295061.
3744501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki    // Package.writeToParcel can't handle circular package references.
3754501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki
3764501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki    @Test
3774501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki    public void testPackageWithComponents_no_cache() throws Exception {
3784501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki        checkPackageWithComponents(p -> p);
3794501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki    }
3804501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki
3815213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer    @Test
3824501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki    public void testPackageWithComponents_cached() throws Exception {
3834501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki        checkPackageWithComponents(p ->
3844501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki                PackageParser.fromCacheEntryStatic(PackageParser.toCacheEntryStatic(p)));
3854501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki    }
3864501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki
3874501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki    private void checkPackageWithComponents(
3884501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki            Function<Package, Package> converter) throws Exception {
3895213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        Package p = parsePackage(
3904501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki                "install_complete_package_info.apk", R.raw.install_complete_package_info,
3914501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki                converter);
3925213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        String packageName = "com.android.frameworks.coretests.install_complete_package_info";
3935213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer
3945213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        assertEquals(packageName, p.packageName);
3955213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        assertEquals(1, p.permissions.size());
3965213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        assertPermission(
3975213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer                "com.android.frameworks.coretests.install_complete_package_info.test_permission",
3985213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer                packageName, PermissionInfo.PROTECTION_NORMAL, p.permissions.get(0));
3995213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer
4005213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        assertOneComponentOfEachType("com.android.frameworks.coretests.Test%s", p);
4014501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki
4024501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki        assertMetadata(p.mAppMetaData,
4034501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki                "key1", "value1",
4044501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki                "key2", "this_is_app");
4054501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki        assertMetadata(p.activities.get(0).metaData,
4064501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki                "key1", "value1",
4074501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki                "key2", "this_is_activity");
4084501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki        assertMetadata(p.services.get(0).metaData,
4094501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki                "key1", "value1",
4104501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki                "key2", "this_is_service");
4114501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki        assertMetadata(p.receivers.get(0).metaData,
4124501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki                "key1", "value1",
4134501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki                "key2", "this_is_receiver");
4144501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki        assertMetadata(p.providers.get(0).metaData,
4154501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki                "key1", "value1",
4164501c61d65f0590bdc4e6a8a6f3a1b0cf2165b9fMakoto Onuki                "key2", "this_is_provider");
4175213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer    }
4185213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer
41917041530bfa8199414b8480691303739b30126b4Garrett Boyer    /**
42017041530bfa8199414b8480691303739b30126b4Garrett Boyer     * Determines if the current device supports multi-package APKs.
42117041530bfa8199414b8480691303739b30126b4Garrett Boyer     */
42217041530bfa8199414b8480691303739b30126b4Garrett Boyer    private boolean supportsMultiPackageApk() {
42317041530bfa8199414b8480691303739b30126b4Garrett Boyer        return SystemProperties.getBoolean("persist.sys.child_packages_enabled", false);
42417041530bfa8199414b8480691303739b30126b4Garrett Boyer    }
42517041530bfa8199414b8480691303739b30126b4Garrett Boyer
4265213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer    @Test
4275213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer    public void testMultiPackageComponents() throws Exception {
42817041530bfa8199414b8480691303739b30126b4Garrett Boyer        // TODO(gboyer): Remove once we decide to launch multi-package APKs.
42917041530bfa8199414b8480691303739b30126b4Garrett Boyer        if (!supportsMultiPackageApk()) {
43017041530bfa8199414b8480691303739b30126b4Garrett Boyer            return;
43117041530bfa8199414b8480691303739b30126b4Garrett Boyer        }
4325213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        String parentName = "com.android.frameworks.coretests.install_multi_package";
4335213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        String firstChildName =
4345213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer                "com.android.frameworks.coretests.install_multi_package.first_child";
4355213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        String secondChildName =  // NOTE: intentionally inconsistent!
4365213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer                "com.android.frameworks.coretests.blah.second_child";
4375213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer
4385213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        Package parent = parsePackage("install_multi_package.apk", R.raw.install_multi_package);
4395213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        assertEquals(parentName, parent.packageName);
4405213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        assertEquals(2, parent.childPackages.size());
4415213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        assertOneComponentOfEachType("com.android.frameworks.coretests.Test%s", parent);
4425213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        assertEquals(1, parent.permissions.size());
4435213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        assertPermission(parentName + ".test_permission", parentName,
4445213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer                PermissionInfo.PROTECTION_NORMAL, parent.permissions.get(0));
4455213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        assertEquals(Arrays.asList("android.permission.INTERNET"),
4465213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer                parent.requestedPermissions);
4475213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer
4485213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        Package firstChild = parent.childPackages.get(0);
4495213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        assertEquals(firstChildName, firstChild.packageName);
4505213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        assertOneComponentOfEachType(
4515213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer                "com.android.frameworks.coretests.FirstChildTest%s", firstChild);
4525213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        assertEquals(0, firstChild.permissions.size());  // Child APKs cannot declare permissions.
4535213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        assertEquals(Arrays.asList("android.permission.NFC"),
4545213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer                firstChild.requestedPermissions);
4555213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer
4565213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        Package secondChild = parent.childPackages.get(1);
4575213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        assertEquals(secondChildName, secondChild.packageName);
4585213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        assertOneComponentOfEachType(
4595213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer                "com.android.frameworks.coretests.SecondChildTest%s", secondChild);
4605213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        assertEquals(0, secondChild.permissions.size());  // Child APKs cannot declare permissions.
4615213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer        assertEquals(
4625213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer                Arrays.asList(
4635213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer                        "android.permission.ACCESS_NETWORK_STATE",
4645213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer                        "android.permission.READ_CONTACTS"),
4655213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer                secondChild.requestedPermissions);
4665213666521ceb6254cdc48b79d50ad3ffacaac01Garrett Boyer    }
46782f4b263a09630b9937ecb2cc3dea5b21eaa7b8fAlan Viverette}
468