Expand the number of signature tests

Replaces CtsApiSignatureTestCases which tests whether the runtime seen
by an app that has <uses-library android:name="android.test.runner"/> in
its manifest provides the API in frameworks/bases/api/current.txt with a
number of tests that test different app configurations.

CtsCurrentApiSignatureTestCases
    tests that an app that is targeted at the current API level and does
    not have any <uses-library> entries in its manifest can access the
    API described in frameworks/base/api/current.txt - excluding APIs
    provided by the android.test.runner and android.test.mock libraries.

CtsSystemCurrentApiSignatureTestCases
    tests that an app that is targeted at the current API level and does
    not have any <uses-library> entries in its manifest can access the
    API described in frameworks/base/api/system-current.txt - excluding
    APIs provided by the android.test.runner and android.test.mock
    libraries.

CtsAndroidTestMockCurrentApiSignatureTestCases
    tests that an app that is targeted at the current API level and has
    <uses-library android:name="android.test.mock"/> in its manifest can
    access the API described in
    frameworks/base/test-runner/api/android-test-mock-current.txt.

CtsAndroidTestRunnerCurrentApiSignatureTestCases
    tests that an app that is targeted at the current API level and has
    <uses-library android:name="android.test.runner"/> in its manifest
    can access the API described in
    frameworks/base/test-runner/api/android-test-runner-current.txt and
    in frameworks/base/test-runner/api/android-test-mock-current.txt.

CtsLegacyTest26ApiSignatureTestCases
    tests that an app that is targeted at API level 26 can access the
    API described in
    frameworks/base/legacy-test/api/legacy-test-current.txt.

Adds tests/signature/runSignatureTests.sh to run the above tests.

The rest of the changes are made to support the above tests:
* Changes SignatureTest and other Java files to support providing an API
  description file containing classes that are not expected to be
  accessible to the application. This is used to ensure that optional
  classes are not visible unless specifically requested.

* Generates additional *.api files for use by the above tests.

* Refactors the makefiles for generating *.api files and building test
  APKs to extract the common behavior into separate reusable *.mk files
  to reduce duplication.

Bug: 35192974
Bug: 30188076
Test: ran tests/signature/runSignatureTests.sh
Change-Id: Ibb178052a6098e4b42921067ae8ec86d6e7cb379
diff --git a/tests/signature/api-check/Android.mk b/tests/signature/api-check/Android.mk
index 932753c..013cc4d 100644
--- a/tests/signature/api-check/Android.mk
+++ b/tests/signature/api-check/Android.mk
@@ -12,7 +12,11 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-LOCAL_PATH:= $(call my-dir)
+LOCAL_PATH := $(call my-dir)
+
+# cts-api-signature-test java library
+# ===================================
+
 include $(CLEAR_VARS)
 
 # don't include this package in any target
@@ -20,10 +24,7 @@
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_PACKAGE_NAME := CtsApiSignatureTestCases
-
-# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_MODULE := cts-api-signature-test
 
 LOCAL_SDK_VERSION := current
 
@@ -32,4 +33,6 @@
     repackaged-legacy-test \
     repackaged.android.test.runner \
 
-include $(BUILD_CTS_PACKAGE)
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/signature/api-check/android-test-mock-current-api/Android.mk b/tests/signature/api-check/android-test-mock-current-api/Android.mk
new file mode 100644
index 0000000..b60f6a3
--- /dev/null
+++ b/tests/signature/api-check/android-test-mock-current-api/Android.mk
@@ -0,0 +1,24 @@
+# Copyright (C) 2017 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.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsAndroidTestMockCurrentApiSignatureTestCases
+
+LOCAL_SIGNATURE_API_FILES := \
+    android-test-mock-current.api \
+
+include $(LOCAL_PATH)/../build_signature_apk.mk
diff --git a/tests/signature/api-check/AndroidManifest.xml b/tests/signature/api-check/android-test-mock-current-api/AndroidManifest.xml
similarity index 81%
copy from tests/signature/api-check/AndroidManifest.xml
copy to tests/signature/api-check/android-test-mock-current-api/AndroidManifest.xml
index dbeccf5..5c88521 100644
--- a/tests/signature/api-check/AndroidManifest.xml
+++ b/tests/signature/api-check/android-test-mock-current-api/AndroidManifest.xml
@@ -16,16 +16,16 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.signature.cts.api">
+          package="android.signature.cts.api.android_test_mock_current">
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
 
     <application>
-        <uses-library android:name="android.test.runner"/>
+        <uses-library android:name="android.test.mock"/>
     </application>
 
     <instrumentation android:name="repackaged.android.test.InstrumentationTestRunner"
-                     android:targetPackage="android.signature.cts.api"
-                     android:label="API Signature Test"/>
+                     android:targetPackage="android.signature.cts.api.android_test_mock_current"
+                     android:label="Android Test Mock Current API Signature Test"/>
 
 </manifest>
diff --git a/tests/signature/api-check/AndroidTest.xml b/tests/signature/api-check/android-test-mock-current-api/AndroidTest.xml
similarity index 79%
copy from tests/signature/api-check/AndroidTest.xml
copy to tests/signature/api-check/android-test-mock-current-api/AndroidTest.xml
index a52d3df..c7cd631 100644
--- a/tests/signature/api-check/AndroidTest.xml
+++ b/tests/signature/api-check/android-test-mock-current-api/AndroidTest.xml
@@ -20,16 +20,16 @@
         <option name="teardown-command" value="rm -rf /data/local/tmp/signature-test" />
     </target_preparer>
     <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
-        <option name="push" value="current.api->/data/local/tmp/signature-test/current.api" />
+        <option name="push" value="android-test-mock-current.api->/data/local/tmp/signature-test/android-test-mock-current.api" />
     </target_preparer>
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
-        <option name="test-file-name" value="CtsApiSignatureTestCases.apk" />
+        <option name="test-file-name" value="CtsAndroidTestMockCurrentApiSignatureTestCases.apk" />
     </target_preparer>
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="android.signature.cts.api" />
+        <option name="package" value="android.signature.cts.api.android_test_mock_current" />
         <option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
-        <option name="instrumentation-arg" key="expected-api-files" value="current.api" />
-        <option name="runtime-hint" value="30s" />
+        <option name="instrumentation-arg" key="expected-api-files" value="android-test-mock-current.api" />
+        <option name="runtime-hint" value="5s" />
     </test>
 </configuration>
diff --git a/tests/signature/api-check/android-test-runner-current-api/Android.mk b/tests/signature/api-check/android-test-runner-current-api/Android.mk
new file mode 100644
index 0000000..d840506
--- /dev/null
+++ b/tests/signature/api-check/android-test-runner-current-api/Android.mk
@@ -0,0 +1,25 @@
+# Copyright (C) 2017 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.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsAndroidTestRunnerCurrentApiSignatureTestCases
+
+LOCAL_SIGNATURE_API_FILES := \
+    android-test-mock-current.api \
+    android-test-runner-current.api \
+
+include $(LOCAL_PATH)/../build_signature_apk.mk
diff --git a/tests/signature/api-check/AndroidManifest.xml b/tests/signature/api-check/android-test-runner-current-api/AndroidManifest.xml
similarity index 85%
rename from tests/signature/api-check/AndroidManifest.xml
rename to tests/signature/api-check/android-test-runner-current-api/AndroidManifest.xml
index dbeccf5..61de501 100644
--- a/tests/signature/api-check/AndroidManifest.xml
+++ b/tests/signature/api-check/android-test-runner-current-api/AndroidManifest.xml
@@ -16,7 +16,7 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.signature.cts.api">
+          package="android.signature.cts.api.android_test_runner_current">
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
 
@@ -25,7 +25,7 @@
     </application>
 
     <instrumentation android:name="repackaged.android.test.InstrumentationTestRunner"
-                     android:targetPackage="android.signature.cts.api"
-                     android:label="API Signature Test"/>
+                     android:targetPackage="android.signature.cts.api.android_test_runner_current"
+                     android:label="Android Test Runner Current API Signature Test"/>
 
 </manifest>
diff --git a/tests/signature/api-check/AndroidTest.xml b/tests/signature/api-check/android-test-runner-current-api/AndroidTest.xml
similarity index 69%
copy from tests/signature/api-check/AndroidTest.xml
copy to tests/signature/api-check/android-test-runner-current-api/AndroidTest.xml
index a52d3df..72b3b8b 100644
--- a/tests/signature/api-check/AndroidTest.xml
+++ b/tests/signature/api-check/android-test-runner-current-api/AndroidTest.xml
@@ -20,16 +20,19 @@
         <option name="teardown-command" value="rm -rf /data/local/tmp/signature-test" />
     </target_preparer>
     <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
-        <option name="push" value="current.api->/data/local/tmp/signature-test/current.api" />
+        <option name="push" value="android-test-mock-current.api->/data/local/tmp/signature-test/android-test-mock-current.api" />
+    </target_preparer>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
+        <option name="push" value="android-test-runner-current.api->/data/local/tmp/signature-test/android-test-runner-current.api" />
     </target_preparer>
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
-        <option name="test-file-name" value="CtsApiSignatureTestCases.apk" />
+        <option name="test-file-name" value="CtsAndroidTestRunnerCurrentApiSignatureTestCases.apk" />
     </target_preparer>
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="android.signature.cts.api" />
+        <option name="package" value="android.signature.cts.api.android_test_runner_current" />
         <option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
-        <option name="instrumentation-arg" key="expected-api-files" value="current.api" />
-        <option name="runtime-hint" value="30s" />
+        <option name="instrumentation-arg" key="expected-api-files" value="android-test-mock-current.api,android-test-runner-current.api" />
+        <option name="runtime-hint" value="5s" />
     </test>
 </configuration>
diff --git a/tests/signature/api-check/build_signature_apk.mk b/tests/signature/api-check/build_signature_apk.mk
new file mode 100644
index 0000000..f05d1a6
--- /dev/null
+++ b/tests/signature/api-check/build_signature_apk.mk
@@ -0,0 +1,38 @@
+# Copyright (C) 2017 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.
+
+# Specify the following variables before including:
+#
+#     LOCAL_PACKAGE_NAME
+#         the name of the package
+#
+#     LOCAL_SIGNATURE_API_FILES
+#         the list of api files needed
+
+# don't include this package in any target
+LOCAL_MODULE_TAGS := optional
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts general-tests
+
+LOCAL_SDK_VERSION := current
+
+LOCAL_STATIC_JAVA_LIBRARIES := cts-api-signature-test
+
+LOCAL_ADDITIONAL_DEPENDENCIES += \
+    $(addprefix $(COMPATIBILITY_TESTCASES_OUT_cts)/,$(LOCAL_SIGNATURE_API_FILES))
+
+include $(BUILD_CTS_PACKAGE)
+
+LOCAL_SIGNATURE_API_FILES :=
diff --git a/tests/signature/api-check/current-api/Android.mk b/tests/signature/api-check/current-api/Android.mk
new file mode 100644
index 0000000..0e7997d
--- /dev/null
+++ b/tests/signature/api-check/current-api/Android.mk
@@ -0,0 +1,26 @@
+# Copyright (C) 2017 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.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsCurrentApiSignatureTestCases
+
+LOCAL_SIGNATURE_API_FILES := \
+    current.api \
+    android-test-mock-current.api \
+    android-test-runner-current.api \
+
+include $(LOCAL_PATH)/../build_signature_apk.mk
diff --git a/tests/signature/api-check/AndroidManifest.xml b/tests/signature/api-check/current-api/AndroidManifest.xml
similarity index 83%
copy from tests/signature/api-check/AndroidManifest.xml
copy to tests/signature/api-check/current-api/AndroidManifest.xml
index dbeccf5..7dc5730 100644
--- a/tests/signature/api-check/AndroidManifest.xml
+++ b/tests/signature/api-check/current-api/AndroidManifest.xml
@@ -16,16 +16,14 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.signature.cts.api">
+          package="android.signature.cts.api.current">
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
 
-    <application>
-        <uses-library android:name="android.test.runner"/>
-    </application>
+    <application/>
 
     <instrumentation android:name="repackaged.android.test.InstrumentationTestRunner"
-                     android:targetPackage="android.signature.cts.api"
-                     android:label="API Signature Test"/>
+                     android:targetPackage="android.signature.cts.api.current"
+                     android:label="Current API Signature Test"/>
 
 </manifest>
diff --git a/tests/signature/api-check/AndroidTest.xml b/tests/signature/api-check/current-api/AndroidTest.xml
similarity index 69%
copy from tests/signature/api-check/AndroidTest.xml
copy to tests/signature/api-check/current-api/AndroidTest.xml
index a52d3df..0576f9e 100644
--- a/tests/signature/api-check/AndroidTest.xml
+++ b/tests/signature/api-check/current-api/AndroidTest.xml
@@ -22,14 +22,21 @@
     <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
         <option name="push" value="current.api->/data/local/tmp/signature-test/current.api" />
     </target_preparer>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
+        <option name="push" value="android-test-mock-current.api->/data/local/tmp/signature-test/android-test-mock-current.api" />
+    </target_preparer>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
+        <option name="push" value="android-test-runner-current.api->/data/local/tmp/signature-test/android-test-runner-current.api" />
+    </target_preparer>
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
-        <option name="test-file-name" value="CtsApiSignatureTestCases.apk" />
+        <option name="test-file-name" value="CtsCurrentApiSignatureTestCases.apk" />
     </target_preparer>
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="android.signature.cts.api" />
+        <option name="package" value="android.signature.cts.api.current" />
         <option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
         <option name="instrumentation-arg" key="expected-api-files" value="current.api" />
+        <option name="instrumentation-arg" key="unexpected-api-files" value="android-test-mock-current.api,android-test-runner-current.api" />
         <option name="runtime-hint" value="30s" />
     </test>
 </configuration>
diff --git a/tests/signature/api-check/legacy-test-26-api/Android.mk b/tests/signature/api-check/legacy-test-26-api/Android.mk
new file mode 100644
index 0000000..699bd0c
--- /dev/null
+++ b/tests/signature/api-check/legacy-test-26-api/Android.mk
@@ -0,0 +1,24 @@
+# Copyright (C) 2017 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.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsLegacyTest26ApiSignatureTestCases
+
+LOCAL_SIGNATURE_API_FILES := \
+    legacy-test-current.api \
+
+include $(LOCAL_PATH)/../build_signature_apk.mk
diff --git a/tests/signature/api-check/AndroidManifest.xml b/tests/signature/api-check/legacy-test-26-api/AndroidManifest.xml
similarity index 80%
copy from tests/signature/api-check/AndroidManifest.xml
copy to tests/signature/api-check/legacy-test-26-api/AndroidManifest.xml
index dbeccf5..636dfd3 100644
--- a/tests/signature/api-check/AndroidManifest.xml
+++ b/tests/signature/api-check/legacy-test-26-api/AndroidManifest.xml
@@ -16,16 +16,16 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.signature.cts.api">
+          package="android.signature.cts.api.legacy_test_26">
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
 
-    <application>
-        <uses-library android:name="android.test.runner"/>
-    </application>
+    <uses-sdk android:minSdkVersion="25" android:targetSdkVersion="26"/>
+
+    <application/>
 
     <instrumentation android:name="repackaged.android.test.InstrumentationTestRunner"
-                     android:targetPackage="android.signature.cts.api"
-                     android:label="API Signature Test"/>
+                     android:targetPackage="android.signature.cts.api.legacy_test_26"
+                     android:label="Legacy Test 26 API Signature Test"/>
 
 </manifest>
diff --git a/tests/signature/api-check/AndroidTest.xml b/tests/signature/api-check/legacy-test-26-api/AndroidTest.xml
similarity index 80%
rename from tests/signature/api-check/AndroidTest.xml
rename to tests/signature/api-check/legacy-test-26-api/AndroidTest.xml
index a52d3df..ad30330 100644
--- a/tests/signature/api-check/AndroidTest.xml
+++ b/tests/signature/api-check/legacy-test-26-api/AndroidTest.xml
@@ -20,16 +20,16 @@
         <option name="teardown-command" value="rm -rf /data/local/tmp/signature-test" />
     </target_preparer>
     <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
-        <option name="push" value="current.api->/data/local/tmp/signature-test/current.api" />
+        <option name="push" value="legacy-test-current.api->/data/local/tmp/signature-test/legacy-test-current.api" />
     </target_preparer>
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
-        <option name="test-file-name" value="CtsApiSignatureTestCases.apk" />
+        <option name="test-file-name" value="CtsLegacyTest26ApiSignatureTestCases.apk" />
     </target_preparer>
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="android.signature.cts.api" />
+        <option name="package" value="android.signature.cts.api.legacy_test_26" />
         <option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
-        <option name="instrumentation-arg" key="expected-api-files" value="current.api" />
-        <option name="runtime-hint" value="30s" />
+        <option name="instrumentation-arg" key="expected-api-files" value="legacy-test-current.api" />
+        <option name="runtime-hint" value="5s" />
     </test>
 </configuration>
diff --git a/tests/signature/api-check/src/android/signature/cts/api/SignatureTest.java b/tests/signature/api-check/src/android/signature/cts/api/SignatureTest.java
index 592ba34..08cc051 100644
--- a/tests/signature/api-check/src/android/signature/cts/api/SignatureTest.java
+++ b/tests/signature/api-check/src/android/signature/cts/api/SignatureTest.java
@@ -21,9 +21,16 @@
 import android.signature.cts.ApiComplianceChecker;
 import android.signature.cts.FailureType;
 import android.signature.cts.JDiffClassDescription;
+import android.signature.cts.ReflectionHelper;
 import android.signature.cts.ResultObserver;
 import java.io.File;
 import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.TreeSet;
+import org.xmlpull.v1.XmlPullParserException;
 import repackaged.android.test.InstrumentationTestCase;
 import repackaged.android.test.InstrumentationTestRunner;
 
@@ -36,9 +43,24 @@
 
     private static final String TAG = SignatureTest.class.getSimpleName();
 
+    /**
+     * A set of class names that are inaccessible for some reason.
+     */
+    private static final Set<String> KNOWN_INACCESSIBLE_CLASSES = new HashSet<>();
+
+    static {
+        // TODO(b/63383787) - These classes, which are nested annotations with @Retention(SOURCE)
+        // are removed from framework.dex for an as yet unknown reason.
+        KNOWN_INACCESSIBLE_CLASSES.add("android.content.pm.PackageManager.PermissionFlags");
+        KNOWN_INACCESSIBLE_CLASSES.add("android.os.UserManager.UserRestrictionSource");
+        KNOWN_INACCESSIBLE_CLASSES.add(
+                "android.service.persistentdata.PersistentDataBlockManager.FlashLockState");
+    }
+
     private TestResultObserver mResultObserver;
 
     private String[] expectedApiFiles;
+    private String[] unexpectedApiFiles;
 
     private class TestResultObserver implements ResultObserver {
 
@@ -67,8 +89,16 @@
         Bundle instrumentationArgs =
                 ((InstrumentationTestRunner) getInstrumentation()).getArguments();
 
-        String argument = instrumentationArgs.getString("expected-api-files");
-        expectedApiFiles = argument.split(",");
+        expectedApiFiles = getCommaSeparatedList(instrumentationArgs, "expected-api-files");
+        unexpectedApiFiles = getCommaSeparatedList(instrumentationArgs, "unexpected-api-files");
+    }
+
+    private String[] getCommaSeparatedList(Bundle instrumentationArgs, String key) {
+        String argument = instrumentationArgs.getString(key);
+        if (argument == null) {
+            return new String[0];
+        }
+        return argument.split(",");
     }
 
     /**
@@ -78,12 +108,31 @@
      */
     public void testSignature() {
         try {
+            Set<JDiffClassDescription> unexpectedClasses = loadUnexpectedClasses();
+            for (JDiffClassDescription classDescription : unexpectedClasses) {
+                Class<?> unexpectedClass = findUnexpectedClass(classDescription);
+                if (unexpectedClass != null) {
+                    mResultObserver.notifyFailure(
+                            FailureType.UNEXPECTED_CLASS,
+                            classDescription.getAbsoluteClassName(),
+                            "Class should not be accessible to this APK");
+                }
+            }
+
             ApiComplianceChecker complianceChecker = new ApiComplianceChecker(mResultObserver);
             ApiDocumentParser apiDocumentParser = new ApiDocumentParser(
                     TAG, new ApiDocumentParser.Listener() {
                 @Override
                 public void completedClass(JDiffClassDescription classDescription) {
-                    complianceChecker.checkSignatureCompliance(classDescription);
+                    // Ignore classes that are known to be inaccessible.
+                    if (KNOWN_INACCESSIBLE_CLASSES.contains(classDescription.getAbsoluteClassName())) {
+                        return;
+                    }
+
+                    // Ignore unexpected classes that are in the API definition.
+                    if (!unexpectedClasses.contains(classDescription)) {
+                        complianceChecker.checkSignatureCompliance(classDescription);
+                    }
                 }
             });
 
@@ -96,7 +145,41 @@
                     e.getMessage());
         }
         if (mResultObserver.mDidFail) {
-            fail(mResultObserver.mErrorString.toString());
+            StringBuilder errorString = mResultObserver.mErrorString;
+            ClassLoader classLoader = getClass().getClassLoader();
+            errorString.append("\nClassLoader hierarchy\n");
+            while (classLoader != null) {
+                errorString.append("    ").append(classLoader).append("\n");
+                classLoader = classLoader.getParent();
+            }
+            fail(errorString.toString());
         }
     }
+
+    private Class<?> findUnexpectedClass(JDiffClassDescription classDescription) {
+        try {
+            return ReflectionHelper.findMatchingClass(classDescription);
+        } catch (ClassNotFoundException e) {
+            return null;
+        }
+    }
+
+    private Set<JDiffClassDescription> loadUnexpectedClasses()
+            throws IOException, XmlPullParserException {
+
+        Set<JDiffClassDescription> unexpectedClasses = new TreeSet<>(
+                Comparator.comparing(JDiffClassDescription::getAbsoluteClassName));
+        ApiDocumentParser apiDocumentParser = new ApiDocumentParser(TAG,
+                new ApiDocumentParser.Listener() {
+                    @Override
+                    public void completedClass(JDiffClassDescription classDescription) {
+                        unexpectedClasses.add(classDescription);
+                    }
+                });
+        for (String expectedApiFile : unexpectedApiFiles) {
+            File file = new File(API_FILE_DIRECTORY + "/" + expectedApiFile);
+            apiDocumentParser.parse(new FileInputStream(file));
+        }
+        return unexpectedClasses;
+    }
 }
diff --git a/tests/signature/api-check/system-current-api/Android.mk b/tests/signature/api-check/system-current-api/Android.mk
new file mode 100644
index 0000000..1c10d2c
--- /dev/null
+++ b/tests/signature/api-check/system-current-api/Android.mk
@@ -0,0 +1,26 @@
+# Copyright (C) 2017 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.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsSystemCurrentApiSignatureTestCases
+
+LOCAL_SIGNATURE_API_FILES := \
+    system-current.api \
+    android-test-mock-current.api \
+    android-test-runner-current.api \
+
+include $(LOCAL_PATH)/../build_signature_apk.mk
diff --git a/tests/signature/api-check/AndroidManifest.xml b/tests/signature/api-check/system-current-api/AndroidManifest.xml
similarity index 83%
copy from tests/signature/api-check/AndroidManifest.xml
copy to tests/signature/api-check/system-current-api/AndroidManifest.xml
index dbeccf5..d678c4b 100644
--- a/tests/signature/api-check/AndroidManifest.xml
+++ b/tests/signature/api-check/system-current-api/AndroidManifest.xml
@@ -16,16 +16,14 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.signature.cts.api">
+          package="android.signature.cts.api.system_current">
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
 
-    <application>
-        <uses-library android:name="android.test.runner"/>
-    </application>
+    <application/>
 
     <instrumentation android:name="repackaged.android.test.InstrumentationTestRunner"
-                     android:targetPackage="android.signature.cts.api"
-                     android:label="API Signature Test"/>
+                     android:targetPackage="android.signature.cts.api.system_current"
+                     android:label="System Current API Signature Test"/>
 
 </manifest>
diff --git a/tests/signature/api-check/AndroidTest.xml b/tests/signature/api-check/system-current-api/AndroidTest.xml
similarity index 63%
copy from tests/signature/api-check/AndroidTest.xml
copy to tests/signature/api-check/system-current-api/AndroidTest.xml
index a52d3df..ab7ea3c 100644
--- a/tests/signature/api-check/AndroidTest.xml
+++ b/tests/signature/api-check/system-current-api/AndroidTest.xml
@@ -20,16 +20,23 @@
         <option name="teardown-command" value="rm -rf /data/local/tmp/signature-test" />
     </target_preparer>
     <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
-        <option name="push" value="current.api->/data/local/tmp/signature-test/current.api" />
+        <option name="push" value="system-current.api->/data/local/tmp/signature-test/system-current.api" />
+    </target_preparer>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
+        <option name="push" value="android-test-mock-current.api->/data/local/tmp/signature-test/android-test-mock-current.api" />
+    </target_preparer>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
+        <option name="push" value="android-test-runner-current.api->/data/local/tmp/signature-test/android-test-runner-current.api" />
     </target_preparer>
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
-        <option name="test-file-name" value="CtsApiSignatureTestCases.apk" />
+        <option name="test-file-name" value="CtsSystemCurrentApiSignatureTestCases.apk" />
     </target_preparer>
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="android.signature.cts.api" />
+        <option name="package" value="android.signature.cts.api.system_current" />
         <option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
-        <option name="instrumentation-arg" key="expected-api-files" value="current.api" />
+        <option name="instrumentation-arg" key="expected-api-files" value="system-current.api" />
+        <option name="instrumentation-arg" key="unexpected-api-files" value="android-test-mock-current.api,android-test-runner-current.api" />
         <option name="runtime-hint" value="30s" />
     </test>
 </configuration>