Merge "Add CTS tests to ensure platform extensions are present" into nyc-dev
diff --git a/tests/tests/os/src/android/os/cts/RequiredComponentsTest.java b/tests/tests/os/src/android/os/cts/RequiredComponentsTest.java
new file mode 100644
index 0000000..378ac09
--- /dev/null
+++ b/tests/tests/os/src/android/os/cts/RequiredComponentsTest.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2016 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os.cts;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.net.Uri;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.File;
+import java.util.List;
+
+import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
+import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
+import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
+
+/**
+ * Tests whether all platform components that are implemented
+ * as APKs for various reasons are present.
+ */
+@RunWith(AndroidJUnit4.class)
+public class RequiredComponentsTest {
+ private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
+
+ @Test
+ public void testPackageInstallerPresent() throws Exception {
+ Intent installerIntent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
+ installerIntent.addCategory(Intent.CATEGORY_DEFAULT);
+ installerIntent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
+ List<ResolveInfo> installers = InstrumentationRegistry.getContext()
+ .getPackageManager().queryIntentActivities(installerIntent, MATCH_SYSTEM_ONLY
+ | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
+ if (installers.size() == 1) {
+ ResolveInfo resolveInfo = installers.get(0);
+ if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
+ fail("The installer must be a privileged app");
+ }
+ } else {
+ fail("There must be exactly one installer; found " + installers);
+ }
+ }
+
+ @Test
+ public void testExtServicesPresent() throws Exception {
+ enforceSharedLibPresentAndProperlyHosted(
+ PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES,
+ ApplicationInfo.FLAG_SYSTEM,
+ ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
+ }
+
+ @Test
+ public void testSharedServicesPresent() throws Exception {
+ enforceSharedLibPresentAndProperlyHosted(
+ PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
+ ApplicationInfo.FLAG_SYSTEM, 0);
+ }
+
+ private void enforceSharedLibPresentAndProperlyHosted(String libName,
+ int requiredHostAppFlags, int requiredHostAppPrivateFlags) throws Exception {
+ PackageManager packageManager = InstrumentationRegistry.getContext()
+ .getPackageManager();
+
+ // Is the lib present?
+ String[] libs = packageManager.getSystemSharedLibraryNames();
+ boolean libPresent = false;
+ for (String lib : libs) {
+ if (libName.equals(lib)) {
+ libPresent = true;
+ break;
+ }
+ }
+ if (!libPresent) {
+ fail("Missing required shared library:" + libName);
+ }
+
+ // Is it properly hosted?
+ String packageName = packageManager.getServicesSystemSharedLibraryPackageName();
+ PackageInfo packageInfo = packageManager.getPackageInfo(packageName, 0);
+
+ assertTrue(libName + " must be hosted by a system app with flags:"
+ + requiredHostAppFlags, (packageInfo.applicationInfo.flags
+ & requiredHostAppFlags) == requiredHostAppFlags);
+
+ assertTrue(libName + " must be hosted by a system app with private flags:"
+ + requiredHostAppPrivateFlags, (packageInfo.applicationInfo.privateFlags
+ & requiredHostAppPrivateFlags) == requiredHostAppPrivateFlags);
+ }
+}