am d866ed04: Merge "Remove optional video encoder: MPEG-4 SP" into jb-dev
* commit 'd866ed04ecb7b051b89abe7b479ab73a5c15f094':
Remove optional video encoder: MPEG-4 SP
diff --git a/CtsCoverage.mk b/CtsCoverage.mk
index 8e00913..61ad9c9 100644
--- a/CtsCoverage.mk
+++ b/CtsCoverage.mk
@@ -33,6 +33,7 @@
cts-test-coverage-report := $(coverage_out)/test-coverage.html
cts-verifier-coverage-report := $(coverage_out)/verifier-coverage.html
+cts-combined-coverage-report := $(coverage_out)/combined-coverage.html
cts_api_coverage_dependencies := $(cts_api_coverage_exe) $(dexdeps_exe) $(api_xml_description) $(ACP)
@@ -44,16 +45,24 @@
$(call generate-coverage-report,"CTS Verifier API Coverage Report",\
CtsVerifier,cts-verifier-apks,html,verifier-coverage.html)
+$(cts-combined-coverage-report) : CtsVerifier $(cts_api_coverage_dependencies) $(CTS_COVERAGE_TEST_CASE_LIST) $(cts_api_coverage_dependencies)
+ $(call generate-coverage-report,"CTS Combined API Coverage Report",\
+ $(CTS_COVERAGE_TEST_CASE_LIST) CtsVerifier,cts-combined-apks,html,combined-coverage.html)
+
.PHONY: cts-test-coverage
cts-test-coverage : $(cts-test-coverage-report)
.PHONY: cts-verifier-coverage
cts-verifier-coverage : $(cts-verifier-coverage-report)
+.PHONY: cts-combined-coverage
+cts-combined-coverage : $(cts-combined-coverage-report)
+
# Put the test coverage report in the dist dir if "cts" is among the build goals.
ifneq ($(filter cts, $(MAKECMDGOALS)),)
$(call dist-for-goals, cts, $(cts-test-coverage-report):cts-test-coverage-report.html)
$(call dist-for-goals, cts, $(cts-verifier-coverage-report):cts-verifier-coverage-report.html)
+ $(call dist-for-goals, cts, $(cts-combined-coverage-report):cts-combined-coverage-report.html)
endif
# Arguments;
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 6373173..0898369 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -18,7 +18,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.cts.verifier"
android:versionCode="1"
- android:versionName="4.1_r1">
+ android:versionName="4.1_r2">
<!-- Using 10 for more complete NFC support... -->
<uses-sdk android:minSdkVersion="10"></uses-sdk>
@@ -183,7 +183,6 @@
android:configChanges="keyboardHidden|orientation">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
- <category android:name="android.cts.intent.category.MANUAL_TEST" />
</intent-filter>
<meta-data android:name="test_category" android:value="@string/bt_device_communication" />
<meta-data android:name="test_parent" android:value="com.android.cts.verifier.bluetooth.BluetoothTestActivity" />
@@ -194,7 +193,6 @@
android:configChanges="keyboardHidden|orientation">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
- <category android:name="android.cts.intent.category.MANUAL_TEST" />
</intent-filter>
<meta-data android:name="test_category" android:value="@string/bt_device_communication" />
<meta-data android:name="test_parent" android:value="com.android.cts.verifier.bluetooth.BluetoothTestActivity" />
@@ -308,7 +306,6 @@
android:screenOrientation="landscape">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
- <category android:name="android.cts.intent.category.MANUAL_TEST" />
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_camera" />
diff --git a/suite/audio_quality/Android.mk b/suite/audio_quality/Android.mk
index c12e390..2078606 100644
--- a/suite/audio_quality/Android.mk
+++ b/suite/audio_quality/Android.mk
@@ -19,16 +19,26 @@
CTS_AUDIO_TOP:= $(call my-dir)
-CTS_AUDIO_INSTALL_DIR := $(HOST_OUT)/cts_audio_quality
+CTS_AUDIO_INSTALL_DIR := $(HOST_OUT)/cts-audio-quality/android-cts-audio-quality
+CTS_AUDIO_QUALITY_ZIP := $(HOST_OUT)/cts-audio-quality/android-cts-audio-quality.zip
-cts_audio: cts_audio_quality_test cts_audio_quality CtsAudioClient $(CTS_AUDIO_TOP)/test_description
+$(CTS_AUDIO_QUALITY_ZIP): cts_audio_quality_test cts_audio_quality \
+ CtsAudioClient $(CTS_AUDIO_TOP)/test_description
$(hide) mkdir -p $(CTS_AUDIO_INSTALL_DIR)
$(hide) mkdir -p $(CTS_AUDIO_INSTALL_DIR)/client
- $(hide) $(ACP) -fp $(ANDROID_PRODUCT_OUT)/data/app/CtsAudioClient.apk \
+ $(hide) $(ACP) -fp $(PRODUCT_OUT)/data/app/CtsAudioClient.apk \
$(CTS_AUDIO_INSTALL_DIR)/client
$(hide) $(ACP) -fp $(HOST_OUT)/bin/cts_audio_quality_test $(CTS_AUDIO_INSTALL_DIR)
$(hide) $(ACP) -fp $(HOST_OUT)/bin/cts_audio_quality $(CTS_AUDIO_INSTALL_DIR)
$(hide) $(ACP) -fr $(CTS_AUDIO_TOP)/test_description $(CTS_AUDIO_INSTALL_DIR)
+ $(hide) echo "Package cts_audio: $@"
+ $(hide) cd $(HOST_OUT)/cts-audio-quality && \
+ zip -rq android-cts-audio-quality.zip android-cts-audio-quality -x android-cts-audio-quality/reports/\*
+
+cts: $(CTS_AUDIO_QUALITY_ZIP)
+ifneq ($(filter cts, $(MAKECMDGOALS)),)
+$(call dist-for-goals, cts, $(CTS_AUDIO_QUALITY_ZIP))
+endif # cts
include $(call all-subdir-makefiles)
diff --git a/suite/audio_quality/executable/src/main.cpp b/suite/audio_quality/executable/src/main.cpp
index 98dfabe..cf33a0f 100644
--- a/suite/audio_quality/executable/src/main.cpp
+++ b/suite/audio_quality/executable/src/main.cpp
@@ -61,7 +61,7 @@
fprintf(stderr, "%s [-l log_level][-s serial] test_xml\n", argv[0]);
return 1;
}
- int logLevel = 3;
+ int logLevel = Log::ELogE;
char* serial = NULL;
int opt;
while ((opt = getopt(argc, argv, "l:s:")) != -1) {
diff --git a/suite/audio_quality/test_description/dut_speaker_calibration.xml b/suite/audio_quality/test_description/dut_speaker_calibration.xml
index f0ddf17..e0a613d 100644
--- a/suite/audio_quality/test_description/dut_speaker_calibration.xml
+++ b/suite/audio_quality/test_description/dut_speaker_calibration.xml
@@ -31,7 +31,7 @@
<sequential repeat="8" index="j">
<input device="host" id="host_in" gain="100" time="500" sync="complete" />
<!-- ------------moving average RMS min for pass, max for pass result calculated -->
- <process method="builtin:rms_mva" input="id:host_in,consti:3000,consti:8000" output="val:rms_$i_$j" />
+ <process method="builtin:rms_mva" input="id:host_in,consti:1000,consti:8000" output="val:rms_$i_$j" />
<!-- <message input="val:passfail" output_low="Volume Low" output_ok="Volume OK" output_high="Volume High" /> -->
</sequential>
</sequential>
diff --git a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityActivityTestCase.java b/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityActivityTestCase.java
index f1a7114..a5d92ee 100644
--- a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityActivityTestCase.java
+++ b/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityActivityTestCase.java
@@ -53,12 +53,27 @@
public boolean accept(AccessibilityEvent event);
}
+ private static final boolean DEBUG = false;
+
+ private static final String LOG_TAG = AccessibilityActivityTestCase.class.getSimpleName();
+
/**
* Timeout required for pending Binder calls or event processing to
* complete.
*/
public static final long TIMEOUT_ASYNC_PROCESSING = 5000;
+ /**
+ * The timeout after the last accessibility event to consider the device idle.
+ */
+ public static final long TIMEOUT_ACCESSIBILITY_STATE_IDLE = 100;
+
+ /**
+ * Instance for detecting the next accessibility event.
+ */
+ private static final NextAccessibilityEventWatcher sNextEventWatcher =
+ new NextAccessibilityEventWatcher();
+
private static AccessibilityInteractionBridge sInteractionBridge;
/**
@@ -71,6 +86,7 @@
@Override
public void setUp() throws Exception {
super.setUp();
+ waitForAccessibilityStateIdle();
startActivityAndWaitForFirstEvent();
}
@@ -124,6 +140,39 @@
}
/**
+ * Waits for idle accessibility state.
+ */
+ private void waitForAccessibilityStateIdle() throws Exception {
+ AccessibilityEvent awaitedEvent = null;
+ try {
+ do {
+ awaitedEvent = getInteractionBridge().executeCommandAndWaitForAccessibilityEvent(
+ sNextEventWatcher, sNextEventWatcher, TIMEOUT_ACCESSIBILITY_STATE_IDLE);
+ } while (awaitedEvent != null);
+ } catch (TimeoutException te) {
+ /* success - no event within the timeout - do nothing */
+ }
+ }
+
+ /**
+ * Dummy implementation that matches every event and does nothing.
+ */
+ private static class NextAccessibilityEventWatcher implements Runnable,
+ AccessibilityEventFilter {
+ @Override
+ public boolean accept(AccessibilityEvent event) {
+ if (DEBUG) {
+ Log.i(LOG_TAG, "Watcher event: " + event);
+ }
+ return true;
+ }
+ @Override
+ public void run() {
+ /* do nothing */
+ }
+ }
+
+ /**
* This class serves as a bridge for querying the screen content.
* The bride is connected of a delegating accessibility service.
*/
@@ -180,7 +229,6 @@
public void onAccessibilityEvent(AccessibilityEvent event) {
synchronized (mLock) {
- Log.e("OPALA", "Event: " + event);
mLock.notifyAll();
if (mWaitingForEventDelivery) {
mEventQueue.add(AccessibilityEvent.obtain(event));
diff --git a/tests/tests/os/src/android/os/cts/BuildVersionTest.java b/tests/tests/os/src/android/os/cts/BuildVersionTest.java
index 04d5ca9..8b33359 100644
--- a/tests/tests/os/src/android/os/cts/BuildVersionTest.java
+++ b/tests/tests/os/src/android/os/cts/BuildVersionTest.java
@@ -29,7 +29,7 @@
private static final String LOG_TAG = "BuildVersionTest";
private static final Set<String> EXPECTED_RELEASES =
- new HashSet<String>(Arrays.asList("4.1.1"));
+ new HashSet<String>(Arrays.asList("4.1.1", "4.1.2"));
private static final int EXPECTED_SDK = 16;
@SuppressWarnings("deprecation")
diff --git a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
index f5ae100..4712257 100644
--- a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
@@ -165,6 +165,71 @@
assertFalse(f.canRead());
assertFalse(f.canWrite());
assertFalse(f.canExecute());
+
+ assertFileOwnedBy(f, "nfc");
+ assertFileOwnedByGroup(f, "nfc");
+ }
+
+ @MediumTest
+ public void testBcm2079xSane() throws Exception {
+ File f = new File("/dev/bcm2079x");
+ assertFalse(f.canRead());
+ assertFalse(f.canWrite());
+ assertFalse(f.canExecute());
+
+ assertFileOwnedBy(f, "nfc");
+ assertFileOwnedByGroup(f, "nfc");
+ }
+
+ @MediumTest
+ public void testBcm2079xi2cSane() throws Exception {
+ File f = new File("/dev/bcm2079x-i2c");
+ assertFalse(f.canRead());
+ assertFalse(f.canWrite());
+ assertFalse(f.canExecute());
+
+ assertFileOwnedBy(f, "nfc");
+ assertFileOwnedByGroup(f, "nfc");
+ }
+
+ /**
+ * Assert that a file is owned by a specific owner. This is a noop if the
+ * file does not exist.
+ *
+ * @param file The file to check.
+ * @param expectedOwner The owner of the file.
+ */
+ private static void assertFileOwnedBy(File file, String expectedOwner) {
+ FileUtils.FileStatus status = new FileUtils.FileStatus();
+ String path = file.getAbsolutePath();
+ if (file.exists() && FileUtils.getFileStatus(path, status, true)) {
+ String actualOwner = FileUtils.getUserName(status.uid);
+ if (!expectedOwner.equals(actualOwner)) {
+ String msg = String.format("Wrong owner. Expected '%s', but found '%s' for %s.",
+ expectedOwner, actualOwner, path);
+ fail(msg);
+ }
+ }
+ }
+
+ /**
+ * Assert that a file is owned by a specific group. This is a noop if the
+ * file does not exist.
+ *
+ * @param file The file to check.
+ * @param expectedGroup The owner group of the file.
+ */
+ private static void assertFileOwnedByGroup(File file, String expectedGroup) {
+ FileUtils.FileStatus status = new FileUtils.FileStatus();
+ String path = file.getAbsolutePath();
+ if (file.exists() && FileUtils.getFileStatus(path, status, true)) {
+ String actualGroup = FileUtils.getGroupName(status.gid);
+ if (!expectedGroup.equals(actualGroup)) {
+ String msg = String.format("Wrong group. Expected '%s', but found '%s' for %s.",
+ expectedGroup, actualGroup, path);
+ fail(msg);
+ }
+ }
}
@MediumTest
@@ -218,6 +283,8 @@
"/app-cache/ciq/socket",
"/cache/fotapkg",
"/cache/fotapkg/tmp",
+ "/data/_SamsungBnR_",
+ "/data/_SamsungBnR_/BR",
"/data/2nd-init",
"/data/amit",
"/data/anr",
@@ -230,6 +297,7 @@
"/data/btips/TI",
"/data/btips/TI/opp",
"/data/calibration",
+ "/data/clipboard",
"/data/clp",
"/data/dalvik-cache",
"/data/data",
@@ -267,6 +335,7 @@
"/data/drm/rights",
"/data/dump",
"/data/emt",
+ "/data/factory",
"/data/fota",
"/data/gpscfg",
"/data/hwvefs",
@@ -298,6 +367,9 @@
"/data/misc/bluetooth",
"/data/misc/dhcp",
"/data/misc/lockscreen",
+ "/data/misc/webwidgets",
+ "/data/misc/webwidgets/chess",
+ "/data/misc/widgets",
"/data/misc/wifi",
"/data/misc/wifi/sockets",
"/data/misc/wimax",
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java
index 277f104..e02998e 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java
@@ -164,6 +164,7 @@
}
public void testOnUnhandledKeyEvent() throws Throwable {
+ requireLoadedPage();
final MockWebViewClient webViewClient = new MockWebViewClient();
mOnUiThread.setWebViewClient(webViewClient);
@@ -191,6 +192,10 @@
assertTrue(webViewClient.hasOnScaleChangedCalled());
}
+ private void requireLoadedPage() throws Throwable {
+ mOnUiThread.loadUrlAndWaitForCompletion("about:blank");
+ }
+
private class MockWebViewClient extends WaitForLoadedClient {
private boolean mOnPageStartedCalled;
private boolean mOnPageFinishedCalled;
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
index 0a8cc30..3f7ea78 100755
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
@@ -1167,6 +1167,20 @@
}
public void testRequestImageRef() throws Exception, Throwable {
+ final class ImageLoaded {
+ public boolean mImageLoaded;
+
+ public void loaded() {
+ mImageLoaded = true;
+ }
+ }
+ final ImageLoaded imageLoaded = new ImageLoaded();
+ runTestOnUiThread(new Runnable() {
+ public void run() {
+ mOnUiThread.getSettings().setJavaScriptEnabled(true);
+ }
+ });
+ mOnUiThread.addJavascriptInterface(imageLoaded, "imageLoaded");
AssetManager assets = getActivity().getAssets();
Bitmap bitmap = BitmapFactory.decodeStream(assets.open(TestHtmlConstants.LARGE_IMG_URL));
int imgWidth = bitmap.getWidth();
@@ -1175,9 +1189,24 @@
startWebServer(false);
final String imgUrl = mWebServer.getAssetUrl(TestHtmlConstants.LARGE_IMG_URL);
mOnUiThread.loadDataAndWaitForCompletion(
- "<html><title>Title</title><body><img src=\"" + imgUrl
+ "<html><head><title>Title</title><style type=\"text/css\">"
+ + "#imgElement { -webkit-transform: translate3d(0,0,1); }"
+ + "#imgElement.finish { -webkit-transform: translate3d(0,0,0);"
+ + " -webkit-transition-duration: 1ms; }</style>"
+ + "<script type=\"text/javascript\">function imgLoad() {"
+ + "imgElement = document.getElementById('imgElement');"
+ + "imgElement.addEventListener('webkitTransitionEnd',"
+ + "function(e) { imageLoaded.loaded(); });"
+ + "imgElement.className = 'finish';}</script>"
+ + "</head><body><img id=\"imgElement\" src=\"" + imgUrl
+ "\" width=\"" + imgWidth + "\" height=\"" + imgHeight
- + "\"/></body></html>", "text/html", null);
+ + "\" onLoad=\"imgLoad()\"/></body></html>", "text/html", null);
+ new PollingCheck() {
+ @Override
+ protected boolean check() {
+ return imageLoaded.mImageLoaded;
+ }
+ }.run();
getInstrumentation().waitForIdleSync();
final HrefCheckHandler handler = new HrefCheckHandler(mWebView.getHandler().getLooper());
diff --git a/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiClass.java b/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiClass.java
index 101be7f..2a62aa0 100644
--- a/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiClass.java
+++ b/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiClass.java
@@ -28,13 +28,16 @@
private final boolean mDeprecated;
+ private final boolean mAbstract;
+
private final List<ApiConstructor> mApiConstructors = new ArrayList<ApiConstructor>();
private final List<ApiMethod> mApiMethods = new ArrayList<ApiMethod>();
- ApiClass(String name, boolean deprecated) {
+ ApiClass(String name, boolean deprecated, boolean classAbstract) {
mName = name;
mDeprecated = deprecated;
+ mAbstract = classAbstract;
}
@Override
@@ -51,6 +54,10 @@
return mDeprecated;
}
+ public boolean isAbstract() {
+ return mAbstract;
+ }
+
public void addConstructor(ApiConstructor constructor) {
mApiConstructors.add(constructor);
}
@@ -108,6 +115,10 @@
@Override
public float getCoveragePercentage() {
- return (float) getNumCoveredMethods() / getTotalMethods() * 100;
+ if (getTotalMethods() == 0) {
+ return 100;
+ } else {
+ return (float) getNumCoveredMethods() / getTotalMethods() * 100;
+ }
}
-}
\ No newline at end of file
+}
diff --git a/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiCoverage.java b/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiCoverage.java
index dc40062..adf2ea9 100644
--- a/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiCoverage.java
+++ b/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiCoverage.java
@@ -16,6 +16,7 @@
package com.android.cts.apicoverage;
+import java.lang.String;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
@@ -37,4 +38,11 @@
public Collection<ApiPackage> getPackages() {
return Collections.unmodifiableCollection(mPackages.values());
}
+
+ public void removeEmptyAbstractClasses() {
+ for (Map.Entry<String, ApiPackage> entry : mPackages.entrySet()) {
+ ApiPackage pkg = entry.getValue();
+ pkg.removeEmptyAbstractClasses();
+ }
+ }
}
diff --git a/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiPackage.java b/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiPackage.java
index ddc6fb4..c83256c 100644
--- a/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiPackage.java
+++ b/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiPackage.java
@@ -19,7 +19,9 @@
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.Map;
+import java.util.Map.Entry;
/** Representation of a package in the API containing classes. */
class ApiPackage implements HasCoverage {
@@ -69,4 +71,16 @@
public float getCoveragePercentage() {
return (float) getNumCoveredMethods() / getTotalMethods() * 100;
}
-}
\ No newline at end of file
+
+ public void removeEmptyAbstractClasses() {
+ Iterator<Entry<String, ApiClass>> it = mApiClassMap.entrySet().iterator();
+ while (it.hasNext()) {
+ Map.Entry<String, ApiClass> entry = it.next();
+ ApiClass cls = entry.getValue();
+ if (cls.isAbstract() && (cls.getTotalMethods() == 0)) {
+ // this is essentially interface
+ it.remove();
+ }
+ }
+ }
+}
diff --git a/tools/cts-api-coverage/src/com/android/cts/apicoverage/CtsApiCoverage.java b/tools/cts-api-coverage/src/com/android/cts/apicoverage/CtsApiCoverage.java
index 2923ba2..d6abf9a 100644
--- a/tools/cts-api-coverage/src/com/android/cts/apicoverage/CtsApiCoverage.java
+++ b/tools/cts-api-coverage/src/com/android/cts/apicoverage/CtsApiCoverage.java
@@ -109,6 +109,7 @@
*/
ApiCoverage apiCoverage = getEmptyApiCoverage(apiXmlPath);
+ apiCoverage.removeEmptyAbstractClasses();
for (File testApk : testApks) {
addApiCoverage(apiCoverage, testApk, dexDeps);
}
diff --git a/tools/cts-api-coverage/src/com/android/cts/apicoverage/CurrentXmlHandler.java b/tools/cts-api-coverage/src/com/android/cts/apicoverage/CurrentXmlHandler.java
index f3abd86..b9f9e9c 100644
--- a/tools/cts-api-coverage/src/com/android/cts/apicoverage/CurrentXmlHandler.java
+++ b/tools/cts-api-coverage/src/com/android/cts/apicoverage/CurrentXmlHandler.java
@@ -32,12 +32,17 @@
private String mCurrentClassName;
+ private boolean mIgnoreCurrentClass;
+
private String mCurrentMethodName;
private String mCurrentMethodReturnType;
+ private boolean mCurrentMethodIsAbstract;
+
private boolean mDeprecated;
+
private List<String> mCurrentParameterTypes = new ArrayList<String>();
private ApiCoverage mApiCoverage = new ApiCoverage();
@@ -56,15 +61,20 @@
ApiPackage apiPackage = new ApiPackage(mCurrentPackageName);
mApiCoverage.addPackage(apiPackage);
- } else if ("class".equalsIgnoreCase(localName)
- || "interface".equalsIgnoreCase(localName)) {
+ } else if ("class".equalsIgnoreCase(localName)) {
+ if (isEnum(attributes)) {
+ mIgnoreCurrentClass = true;
+ return;
+ }
+ mIgnoreCurrentClass = false;
mCurrentClassName = getValue(attributes, "name");
mDeprecated = isDeprecated(attributes);
-
- ApiClass apiClass = new ApiClass(mCurrentClassName, mDeprecated);
+ ApiClass apiClass = new ApiClass(mCurrentClassName, mDeprecated, isAbstract(attributes));
ApiPackage apiPackage = mApiCoverage.getPackage(mCurrentPackageName);
apiPackage.addClass(apiClass);
-
+ } else if ("interface".equalsIgnoreCase(localName)) {
+ // don't add interface
+ mIgnoreCurrentClass = true;
} else if ("constructor".equalsIgnoreCase(localName)) {
mDeprecated = isDeprecated(attributes);
mCurrentParameterTypes.clear();
@@ -72,6 +82,7 @@
mDeprecated = isDeprecated(attributes);
mCurrentMethodName = getValue(attributes, "name");
mCurrentMethodReturnType = getValue(attributes, "return");
+ mCurrentMethodIsAbstract = isAbstract(attributes);
mCurrentParameterTypes.clear();
} else if ("parameter".equalsIgnoreCase(localName)) {
mCurrentParameterTypes.add(getValue(attributes, "type"));
@@ -81,6 +92,10 @@
@Override
public void endElement(String uri, String localName, String name) throws SAXException {
super.endElement(uri, localName, name);
+ if (mIgnoreCurrentClass) {
+ // do not add anything for interface
+ return;
+ }
if ("constructor".equalsIgnoreCase(localName)) {
if (mCurrentParameterTypes.isEmpty()) {
// Don't add empty default constructors...
@@ -92,6 +107,9 @@
ApiClass apiClass = apiPackage.getClass(mCurrentClassName);
apiClass.addConstructor(apiConstructor);
} else if ("method".equalsIgnoreCase(localName)) {
+ if (mCurrentMethodIsAbstract) { // do not add abstract method
+ return;
+ }
ApiMethod apiMethod = new ApiMethod(mCurrentMethodName, mCurrentParameterTypes,
mCurrentMethodReturnType, mDeprecated);
ApiPackage apiPackage = mApiCoverage.getPackage(mCurrentPackageName);
@@ -110,4 +128,12 @@
private boolean isDeprecated(Attributes attributes) {
return "deprecated".equals(attributes.getValue("deprecated"));
}
+
+ private boolean isAbstract(Attributes attributes) {
+ return "true".equals(attributes.getValue("abstract"));
+ }
+
+ private boolean isEnum(Attributes attributes) {
+ return "java.lang.Enum".equals(attributes.getValue("extends"));
+ }
}
\ No newline at end of file
diff --git a/tools/cts-api-coverage/src/com/android/cts/apicoverage/XmlReport.java b/tools/cts-api-coverage/src/com/android/cts/apicoverage/XmlReport.java
index 94ccbb4..e76343e 100644
--- a/tools/cts-api-coverage/src/com/android/cts/apicoverage/XmlReport.java
+++ b/tools/cts-api-coverage/src/com/android/cts/apicoverage/XmlReport.java
@@ -54,12 +54,18 @@
CoverageComparator comparator = new CoverageComparator();
List<ApiPackage> packages = new ArrayList<ApiPackage>(apiCoverage.getPackages());
Collections.sort(packages, comparator);
+ int totalMethods = 0;
+ int totalCoveredMethods = 0;
for (ApiPackage pkg : packages) {
if (pkg.getName().startsWith("android")
&& pkg.getTotalMethods() > 0) {
+ int pkgTotal = pkg.getTotalMethods();
+ totalMethods += pkgTotal;
+ int pkgTotalCovered = pkg.getNumCoveredMethods();
+ totalCoveredMethods += pkgTotalCovered;
out.println("<package name=\"" + pkg.getName()
- + "\" numCovered=\"" + pkg.getNumCoveredMethods()
- + "\" numTotal=\"" + pkg.getTotalMethods()
+ + "\" numCovered=\"" + pkgTotalCovered
+ + "\" numTotal=\"" + pkgTotal
+ "\" coveragePercentage=\""
+ Math.round(pkg.getCoveragePercentage())
+ "\">");
@@ -81,7 +87,12 @@
out.println("<constructor name=\"" + constructor.getName()
+ "\" deprecated=\"" + constructor.isDeprecated()
+ "\" covered=\"" + constructor.isCovered() + "\">");
-
+ if (constructor.isDeprecated()) {
+ if (constructor.isCovered()) {
+ totalCoveredMethods -= 1;
+ }
+ totalMethods -= 1;
+ }
for (String parameterType : constructor.getParameterTypes()) {
out.println("<parameter type=\"" + parameterType + "\" />");
}
@@ -94,7 +105,12 @@
+ "\" returnType=\"" + method.getReturnType()
+ "\" deprecated=\"" + method.isDeprecated()
+ "\" covered=\"" + method.isCovered() + "\">");
-
+ if (method.isDeprecated()) {
+ if (method.isCovered()) {
+ totalCoveredMethods -= 1;
+ }
+ totalMethods -= 1;
+ }
for (String parameterType : method.getParameterTypes()) {
out.println("<parameter type=\"" + parameterType + "\" />");
}
@@ -109,6 +125,10 @@
}
out.println("</api>");
+ out.println("<total numCovered=\"" + totalCoveredMethods + "\" "
+ + "numTotal=\"" + totalMethods + "\" "
+ + "coveragePercentage=\""
+ + Math.round((float)totalCoveredMethods / totalMethods * 100.0f) + "\" />");
out.println("</api-coverage>");
}
}
diff --git a/tools/cts-api-coverage/src/res/api-coverage.xsl b/tools/cts-api-coverage/src/res/api-coverage.xsl
index 95994e2..9cd4aeb 100644
--- a/tools/cts-api-coverage/src/res/api-coverage.xsl
+++ b/tools/cts-api-coverage/src/res/api-coverage.xsl
@@ -82,6 +82,10 @@
<div class="info">
Generated: <xsl:value-of select="api-coverage/@generatedTime" />
</div>
+ <div class="total">
+ Total: <xsl:value-of select="api-coverage/total/@coveragePercentage" />%
+ (<xsl:value-of select="api-coverage/total/@numCovered" />/<xsl:value-of select="api-coverage/total/@numTotal" />)
+ </div>
<div class="apks" onclick="toggleVisibility('sourceApks')">
Source APKs (<xsl:value-of select="count(api-coverage/debug/sources/apk)" />)
</div>
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java
index 78f7412..a79b84e 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java
@@ -51,6 +51,7 @@
import java.lang.System;
import java.lang.Thread;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
@@ -148,6 +149,9 @@
"Interval between each reboot in min. Meaningful only with reboot-per-package option")
private int mRebootIntervalMin = 30;
+
+ private long mPrevRebootTime; // last reboot time
+
/** data structure for a {@link IRemoteTest} and its known tests */
class TestPackage {
private final IRemoteTest mTestForPackage;
@@ -350,8 +354,8 @@
Log.i(LOG_TAG, "Initial reboot for multiple packages");
rebootDevice();
}
- long prevTime = System.currentTimeMillis();
- long intervalInMSec = mRebootIntervalMin * 60 * 1000;
+ mPrevRebootTime = System.currentTimeMillis();
+
while (!mRemainingTestPkgs.isEmpty()) {
TestPackage knownTests = mRemainingTestPkgs.get(0);
@@ -367,15 +371,7 @@
test.run(filter);
mRemainingTestPkgs.remove(0);
if (mRemainingTestPkgs.size() > 0) {
- if (mRebootPerPackage) {
- long currentTime = System.currentTimeMillis();
- if ((currentTime - prevTime) > intervalInMSec) {
- Log.i(LOG_TAG, String.format("Rebooting after running package %s",
- knownTests.getPackageDef().getName()));
- rebootDevice();
- prevTime = System.currentTimeMillis();
- }
- }
+ rebootIfNecessary(knownTests, mRemainingTestPkgs.get(0));
// remove artifacts like status bar from the previous test.
// But this cannot dismiss dialog popped-up.
changeToHomeScreen();
@@ -398,6 +394,33 @@
}
}
+ private void rebootIfNecessary(TestPackage testFinished, TestPackage testToRun)
+ throws DeviceNotAvailableException {
+ // If there comes spurious failure like INJECT_EVENTS for a package,
+ // reboot it before running it.
+ // Also reboot after package which is know to leave pop-up behind
+ final List<String> rebootAfterList = Arrays.asList("CtsWebkitSecurityTestCases");
+ final List<String> rebootBeforeList = Arrays.asList("CtsAnimationTestCases",
+ "CtsGraphicsTestCases",
+ "CtsViewTestCases",
+ "CtsWebkitSecurityTestCases",
+ "CtsWidgetTestCases" );
+ long intervalInMSec = mRebootIntervalMin * 60 * 1000;
+ if (mRebootPerPackage) {
+ long currentTime = System.currentTimeMillis();
+ if (((currentTime - mPrevRebootTime) > intervalInMSec) ||
+ rebootAfterList.contains(testFinished.getPackageDef().getName()) ||
+ rebootBeforeList.contains(testToRun.getPackageDef().getName()) ) {
+ Log.i(LOG_TAG,
+ String.format("Rebooting after running package %s, before package %s",
+ testFinished.getPackageDef().getName(),
+ testToRun.getPackageDef().getName()));
+ rebootDevice();
+ mPrevRebootTime = System.currentTimeMillis();
+ }
+ }
+ }
+
private void rebootDevice() throws DeviceNotAvailableException {
final int TIMEOUT_MS = 4 * 60 * 1000;
TestDeviceOptions options = mDevice.getOptions();