diff options
9 files changed, 351 insertions, 1 deletions
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index a8cc5fdf884d..17ec51181a89 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -11524,8 +11524,31 @@ public class PackageManagerService extends IPackageManager.Stub if (getInstantAppPackageName(Binder.getCallingUid()) != null) { return; } + final List<String> names = new ArrayList<>(); + final List<ProviderInfo> infos = new ArrayList<>(); + final int callingUserId = UserHandle.getCallingUserId(); mComponentResolver.querySyncProviders( - outNames, outInfo, mSafeMode, UserHandle.getCallingUserId()); + names, infos, mSafeMode, callingUserId); + synchronized (mLock) { + for (int i = infos.size() - 1; i >= 0; i--) { + final ProviderInfo providerInfo = infos.get(i); + final PackageSetting ps = mSettings.getPackageLPr(providerInfo.packageName); + final ComponentName component = + new ComponentName(providerInfo.packageName, providerInfo.name); + if (!shouldFilterApplicationLocked(ps, Binder.getCallingUid(), component, + TYPE_PROVIDER, callingUserId)) { + continue; + } + infos.remove(i); + names.remove(i); + } + } + if (!names.isEmpty()) { + outNames.addAll(names); + } + if (!infos.isEmpty()) { + outInfo.addAll(infos); + } } @Override diff --git a/services/core/java/com/android/server/pm/TEST_MAPPING b/services/core/java/com/android/server/pm/TEST_MAPPING index b7a069e10b67..2b62255adbaa 100644 --- a/services/core/java/com/android/server/pm/TEST_MAPPING +++ b/services/core/java/com/android/server/pm/TEST_MAPPING @@ -13,6 +13,9 @@ "name": "CtsAppEnumerationTestCases" }, { + "name": "AppEnumerationInternalTests" + }, + { "name": "CtsMatchFlagTestCases" }, { diff --git a/services/tests/PackageManagerServiceTests/appenumeration/Android.bp b/services/tests/PackageManagerServiceTests/appenumeration/Android.bp new file mode 100644 index 000000000000..479ef8e5f188 --- /dev/null +++ b/services/tests/PackageManagerServiceTests/appenumeration/Android.bp @@ -0,0 +1,36 @@ +// Copyright (C) 2021 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 { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "frameworks_base_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["frameworks_base_license"], +} + +android_test { + name: "AppEnumerationInternalTests", + srcs: [ + "src/**/*.java", + ], + static_libs: [ + "compatibility-device-util-axt", + "androidx.test.runner", + "truth-prebuilt", + ], + platform_apis: true, + test_suites: ["device-tests"], +} diff --git a/services/tests/PackageManagerServiceTests/appenumeration/AndroidManifest.xml b/services/tests/PackageManagerServiceTests/appenumeration/AndroidManifest.xml new file mode 100644 index 000000000000..2039aaa20945 --- /dev/null +++ b/services/tests/PackageManagerServiceTests/appenumeration/AndroidManifest.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2021 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.server.pm.test.appenumeration"> + + <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner" + android:targetPackage="com.android.server.pm.test.appenumeration" + android:label="Package Manager Service Tests for app enumeration"> + </instrumentation> + +</manifest> + diff --git a/services/tests/PackageManagerServiceTests/appenumeration/AndroidTest.xml b/services/tests/PackageManagerServiceTests/appenumeration/AndroidTest.xml new file mode 100644 index 000000000000..6f168a3888b3 --- /dev/null +++ b/services/tests/PackageManagerServiceTests/appenumeration/AndroidTest.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2021 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. + --> + +<configuration description="Runs Package Manager Service App Enumeration Tests."> + <option name="test-suite-tag" value="apct" /> + <option name="test-suite-tag" value="apct-instrumentation" /> + <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> + <option name="cleanup-apks" value="true" /> + <option name="test-file-name" value="AppEnumerationInternalTests.apk" /> + </target_preparer> + + <!-- Create place to store apks --> + <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer"> + <option name="run-command" value="mkdir -p /data/local/tmp/appenumerationtests" /> + <option name="teardown-command" value="rm -rf /data/local/tmp/appenumerationtests"/> + </target_preparer> + + <!-- Load additional APKs onto device --> + <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher"> + <option name="push" value="AppEnumerationSyncProviderTestApp.apk->/data/local/tmp/appenumerationtests/AppEnumerationSyncProviderTestApp.apk" /> + </target_preparer> + + <option name="test-tag" value="AppEnumerationInternalTest" /> + <test class="com.android.tradefed.testtype.AndroidJUnitTest"> + <option name="package" value="com.android.server.pm.test.appenumeration" /> + <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" /> + <option name="hidden-api-checks" value="false" /> + </test> +</configuration> diff --git a/services/tests/PackageManagerServiceTests/appenumeration/src/com/android/server/pm/test/appenumeration/AppEnumerationInternalTests.java b/services/tests/PackageManagerServiceTests/appenumeration/src/com/android/server/pm/test/appenumeration/AppEnumerationInternalTests.java new file mode 100644 index 000000000000..933784560410 --- /dev/null +++ b/services/tests/PackageManagerServiceTests/appenumeration/src/com/android/server/pm/test/appenumeration/AppEnumerationInternalTests.java @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2021 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.server.pm.test.appenumeration; + +import static com.android.compatibility.common.util.ShellUtils.runShellCommand; + +import static com.google.common.truth.Truth.assertThat; + +import android.app.AppGlobals; +import android.content.pm.IPackageManager; +import android.content.pm.ProviderInfo; + +import androidx.test.runner.AndroidJUnit4; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Application enumeration tests for the internal apis of package manager service. + */ +@RunWith(AndroidJUnit4.class) +public class AppEnumerationInternalTests { + private static final String TEST_DATA_PATH = "/data/local/tmp/appenumerationtests/"; + private static final String SYNC_PROVIDER_APK_PATH = + TEST_DATA_PATH + "AppEnumerationSyncProviderTestApp.apk"; + private static final String SYNC_PROVIDER_PKG_NAME = "com.android.appenumeration.syncprovider"; + private static final String SYNC_PROVIDER_AUTHORITY = SYNC_PROVIDER_PKG_NAME; + + private IPackageManager mIPackageManager; + + @Before + public void setup() { + mIPackageManager = AppGlobals.getPackageManager(); + } + + @After + public void tearDown() throws Exception { + uninstallPackage(SYNC_PROVIDER_PKG_NAME); + } + + @Test + public void querySyncProviders_canSeeForceQueryable() throws Exception { + final List<String> names = new ArrayList<>(); + final List<ProviderInfo> infos = new ArrayList<>(); + installPackage(SYNC_PROVIDER_APK_PATH, true /* forceQueryable */); + mIPackageManager.querySyncProviders(names, infos); + + assertThat(names).contains(SYNC_PROVIDER_AUTHORITY); + assertThat(infos.stream().map(info -> info.packageName).collect(Collectors.toList())) + .contains(SYNC_PROVIDER_PKG_NAME); + } + + @Test + public void querySyncProviders_cannotSeeSyncProvider() throws Exception { + final List<String> names = new ArrayList<>(); + final List<ProviderInfo> infos = new ArrayList<>(); + installPackage(SYNC_PROVIDER_APK_PATH, false /* forceQueryable */); + mIPackageManager.querySyncProviders(names, infos); + + assertThat(names).doesNotContain(SYNC_PROVIDER_AUTHORITY); + assertThat(infos.stream().map(info -> info.packageName).collect(Collectors.toList())) + .doesNotContain(SYNC_PROVIDER_PKG_NAME); + } + + private static void installPackage(String apkPath, boolean forceQueryable) { + final StringBuilder cmd = new StringBuilder("pm install "); + if (forceQueryable) { + cmd.append("--force-queryable "); + } + cmd.append(apkPath); + final String result = runShellCommand(cmd.toString()); + assertThat(result.trim()).contains("Success"); + } + + private static void uninstallPackage(String packageName) { + runShellCommand("pm uninstall " + packageName); + } +} diff --git a/services/tests/PackageManagerServiceTests/appenumeration/test-apps/target/Android.bp b/services/tests/PackageManagerServiceTests/appenumeration/test-apps/target/Android.bp new file mode 100644 index 000000000000..64239b4c6b2d --- /dev/null +++ b/services/tests/PackageManagerServiceTests/appenumeration/test-apps/target/Android.bp @@ -0,0 +1,36 @@ +// Copyright (C) 2021 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 { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "frameworks_base_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["frameworks_base_license"], +} + +android_test_helper_app { + name: "AppEnumerationSyncProviderTestApp", + srcs: ["src/**/*.java"], + manifest: "AndroidManifest-syncprovider.xml", + dex_preopt: { + enabled: false, + }, + optimize: { + enabled: false, + }, + test_suites: ["device-tests"], + platform_apis: true, +} diff --git a/services/tests/PackageManagerServiceTests/appenumeration/test-apps/target/AndroidManifest-syncprovider.xml b/services/tests/PackageManagerServiceTests/appenumeration/test-apps/target/AndroidManifest-syncprovider.xml new file mode 100644 index 000000000000..de8439384b54 --- /dev/null +++ b/services/tests/PackageManagerServiceTests/appenumeration/test-apps/target/AndroidManifest-syncprovider.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2021 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.appenumeration.syncprovider"> + <application> + <provider android:name="com.android.appenumeration.testapp.DummyProvider" + android:authorities="com.android.appenumeration.syncprovider" + android:syncable="true" android:exported="true"> + <intent-filter> + <action android:name="com.android.appenumeration.action.PROVIDER"/> + </intent-filter> + </provider> + </application> +</manifest> diff --git a/services/tests/PackageManagerServiceTests/appenumeration/test-apps/target/src/com/android/appenumeration/testapp/DummyProvider.java b/services/tests/PackageManagerServiceTests/appenumeration/test-apps/target/src/com/android/appenumeration/testapp/DummyProvider.java new file mode 100644 index 000000000000..e8b610969c2f --- /dev/null +++ b/services/tests/PackageManagerServiceTests/appenumeration/test-apps/target/src/com/android/appenumeration/testapp/DummyProvider.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2021 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.appenumeration.testapp; + +import android.content.ContentProvider; +import android.content.ContentValues; +import android.database.Cursor; +import android.net.Uri; + +public class DummyProvider extends ContentProvider { + @Override + public boolean onCreate() { + return true; + } + + @Override + public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, + String sortOrder) { + return null; + } + + @Override + public Uri insert(Uri uri, ContentValues values) { + return null; + } + + @Override + public int delete(Uri uri, String selection, String[] selectionArgs) { + return 0; + } + + @Override + public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { + return 0; + } + + @Override + public String getType(Uri uri) { + return "text/plain"; + } +} |