Merge "Fix MixedProfileOwnerTest#testApplicationRestrictions" into nyc-dev
diff --git a/apps/CameraITS/pymodules/its/device.py b/apps/CameraITS/pymodules/its/device.py
index 741baee..c669540 100644
--- a/apps/CameraITS/pymodules/its/device.py
+++ b/apps/CameraITS/pymodules/its/device.py
@@ -597,7 +597,12 @@
for c in cmd["outputSurfaces"]]
formats = [s if s != "jpg" else "jpeg" for s in formats]
else:
+ max_yuv_size = its.objects.get_available_output_sizes(
+ "yuv", self.props)[0]
formats = ['yuv']
+ cmd["outputSurfaces"] = [{"format": "yuv",
+ "width" : max_yuv_size[0],
+ "height": max_yuv_size[1]}]
ncap = len(cmd["captureRequests"])
nsurf = 1 if out_surfaces is None else len(cmd["outputSurfaces"])
# Only allow yuv output to multiple targets
diff --git a/apps/CameraITS/tests/scene1/test_post_raw_sensitivity_boost.py b/apps/CameraITS/tests/scene1/test_post_raw_sensitivity_boost.py
index b0689c1..682c04a 100644
--- a/apps/CameraITS/tests/scene1/test_post_raw_sensitivity_boost.py
+++ b/apps/CameraITS/tests/scene1/test_post_raw_sensitivity_boost.py
@@ -14,8 +14,9 @@
import its.device
import its.caps
-import its.objects
import its.image
+import its.objects
+import its.target
import os.path
import pylab
import matplotlib
@@ -47,23 +48,24 @@
raw_format = 'raw10'
elif its.caps.raw12(props):
raw_format = 'raw12'
- else # should not reach here
+ else: # should not reach here
raise its.error.Error('Cannot find available RAW output format')
out_surfaces = [{"format": raw_format},
{"format": "yuv", "width": w, "height": h}]
sens_min, sens_max = props['android.sensor.info.sensitivityRange']
- sens_boost_min, sens_boost_max =
+ sens_boost_min, sens_boost_max = \
props['android.control.postRawSensitivityBoostRange']
- e_targer, s_target =
+
+ e_target, s_target = \
its.target.get_target_exposure_combos(cam)["midSensitivity"]
reqs = []
settings = []
s_boost = sens_boost_min
- while s_boost <= sens_boost_min:
+ while s_boost <= sens_boost_max:
s_raw = int(round(s_target * 100.0 / s_boost))
if s_raw < sens_min or s_raw > sens_max:
continue
@@ -77,9 +79,15 @@
raw_rgb_means = []
yuv_rgb_means = []
- for i,cap in enumerate(caps):
+ raw_caps, yuv_caps = caps
+ if not isinstance(raw_caps, list):
+ raw_caps = [raw_caps]
+ if not isinstance(yuv_caps, list):
+ yuv_caps = [yuv_caps]
+ for i in xrange(len(reqs)):
(s, s_boost) = settings[i]
- raw_cap, yuv_cap = cap
+ raw_cap = raw_caps[i]
+ yuv_cap = yuv_caps[i]
raw_rgb = its.image.convert_capture_to_rgb_image(raw_cap, props=props)
yuv_rgb = its.image.convert_capture_to_rgb_image(yuv_cap)
raw_tile = its.image.get_image_patch(raw_rgb, 0.45,0.45,0.1,0.1)
@@ -90,7 +98,7 @@
"%s_raw_s=%04d_boost=%04d.jpg" % (NAME,s,s_boost))
its.image.write_image(yuv_tile,
"%s_yuv_s=%04d_boost=%04d.jpg" % (NAME,s,s_boost))
- print "s=%d, s_boost=%d: raw_means %s, yuv_means %d"%(
+ print "s=%d, s_boost=%d: raw_means %s, yuv_means %s"%(
s,s_boost,raw_rgb_means[-1], yuv_rgb_means[-1])
xs = range(len(reqs))
@@ -125,7 +133,7 @@
yuv_thres_max = 1 + RATIO_THRESHOLD
for rgb in range(3):
vals = [val[rgb] for val in yuv_rgb_means]
- mean = sum(vals) / len(vales)
+ mean = sum(vals) / len(vals)
print "%s channel vals %s mean %f"%(rgb_str[rgb], vals, mean)
for step in range(len(reqs)):
ratio = vals[step] / mean
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index d7dc418..ee98618 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -1520,6 +1520,10 @@
</intent-filter>
</activity-alias>
+ <activity android:name=".managedprovisioning.OrganizationInfoTestActivity"
+ android:label="@string/provisioning_byod_organization_info">
+ </activity>
+
<activity android:name=".managedprovisioning.PolicyTransparencyTestListActivity"
android:label="@string/device_profile_owner_policy_transparency_test">
<intent-filter>
@@ -1624,6 +1628,7 @@
<action android:name="com.android.cts.verifier.managedprovisioning.CLEAR_NOTIFICATION" />
<action android:name="com.android.cts.verifier.managedprovisioning.TEST_SELECT_WORK_CHALLENGE" />
<action android:name="com.android.cts.verifier.managedprovisioning.TEST_CONFIRM_WORK_CREDENTIALS" />
+ <action android:name="com.android.cts.verifier.managedprovisioning.TEST_ORGANIZATION_INFO" />
<category android:name="android.intent.category.DEFAULT"></category>
</intent-filter>
</activity>
diff --git a/apps/CtsVerifier/jni/audio_loopback/sles.cpp b/apps/CtsVerifier/jni/audio_loopback/sles.cpp
index 7859d35..b0b683b 100644
--- a/apps/CtsVerifier/jni/audio_loopback/sles.cpp
+++ b/apps/CtsVerifier/jni/audio_loopback/sles.cpp
@@ -40,14 +40,14 @@
if (ppSles != NULL) {
sles_data * pSles = (sles_data*) calloc(1, sizeof (sles_data));
- SLES_PRINTF("malloc %d bytes at %p",sizeof(sles_data), pSles);
+ SLES_PRINTF("malloc %zu bytes at %p", sizeof(sles_data), pSles);
*ppSles = pSles;
if (pSles != NULL)
{
SLES_PRINTF("creating server. Sampling rate =%d, frame count = %d",samplingRate,
frameCount);
status = slesCreateServer(pSles, samplingRate, frameCount, micSource);
- SLES_PRINTF("slesCreateServer =%d",status);
+ SLES_PRINTF("slesCreateServer =%d", status);
}
}
return status;
@@ -260,6 +260,7 @@
// char **freeBuffers;
// Buffer indices
+/*
pSles->rxFront; // oldest recording
pSles->rxRear; // next to be recorded
pSles->txFront; // oldest playing
@@ -268,9 +269,8 @@
pSles->freeRear; // next to be freed
pSles->fifo; //(*)
+*/
pSles->fifo2Buffer = NULL;
- pSles->recorderBufferQueue;
- pSles->playerBufferQueue;
// compute total free buffers as -r plus -t
pSles->freeBufCount = pSles->rxBufCount + pSles->txBufCount;
@@ -325,7 +325,6 @@
SLresult result;
// create engine
- pSles->engineObject;
result = slCreateEngine(&(pSles->engineObject), 0, NULL, 0, NULL, NULL);
ASSERT_EQ(SL_RESULT_SUCCESS, result);
result = (*(pSles->engineObject))->Realize(pSles->engineObject, SL_BOOLEAN_FALSE);
@@ -336,7 +335,6 @@
ASSERT_EQ(SL_RESULT_SUCCESS, result);
// create output mix
- pSles->outputmixObject;
result = (*engineEngine)->CreateOutputMix(engineEngine, &(pSles->outputmixObject), 0, NULL,
NULL);
ASSERT_EQ(SL_RESULT_SUCCESS, result);
diff --git a/apps/CtsVerifier/res/layout/organization_info.xml b/apps/CtsVerifier/res/layout/organization_info.xml
new file mode 100644
index 0000000..320fb8c
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/organization_info.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/root_view"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <TextView android:id="@+id/provisioning_byod_organization_info_instructions"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:text="@string/provisioning_byod_organization_info_instructions"/>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+ <EditText android:id="@+id/organization_name_edit_text"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:hint="@string/provisioning_byod_organization_name_hint"
+ android:gravity="top|start"
+ android:windowSoftInputMode="adjustPan"
+ android:padding="16dp"
+ android:layout_weight="1"/>
+ <EditText android:id="@+id/organization_color_edit_text"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:hint="@string/provisioning_byod_organization_color_hint"
+ android:gravity="top|start"
+ android:digits="#0123456789abcdefABCDEF"
+ android:inputType="textCapCharacters"
+ android:windowSoftInputMode="adjustPan"
+ android:padding="16dp"
+ android:layout_weight="1" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+ <Button android:id="@+id/organization_info_set_button"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:text="@string/provisioning_byod_set_organization_info_button_text"
+ android:layout_weight="1"/>
+ <Button android:id="@+id/go_button"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:text="@string/go_button_text"
+ android:layout_weight="1"/>
+ </LinearLayout>
+
+ <include layout="@layout/pass_fail_buttons" />
+
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index cbd7f6b..0dbb16f 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -1291,14 +1291,14 @@
<string name="keychain_reset">Reset</string>
<string name="keychain_skip">Skip</string>
<string name="keychain_setup_desc">The first step sets up an internal KeyStore and generates credentials to use for the remainder of the test.\n\n
- Touch \'Next\' to begin.</string>
- <string name="keychain_install_desc">Credentials generated. Touch \'Next\' to install them to the system keychain.\n\n
+ Tap \'Next\' to begin.</string>
+ <string name="keychain_install_desc">Credentials generated. Tap \'Next\' to install them to the system keychain.\n\n
The container for the credentials will not be protected with a password; if prompted for one, leave that field blank.\n\n
During installation you may be prompted for a name - accept the default suggestion.\n\n
In the case that these credentials were already installed, you may skip this step.</string>
<string name="keychain_https_desc">The last test involves setting up an HTTPS connection using credentials from the KeyChain.\n\n
You should be prompted to select credentials; choose the ones you just installed in the previous step.</string>
- <string name="keychain_reset_desc">Before marking this test as passed, touch \'Next\' to open security settings and reset the following items:\n
+ <string name="keychain_reset_desc">Before marking this test as passed, tap \'Next\' to open security settings and reset the following items:\n
1. Clear device credentials.\n
2. Change the lock screen type to \'None\'.</string>
@@ -1921,6 +1921,20 @@
3. Check that the work notification has disappeared.\n
4. Set work mode to on.\n
</string>
+ <string name="provisioning_byod_organization_info">Organization Info</string>
+ <string name="provisioning_byod_organization_name_hint">Name</string>
+ <string name="provisioning_byod_organization_color_hint">#FF00FF</string>
+ <string name="provisioning_byod_set_organization_info_button_text">Set</string>
+ <string name="provisioning_byod_organization_info_instructions">
+ This test verifies that the Organization Info was set correctly.
+ You can only do this test after you have done "select work challenge" test.\n
+ 1. Enter your organization name.\n
+ 2. Enter a valid color code.\n
+ 3. Press the Set button to set organization Info.\n
+ 4. Press the Go button to open a dialog to confirm work credentials.\n
+ 5. Verify that the background color of the resulting dialog is as set by you.\n
+ 6. Verify that the header text has organization name as set by you.\n
+ </string>
<!-- Strings for DeviceOwnerProvisioningTest -->
<string name="provisioning_device_owner">Device Owner Provisioning</string>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
index e00d287..9b5df85 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
@@ -94,6 +94,7 @@
private DialogTestListItem mConfirmWorkCredentials;
private TestListItem mVpnTest;
private TestListItem mDisallowAppsControlTest;
+ private TestListItem mOrganizationInfoTest;
private TestListItem mPolicyTransparencyTest;
public ByodFlowTestActivity() {
@@ -374,6 +375,12 @@
R.string.provisioning_byod_confirm_work_credentials_description,
new Intent(ByodHelperActivity.ACTION_TEST_CONFIRM_WORK_CREDENTIALS));
+ mOrganizationInfoTest = TestListItem.newTest(this,
+ R.string.provisioning_byod_organization_info,
+ OrganizationInfoTestActivity.class.getName(),
+ new Intent(this, OrganizationInfoTestActivity.class),
+ null);
+
final Intent policyTransparencyTestIntent = new Intent(this,
PolicyTransparencyTestListActivity.class);
policyTransparencyTestIntent.putExtra(
@@ -418,6 +425,7 @@
adapter.add(mTurnOffWorkNotifications);
adapter.add(mSelectWorkChallenge);
adapter.add(mConfirmWorkCredentials);
+ adapter.add(mOrganizationInfoTest);
adapter.add(mPolicyTransparencyTest);
if (canResolveIntent(new Intent(Settings.ACTION_APPLICATION_SETTINGS))) {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodHelperActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodHelperActivity.java
index cfb42fd..b9e6541 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodHelperActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodHelperActivity.java
@@ -135,6 +135,9 @@
public static final String ACTION_TEST_CONFIRM_WORK_CREDENTIALS =
"com.android.cts.verifier.managedprovisioning.TEST_CONFIRM_WORK_CREDENTIALS";
+ public static final String ACTION_SET_ORGANIZATION_INFO =
+ "com.android.cts.verifier.managedprovisioning.TEST_ORGANIZATION_INFO";
+
public static final int RESULT_FAILED = RESULT_FIRST_USER;
private static final int REQUEST_INSTALL_PACKAGE = 2;
@@ -324,6 +327,16 @@
(KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
Intent launchIntent = keyguardManager.createConfirmDeviceCredentialIntent(null, null);
startActivity(launchIntent);
+ } else if (ACTION_SET_ORGANIZATION_INFO.equals(action)) {
+ if(intent.hasExtra(OrganizationInfoTestActivity.EXTRA_ORGANIZATION_NAME)) {
+ final String organizationName = intent
+ .getStringExtra(OrganizationInfoTestActivity.EXTRA_ORGANIZATION_NAME);
+ mDevicePolicyManager.setOrganizationName(mAdminReceiverComponent, organizationName);
+ }
+ final int organizationColor = intent.getIntExtra(
+ OrganizationInfoTestActivity.EXTRA_ORGANIZATION_COLOR,
+ mDevicePolicyManager.getOrganizationColor(mAdminReceiverComponent));
+ mDevicePolicyManager.setOrganizationColor(mAdminReceiverComponent, organizationColor);
}
// This activity has no UI and is only used to respond to CtsVerifier in the primary side.
finish();
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java
index d7d9b71..e4250f0 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java
@@ -102,6 +102,7 @@
filter.addAction(VpnTestActivity.ACTION_VPN);
filter.addAction(ByodHelperActivity.ACTION_TEST_SELECT_WORK_CHALLENGE);
filter.addAction(ByodHelperActivity.ACTION_TEST_CONFIRM_WORK_CREDENTIALS);
+ filter.addAction(ByodHelperActivity.ACTION_SET_ORGANIZATION_INFO);
filter.addAction(SetSupportMessageActivity.ACTION_SET_SUPPORT_MSG);
filter.addAction(CommandReceiverActivity.ACTION_EXECUTE_COMMAND);
dpm.addCrossProfileIntentFilter(getWho(context), filter,
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/OrganizationInfoTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/OrganizationInfoTestActivity.java
new file mode 100644
index 0000000..3fb7120
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/OrganizationInfoTestActivity.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2016 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.cts.verifier.managedprovisioning;
+
+import android.content.Intent;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.Toast;
+
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+
+/**
+ * Test class to verify Organization Info.
+ */
+public class OrganizationInfoTestActivity extends PassFailButtons.Activity
+ implements View.OnClickListener {
+
+ public static final String EXTRA_ORGANIZATION_NAME = "extra_organization_name";
+ public static final String EXTRA_ORGANIZATION_COLOR = "extra_organization_color";
+
+ private int mOrganizationColor;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.organization_info);
+ setPassFailButtonClickListeners();
+ setButtonClickListeners();
+ }
+
+ private void setButtonClickListeners() {
+ findViewById(R.id.organization_info_set_button).setOnClickListener(this);
+ findViewById(R.id.go_button).setOnClickListener(this);
+ }
+
+ @Override
+ public void onClick(View view) {
+ if (view.getId() == R.id.organization_info_set_button) {
+ EditText organizationNameEditText = (EditText) findViewById(
+ R.id.organization_name_edit_text);
+ Intent intent = new Intent(ByodHelperActivity.ACTION_SET_ORGANIZATION_INFO);
+ intent.putExtra(EXTRA_ORGANIZATION_NAME, organizationNameEditText.getText().toString());
+ if (isOrganizationColorSet()) {
+ intent.putExtra(EXTRA_ORGANIZATION_COLOR, mOrganizationColor);
+ }
+ startActivity(intent);
+ } else if (view.getId() == R.id.go_button) {
+ Intent intent = new Intent(ByodHelperActivity.ACTION_TEST_CONFIRM_WORK_CREDENTIALS);
+ startActivity(intent);
+ }
+ }
+
+ private boolean isOrganizationColorSet() {
+ EditText organizationColorEditText = (EditText) findViewById(
+ R.id.organization_color_edit_text);
+ try {
+ mOrganizationColor = Color.parseColor(organizationColorEditText.getText().toString());
+ } catch (Exception e) {
+ Toast.makeText(this, "Not a valid Color value", Toast.LENGTH_SHORT).show();
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/ApkInstrumentationPreparer.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/ApkInstrumentationPreparer.java
index 916e8ec..33ee5d8 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/ApkInstrumentationPreparer.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/ApkInstrumentationPreparer.java
@@ -26,7 +26,6 @@
import com.android.tradefed.config.OptionClass;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
import com.android.tradefed.result.ITestInvocationListener;
import com.android.tradefed.targetprep.BuildError;
import com.android.tradefed.targetprep.ITargetCleaner;
@@ -83,7 +82,9 @@
return;
}
try {
- if (!instrument(device, buildInfo)) {
+ if (instrument(device, buildInfo)) {
+ logInfo("Target preparation successful");
+ } else {
throw new TargetSetupError("Not all target preparation steps completed");
}
} catch (FileNotFoundException e) {
@@ -106,8 +107,8 @@
try {
instrument(device, buildInfo);
} catch (FileNotFoundException e1) {
- CLog.e("Couldn't find apk to instrument");
- CLog.e(e1);
+ logError("Couldn't find apk to instrument");
+ logError(e1);
}
}
@@ -122,6 +123,12 @@
throw new FileNotFoundException(String.format("%s not found", mApkFileName));
}
+ if (device.getAppPackageInfo(mPackageName) != null) {
+ logInfo("Package %s already present on the device, uninstalling ...", mPackageName);
+ device.uninstallPackage(mPackageName);
+ }
+
+ logInfo("Instrumenting package %s:", mPackageName);
AndroidJUnitTest instrTest = new AndroidJUnitTest();
instrTest.setDevice(device);
instrTest.setInstallFile(apkFile);
@@ -134,7 +141,7 @@
for (TestIdentifier test : testFailures.keySet()) {
success = false;
String trace = testFailures.get(test);
- CLog.e("Target preparation step %s failed.\n%s", test.getTestName(), trace);
+ logError("Target preparation step %s failed.\n%s", test.getTestName(), trace);
}
}
return success;
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/LocationCheck.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/LocationCheck.java
index cea3136..94bc64f 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/LocationCheck.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/LocationCheck.java
@@ -51,6 +51,7 @@
return; // skip this precondition if required location feature is not present
}
+ logInfo("Verifying location setting");
mSettingName = LOCATION_SETTING;
mSettingType = SettingsPreparer.SettingType.SECURE;
mExpectedSettingValues.add(NETWORK);
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/PreconditionPreparer.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/PreconditionPreparer.java
index 3b86b65..fc25e03 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/PreconditionPreparer.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/PreconditionPreparer.java
@@ -17,16 +17,18 @@
package com.android.compatibility.common.tradefed.targetprep;
import com.android.compatibility.common.tradefed.testtype.CompatibilityTest;
+import com.android.ddmlib.Log;
import com.android.tradefed.build.IBuildInfo;
import com.android.tradefed.config.Option;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.LogUtil;
import com.android.tradefed.targetprep.BuildError;
import com.android.tradefed.targetprep.ITargetPreparer;
import com.android.tradefed.targetprep.TargetSetupError;
/**
- * An {@link ITargetPreparer} that performs checks and/or tasks to ensure the
+ * An {@link ITargetPreparer} that performs checks and/or tasks to ensure the
* the device is ready to run the test suite.
*/
public abstract class PreconditionPreparer implements ITargetPreparer {
@@ -36,6 +38,8 @@
description = "Whether preconditions should be skipped")
private boolean mSkipPreconditions = false;
+ protected final String LOG_TAG = getClass().getSimpleName();
+
@Override
public void setUp(ITestDevice device, IBuildInfo buildInfo) throws TargetSetupError,
BuildError, DeviceNotAvailableException {
@@ -46,4 +50,35 @@
public abstract void run(ITestDevice device, IBuildInfo buildInfo)
throws TargetSetupError, BuildError, DeviceNotAvailableException;
+
+ protected void logInfo(String info) {
+ LogUtil.printLog(Log.LogLevel.INFO, LOG_TAG, info);
+ }
+
+ protected void logInfo(String infoFormat, Object... args) {
+ LogUtil.printLog(Log.LogLevel.INFO, LOG_TAG, String.format(infoFormat, args));
+ }
+
+ protected void logWarning(String warning) {
+ LogUtil.printLog(Log.LogLevel.WARN, LOG_TAG, warning);
+ }
+
+ protected void logWarning(String warningFormat, Object... args) {
+ LogUtil.printLog(Log.LogLevel.WARN, LOG_TAG, String.format(warningFormat, args));
+ }
+
+ protected void logError(String error) {
+ LogUtil.printLog(Log.LogLevel.ERROR, LOG_TAG, error);
+ }
+
+ protected void logError(String errorFormat, Object... args) {
+ LogUtil.printLog(Log.LogLevel.ERROR, LOG_TAG, String.format(errorFormat, args));
+ }
+
+ protected void logError(Throwable t) {
+ if (t != null) {
+ Log.e(LOG_TAG, t);
+ }
+ }
+
}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/PropertyCheck.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/PropertyCheck.java
index 4d00ea5..79f19d0 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/PropertyCheck.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/PropertyCheck.java
@@ -15,13 +15,11 @@
*/
package com.android.compatibility.common.tradefed.targetprep;
-import com.android.ddmlib.Log;
import com.android.tradefed.build.IBuildInfo;
import com.android.tradefed.config.Option;
import com.android.tradefed.config.OptionClass;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil;
import com.android.tradefed.targetprep.BuildError;
import com.android.tradefed.targetprep.TargetSetupError;
@@ -48,11 +46,11 @@
@Override
public void run(ITestDevice device, IBuildInfo buildInfo) throws TargetSetupError,
BuildError, DeviceNotAvailableException {
+
String propertyValue = device.getProperty(mPropertyName);
if (propertyValue == null) {
- LogUtil.printLog(Log.LogLevel.WARN, LOG_TAG, String.format(
- "Property \"%s\" not found on device, cannot verify value \"%s\" ",
- mPropertyName, mExpectedPropertyValue));
+ logWarning("Property \"%s\" not found on device, cannot verify value \"%s\" ",
+ mPropertyName, mExpectedPropertyValue);
return;
}
@@ -63,7 +61,7 @@
if(mThrowError) {
throw new TargetSetupError(msg);
} else {
- LogUtil.printLog(Log.LogLevel.WARN, LOG_TAG, msg);
+ logWarning(msg);
}
}
}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/SettingsPreparer.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/SettingsPreparer.java
index f21ef39..d4c9d54 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/SettingsPreparer.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/SettingsPreparer.java
@@ -95,6 +95,8 @@
String currentSettingValue = device.executeShellCommand(shellCmdGet).trim();
// only change unexpected setting value
if (!mExpectedSettingValues.contains(currentSettingValue)) {
+ logInfo("Changing value for %s from %s to %s",
+ mSettingName, currentSettingValue, mSetValue);
device.executeShellCommand(shellCmdPut);
}
return;
@@ -102,6 +104,7 @@
/* Case 2: Only set-value given */
if (mSetValue != null) {
+ logInfo("Setting %s to value %s", mSettingName, mSetValue);
device.executeShellCommand(shellCmdPut);
return;
}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/WifiCheck.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/WifiCheck.java
index 0100969..5863bd8 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/WifiCheck.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/WifiCheck.java
@@ -15,13 +15,11 @@
*/
package com.android.compatibility.common.tradefed.targetprep;
-import com.android.ddmlib.Log.LogLevel;
import com.android.tradefed.build.IBuildInfo;
import com.android.tradefed.config.Option;
import com.android.tradefed.config.OptionClass;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
import com.android.tradefed.targetprep.BuildError;
import com.android.tradefed.targetprep.TargetSetupError;
@@ -65,16 +63,15 @@
if (mWifiSsid == null) { // no connection to create, check for existing connectivity
if (!device.checkConnectivity()) {
throw new TargetSetupError("Device has no network connection, no ssid provided");
- }
+ }
} else { // network provided in options, attempt to create new connection
- CLog.logAndDisplay(LogLevel.INFO, "Attempting connection to \"%s\"", mWifiSsid);
- if (device.connectToWifiNetwork(mWifiSsid, mWifiPsk)) { // attempt connection
- CLog.logAndDisplay(LogLevel.INFO, "Connection successful");
- } else {
+ logInfo("Attempting connection to \"%s\"", mWifiSsid);
+ if (!device.connectToWifiNetwork(mWifiSsid, mWifiPsk)) { // attempt connection
throw new TargetSetupError(String.format(
"Unable to connect to network \"%s\", some modules of CTS" +
"require an active network connection", mWifiSsid));
}
}
+ logInfo("Wifi is connected");
}
}
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/DocumentsTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/DocumentsTest.java
index c2f17c53..d81abb6 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/DocumentsTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/DocumentsTest.java
@@ -17,51 +17,23 @@
package android.appsecurity.cts;
import com.android.cts.migration.MigrationHelper;
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.testtype.DeviceTestCase;
-import com.android.tradefed.testtype.IAbi;
-import com.android.tradefed.testtype.IAbiReceiver;
-import com.android.tradefed.testtype.IBuildReceiver;
/**
* Set of tests that verify behavior of
* {@link android.provider.DocumentsContract} and related intents.
*/
-public class DocumentsTest extends DeviceTestCase implements IAbiReceiver, IBuildReceiver {
+public class DocumentsTest extends DocumentsTestCase {
private static final String PROVIDER_PKG = "com.android.cts.documentprovider";
private static final String PROVIDER_APK = "CtsDocumentProvider.apk";
- private static final String CLIENT_PKG = "com.android.cts.documentclient";
- private static final String CLIENT_APK = "CtsDocumentClient.apk";
-
- private IAbi mAbi;
- private IBuildInfo mCtsBuild;
-
- @Override
- public void setAbi(IAbi abi) {
- mAbi = abi;
- }
-
- @Override
- public void setBuild(IBuildInfo buildInfo) {
- mCtsBuild = buildInfo;
- }
-
@Override
protected void setUp() throws Exception {
super.setUp();
- assertNotNull(mAbi);
- assertNotNull(mCtsBuild);
-
getDevice().uninstallPackage(PROVIDER_PKG);
- getDevice().uninstallPackage(CLIENT_PKG);
assertNull(getDevice().installPackage(
MigrationHelper.getTestFile(mCtsBuild, PROVIDER_APK), false));
- assertNull(getDevice().installPackage(
- MigrationHelper.getTestFile(mCtsBuild, CLIENT_APK), false));
}
@Override
@@ -69,7 +41,6 @@
super.tearDown();
getDevice().uninstallPackage(PROVIDER_PKG);
- getDevice().uninstallPackage(CLIENT_PKG);
}
public void testOpenSimple() throws Exception {
@@ -92,43 +63,6 @@
runDeviceTests(CLIENT_PKG, ".DocumentsClientTest", "testTree");
}
- public void testOpenExternalDirectory_invalidPath() throws Exception {
- runDeviceTests(CLIENT_PKG, ".DocumentsClientTest", "testOpenExternalDirectory_invalidPath");
- }
-
- public void testOpenExternalDirectory_userRejects() throws Exception {
- runDeviceTests(CLIENT_PKG, ".DocumentsClientTest", "testOpenExternalDirectory_userRejects");
- }
-
- public void testOpenExternalDirectory_userAccepts() throws Exception {
- runDeviceTests(CLIENT_PKG, ".DocumentsClientTest", "testOpenExternalDirectory_userAccepts");
- }
-
- public void testOpenExternalDirectory_notAskedAgain() throws Exception {
- runDeviceTests(CLIENT_PKG, ".DocumentsClientTest",
- "testOpenExternalDirectory_notAskedAgain");
- }
-
- public void testOpenExternalDirectory_deniesOnceButAllowsAskingAgain() throws Exception {
- runDeviceTests(CLIENT_PKG, ".DocumentsClientTest",
- "testOpenExternalDirectory_deniesOnceButAllowsAskingAgain");
- }
-
- public void testOpenExternalDirectory_deniesOnceForAll() throws Exception {
- runDeviceTests(CLIENT_PKG, ".DocumentsClientTest",
- "testOpenExternalDirectory_deniesOnceForAll");
- }
-
- public void testOpenExternalDirectory_userAcceptsNewDirectory() throws Exception {
- // TODO: figure out a better way to remove the directory.
- final String command = "rm -rf /sdcard/Pictures";
- final String output = getDevice().executeShellCommand(command);
- if (!output.trim().isEmpty()) {
- fail("Command '" + command + "' failed: '" + output + "'");
- }
- runDeviceTests(CLIENT_PKG, ".DocumentsClientTest", "testOpenExternalDirectory_userAccepts");
- }
-
public void testGetContent() throws Exception {
runDeviceTests(CLIENT_PKG, ".DocumentsClientTest", "testGetContent");
}
@@ -136,9 +70,4 @@
public void testTransferDocument() throws Exception {
runDeviceTests(CLIENT_PKG, ".DocumentsClientTest", "testTransferDocument");
}
-
- public void runDeviceTests(String packageName, String testClassName, String testMethodName)
- throws DeviceNotAvailableException {
- Utils.runDeviceTests(getDevice(), packageName, testClassName, testMethodName);
- }
}
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/DocumentsTestCase.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/DocumentsTestCase.java
new file mode 100644
index 0000000..7bd42b5
--- /dev/null
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/DocumentsTestCase.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2016 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 android.appsecurity.cts;
+
+import com.android.cts.migration.MigrationHelper;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.testtype.IAbi;
+import com.android.tradefed.testtype.IAbiReceiver;
+import com.android.tradefed.testtype.IBuildReceiver;
+
+/**
+ * Base class for {@link android.provider.DocumentsContract} and related test cases.
+ */
+abstract class DocumentsTestCase extends DeviceTestCase implements IAbiReceiver, IBuildReceiver {
+ protected static final String CLIENT_PKG = "com.android.cts.documentclient";
+ protected static final String CLIENT_APK = "CtsDocumentClient.apk";
+
+ protected IAbi mAbi;
+ protected IBuildInfo mCtsBuild;
+
+ @Override
+ public void setAbi(IAbi abi) {
+ mAbi = abi;
+ }
+
+ @Override
+ public void setBuild(IBuildInfo buildInfo) {
+ mCtsBuild = buildInfo;
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ assertNotNull(mAbi);
+ assertNotNull(mCtsBuild);
+
+ getDevice().uninstallPackage(CLIENT_PKG);
+
+ assertNull(getDevice().installPackage(
+ MigrationHelper.getTestFile(mCtsBuild, CLIENT_APK), false));
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+
+ getDevice().uninstallPackage(CLIENT_PKG);
+ }
+
+ public void runDeviceTests(String packageName, String testClassName, String testMethodName)
+ throws DeviceNotAvailableException {
+ Utils.runDeviceTests(getDevice(), packageName, testClassName, testMethodName);
+ }
+}
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/ScopedDirectoryAccessTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/ScopedDirectoryAccessTest.java
new file mode 100644
index 0000000..ffc7597
--- /dev/null
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/ScopedDirectoryAccessTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2016 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 android.appsecurity.cts;
+
+/**
+ * Set of tests that verify behavior of the Scoped Directory access API.
+ */
+public class ScopedDirectoryAccessTest extends DocumentsTestCase {
+
+ public void testInvalidPath() throws Exception {
+ runDeviceTests(CLIENT_PKG, ".ScopedDirectoryAccessClientTest", "testInvalidPath");
+ }
+
+ public void testUserRejects() throws Exception {
+ runDeviceTests(CLIENT_PKG, ".ScopedDirectoryAccessClientTest", "testUserRejects");
+ }
+
+ public void testUserAccepts() throws Exception {
+ runDeviceTests(CLIENT_PKG, ".ScopedDirectoryAccessClientTest", "testUserAccepts");
+ }
+
+ public void testUserAcceptsNewDirectory() throws Exception {
+ runDeviceTests(CLIENT_PKG, ".ScopedDirectoryAccessClientTest",
+ "testUserAcceptsNewDirectory");
+ }
+
+ public void testNotAskedAgain() throws Exception {
+ runDeviceTests(CLIENT_PKG, ".ScopedDirectoryAccessClientTest", "testNotAskedAgain");
+ }
+
+ public void testDeniesOnceButAllowsAskingAgain() throws Exception {
+ runDeviceTests(CLIENT_PKG, ".ScopedDirectoryAccessClientTest",
+ "testDeniesOnceButAllowsAskingAgain");
+ }
+
+ public void testDeniesOnceForAll() throws Exception {
+ runDeviceTests(CLIENT_PKG, ".ScopedDirectoryAccessClientTest", "testDeniesOnceForAll");
+ }
+}
diff --git a/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTest.java b/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTest.java
index 6c9108d..acba1f4 100644
--- a/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTest.java
+++ b/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTest.java
@@ -16,58 +16,20 @@
package com.android.cts.documentclient;
-import static android.os.Environment.DIRECTORY_ALARMS;
-import static android.os.Environment.DIRECTORY_DCIM;
-import static android.os.Environment.DIRECTORY_DOCUMENTS;
-import static android.os.Environment.DIRECTORY_DOWNLOADS;
-import static android.os.Environment.DIRECTORY_MOVIES;
-import static android.os.Environment.DIRECTORY_MUSIC;
-import static android.os.Environment.DIRECTORY_NOTIFICATIONS;
-import static android.os.Environment.DIRECTORY_PICTURES;
-import static android.os.Environment.DIRECTORY_PODCASTS;
-import static android.os.Environment.DIRECTORY_RINGTONES;
-import static android.os.Environment.getExternalStorageDirectory;
-import static android.test.MoreAsserts.assertContainsRegex;
-import static android.test.MoreAsserts.assertNotEqual;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-import android.app.Activity;
-import android.app.ActivityManager;
-import android.app.Instrumentation;
import android.content.ContentResolver;
-import android.content.Context;
import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.res.AssetFileDescriptor.AutoCloseInputStream;
-import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.net.Uri;
-import android.os.Environment;
import android.os.SystemClock;
-import android.os.storage.StorageManager;
-import android.os.storage.StorageVolume;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Document;
import android.provider.DocumentsProvider;
-import android.support.test.uiautomator.By;
-import android.support.test.uiautomator.Configurator;
-import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject;
import android.support.test.uiautomator.UiObjectNotFoundException;
import android.support.test.uiautomator.UiScrollable;
import android.support.test.uiautomator.UiSelector;
-import android.support.test.uiautomator.Until;
-import android.test.InstrumentationTestCase;
import android.test.MoreAsserts;
-import android.text.format.DateUtils;
import android.util.Log;
-import android.view.MotionEvent;
import com.android.cts.documentclient.MyActivity.Result;
@@ -75,47 +37,9 @@
* Tests for {@link DocumentsProvider} and interaction with platform intents
* like {@link Intent#ACTION_OPEN_DOCUMENT}.
*/
-public class DocumentsClientTest extends InstrumentationTestCase {
+public class DocumentsClientTest extends DocumentsClientTestCase {
private static final String TAG = "DocumentsClientTest";
- private UiDevice mDevice;
- private MyActivity mActivity;
-
- private static final long TIMEOUT = 30 * DateUtils.SECOND_IN_MILLIS;
-
- private static final int REQUEST_CODE = 42;
-
- private static final String[] STANDARD_DIRECTORIES = {
- DIRECTORY_MUSIC,
- DIRECTORY_PODCASTS,
- DIRECTORY_RINGTONES,
- DIRECTORY_ALARMS,
- DIRECTORY_NOTIFICATIONS,
- DIRECTORY_PICTURES,
- DIRECTORY_MOVIES,
- DIRECTORY_DOWNLOADS,
- DIRECTORY_DCIM,
- DIRECTORY_DOCUMENTS
- };
-
- @Override
- public void setUp() throws Exception {
- super.setUp();
-
- Configurator.getInstance().setToolType(MotionEvent.TOOL_TYPE_FINGER);
-
- mDevice = UiDevice.getInstance(getInstrumentation());
- mActivity = launchActivity(getInstrumentation().getTargetContext().getPackageName(),
- MyActivity.class, null);
- mDevice.waitForIdle();
- }
-
- @Override
- public void tearDown() throws Exception {
- super.tearDown();
- mActivity.finish();
- }
-
private UiObject findRoot(String label) throws UiObjectNotFoundException {
final UiSelector rootsList = new UiSelector().resourceId(
"com.android.documentsui:id/container_roots").childSelector(
@@ -370,162 +294,6 @@
}
}
- public void testOpenExternalDirectory_invalidPath() throws Exception {
- if (!supportedHardware()) return;
-
- for (StorageVolume volume : getVolumes()) {
- openExternalDirectoryInvalidPath(volume, "");
- openExternalDirectoryInvalidPath(volume, "/dev/null");
- openExternalDirectoryInvalidPath(volume, "/../");
- openExternalDirectoryInvalidPath(volume, "/HiddenStuff");
- }
- }
-
- public void testOpenExternalDirectory_userRejects() throws Exception {
- if (!supportedHardware()) return;
-
- final StorageVolume primaryVolume = getPrimaryVolume();
-
- // Tests user clicking DENY button, for all valid directories.
- for (String directory : STANDARD_DIRECTORIES) {
- final UiAlertDialog dialog = openExternalDirectoryValidPath(primaryVolume, directory);
- dialog.noButton.click();
- assertActivityFailed();
- }
-
- // Also test user clicking back button - one directory is enough.
- openExternalDirectoryValidPath(primaryVolume, DIRECTORY_PICTURES);
- mDevice.pressBack();
- assertActivityFailed();
- }
-
- public void testOpenExternalDirectory_userAccepts() throws Exception {
- if (!supportedHardware())
- return;
-
- for (StorageVolume volume : getVolumes()) {
- userAcceptsOpenExternalDirectoryTest(volume, DIRECTORY_PICTURES);
- }
- }
-
- public void testOpenExternalDirectory_notAskedAgain() throws Exception {
- if (!supportedHardware())
- return;
-
- final StorageVolume volume = getPrimaryVolume();
- final Uri grantedUri = userAcceptsOpenExternalDirectoryTest(volume, DIRECTORY_PICTURES);
-
- // Calls it again - since the permission has been granted, it should return right away,
- // without popping up the permissions dialog.
- sendOpenExternalDirectoryIntent(volume, DIRECTORY_PICTURES);
- final Intent newData = assertActivitySucceeded();
- assertEquals(grantedUri, newData.getData());
-
- // Make sure other directories still require user permission.
- final Uri grantedUri2 = userAcceptsOpenExternalDirectoryTest(volume, DIRECTORY_ALARMS);
- assertNotEqual(grantedUri, grantedUri2);
- }
-
- public void testOpenExternalDirectory_deniesOnceButAllowsAskingAgain() throws Exception {
- if (!supportedHardware())
- return;
-
- for (StorageVolume volume : getVolumes()) {
- // Rejects the first attempt...
- UiAlertDialog dialog = openExternalDirectoryValidPath(volume, DIRECTORY_DCIM);
- dialog.assertDoNotAskAgainVisibility(false);
- dialog.noButton.click();
- assertActivityFailed();
-
- // ...and the second.
- dialog = openExternalDirectoryValidPath(volume, DIRECTORY_DCIM);
- dialog.assertDoNotAskAgainVisibility(true);
- dialog.noButton.click();
- assertActivityFailed();
-
- // Third time is a charm...
- userAcceptsOpenExternalDirectoryTest(volume, DIRECTORY_DCIM);
- }
- }
-
- public void testOpenExternalDirectory_deniesOnceForAll() throws Exception {
- if (!supportedHardware())
- return;
- for (StorageVolume volume : getVolumes()) {
- // Rejects the first attempt...
- UiAlertDialog dialog = openExternalDirectoryValidPath(volume, DIRECTORY_RINGTONES);
- dialog.assertDoNotAskAgainVisibility(false);
- dialog.noButton.click();
- assertActivityFailed();
-
- // ...and the second, checking the box
- dialog = openExternalDirectoryValidPath(volume, DIRECTORY_RINGTONES);
- UiObject checkbox = dialog.assertDoNotAskAgainVisibility(true);
- assertTrue("checkbox should not be checkable", checkbox.isCheckable());
- assertFalse("checkbox should not be checked", checkbox.isChecked());
- checkbox.click();
- assertTrue("checkbox should be checked", checkbox.isChecked()); // Sanity check
- assertFalse("allow button should be disabled", dialog.yesButton.isEnabled());
-
- dialog.noButton.click();
- assertActivityFailed();
-
- // Third strike out...
- sendOpenExternalDirectoryIntent(volume, DIRECTORY_RINGTONES);
- assertActivityFailed();
- }
- }
-
- private Uri userAcceptsOpenExternalDirectoryTest(StorageVolume volume, String directoryName)
- throws Exception {
- // Asserts dialog contain the proper message.
- final UiAlertDialog dialog = openExternalDirectoryValidPath(volume, directoryName);
- final String message = dialog.messageText.getText();
- Log.v(TAG, "request permission message: " + message);
- final Context context = getInstrumentation().getTargetContext();
- final String appLabel = context.getPackageManager().getApplicationLabel(
- context.getApplicationInfo()).toString();
- assertContainsRegex("missing app label", appLabel, message);
- assertContainsRegex("missing folder", directoryName, message);
- assertContainsRegex("missing root", volume.getDescription(context), message);
-
- // Call API...
- dialog.yesButton.click();
-
- // ...and get its response.
- final Intent data = assertActivitySucceeded();
- final Uri grantedUri = data.getData();
-
- // Test granted permission directly by persisting it...
- final ContentResolver resolver = getInstrumentation().getContext().getContentResolver();
- final int modeFlags = data.getFlags()
- & (Intent.FLAG_GRANT_READ_URI_PERMISSION
- | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
- resolver.takePersistableUriPermission(grantedUri, modeFlags);
-
- // ...and indirectly by creating some documents
- final Uri doc = DocumentsContract.buildDocumentUriUsingTree(grantedUri,
- DocumentsContract.getTreeDocumentId(grantedUri));
- assertNotNull("could not get tree URI", doc);
- final Uri pic = DocumentsContract.createDocument(resolver, doc, "image/png", "pic.png");
- assertNotNull("could not create file (pic.png) on tree root", pic);
- final Uri dir = DocumentsContract.createDocument(resolver, doc, Document.MIME_TYPE_DIR,
- "my dir");
- assertNotNull("could not create child dir (my dir)", pic);
- final Uri dirPic = DocumentsContract.createDocument(resolver, dir, "image/png", "pic2.png");
- assertNotNull("could not create file (pic.png) on child dir (my dir)", dirPic);
-
- writeFully(pic, "pic".getBytes());
- writeFully(dirPic, "dirPic".getBytes());
-
- // Clean up created documents.
- assertTrue("delete", DocumentsContract.deleteDocument(resolver, pic));
- assertTrue("delete", DocumentsContract.deleteDocument(resolver, dirPic));
- assertTrue("delete", DocumentsContract.deleteDocument(resolver, dir));
-
- return grantedUri;
- }
-
public void testGetContent() throws Exception {
if (!supportedHardware()) return;
@@ -660,147 +428,4 @@
cursorDst.close();
}
}
-
- private String getColumn(Uri uri, String column) {
- final ContentResolver resolver = getInstrumentation().getContext().getContentResolver();
- final Cursor cursor = resolver.query(uri, new String[] { column }, null, null, null);
- try {
- assertTrue(cursor.moveToFirst());
- return cursor.getString(0);
- } finally {
- cursor.close();
- }
- }
-
- private byte[] readFully(Uri uri) throws IOException {
- final InputStream in = getInstrumentation().getContext().getContentResolver()
- .openInputStream(uri);
- return readFully(in);
- }
-
- private byte[] readTypedFully(Uri uri, String mimeType) throws IOException {
- final AssetFileDescriptor descriptor =
- getInstrumentation().getContext().getContentResolver()
- .openTypedAssetFileDescriptor(uri, mimeType, null, null);
- try (AutoCloseInputStream in = new AutoCloseInputStream(descriptor)) {
- return readFully(in);
- }
- }
-
- private byte[] readFully(InputStream in) throws IOException {
- try {
- ByteArrayOutputStream bytes = new ByteArrayOutputStream();
- byte[] buffer = new byte[1024];
- int count;
- while ((count = in.read(buffer)) != -1) {
- bytes.write(buffer, 0, count);
- }
- return bytes.toByteArray();
- } finally {
- in.close();
- }
- }
-
- private void writeFully(Uri uri, byte[] data) throws IOException {
- OutputStream out = getInstrumentation().getContext().getContentResolver()
- .openOutputStream(uri);
- try {
- out.write(data);
- } finally {
- out.close();
- }
- }
-
- private boolean supportedHardware() {
- final PackageManager pm = getInstrumentation().getContext().getPackageManager();
- if (pm.hasSystemFeature("android.hardware.type.television")
- || pm.hasSystemFeature("android.hardware.type.watch")) {
- return false;
- }
- return true;
- }
-
- private void assertActivityFailed() {
- final Result result = mActivity.getResult();
- assertEquals(REQUEST_CODE, result.requestCode);
- assertEquals(Activity.RESULT_CANCELED, result.resultCode);
- assertNull(result.data);
- }
-
- private Intent assertActivitySucceeded() {
- final Result result = mActivity.getResult();
- assertEquals(REQUEST_CODE, result.requestCode);
- assertEquals(Activity.RESULT_OK, result.resultCode);
- assertNotNull(result.data);
- return result.data;
- }
-
- private void openExternalDirectoryInvalidPath(StorageVolume volume, String path) {
- sendOpenExternalDirectoryIntent(volume, path);
- assertActivityFailed();
- }
-
- private UiAlertDialog openExternalDirectoryValidPath(StorageVolume volume, String path)
- throws UiObjectNotFoundException {
- sendOpenExternalDirectoryIntent(volume, path);
- return new UiAlertDialog();
- }
-
- private void sendOpenExternalDirectoryIntent(StorageVolume volume, String directoryName) {
- final Intent intent = volume.createAccessIntent(directoryName);
- mActivity.startActivityForResult(intent, REQUEST_CODE);
- mDevice.waitForIdle();
- }
-
- private StorageVolume[] getVolumes() {
- final StorageManager sm = (StorageManager)
- getInstrumentation().getTargetContext().getSystemService(Context.STORAGE_SERVICE);
- final StorageVolume[] volumes = sm.getVolumeList();
- assertTrue("empty volumes", volumes.length > 0);
- return volumes;
- }
-
- private StorageVolume getPrimaryVolume() {
- final StorageManager sm = (StorageManager)
- getInstrumentation().getTargetContext().getSystemService(Context.STORAGE_SERVICE);
- return sm.getPrimaryVolume();
- }
-
- private final class UiAlertDialog {
- final UiObject dialog;
- final UiObject messageText;
- final UiObject yesButton;
- final UiObject noButton;
-
- UiAlertDialog() throws UiObjectNotFoundException {
- final String id = "android:id/parentPanel";
- boolean gotIt = mDevice.wait(Until.hasObject(By.res(id)), TIMEOUT);
- assertTrue("object with id '(" + id + "') not visible yet", gotIt);
- dialog = mDevice.findObject(new UiSelector().resourceId(id));
- assertTrue("object with id '(" + id + "') doesn't exist", dialog.exists());
- messageText = dialog.getChild(
- new UiSelector().resourceId("com.android.documentsui:id/message"));
- yesButton = dialog.getChild(new UiSelector().resourceId("android:id/button1"));
- noButton = dialog.getChild(new UiSelector().resourceId("android:id/button2"));
- }
-
- private UiObject getDoNotAskAgainCheckBox() throws UiObjectNotFoundException {
- return dialog.getChild(
- new UiSelector().resourceId("com.android.documentsui:id/do_not_ask_checkbox"));
- }
-
- UiObject assertDoNotAskAgainVisibility(boolean expectVisible) {
- UiObject checkbox = null;
- try {
- checkbox = getDoNotAskAgainCheckBox();
- assertEquals("Wrong value for 'DoNotAskAgain.exists()",
- expectVisible, checkbox.exists());
- } catch (UiObjectNotFoundException e) {
- if (expectVisible) {
- fail("'Do Not Ask Again' not found");
- }
- }
- return checkbox;
- }
- }
}
diff --git a/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTestCase.java b/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTestCase.java
new file mode 100644
index 0000000..cb7dc48
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTestCase.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2016 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.cts.documentclient;
+
+import static android.cts.util.SystemUtil.runShellCommand;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import com.android.cts.documentclient.MyActivity.Result;
+
+import android.app.Activity;
+import android.content.ContentResolver;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.res.AssetFileDescriptor;
+import android.content.res.AssetFileDescriptor.AutoCloseInputStream;
+import android.database.Cursor;
+import android.net.Uri;
+import android.support.test.uiautomator.Configurator;
+import android.support.test.uiautomator.UiDevice;
+import android.test.InstrumentationTestCase;
+import android.text.format.DateUtils;
+import android.util.Log;
+import android.view.MotionEvent;
+
+/**
+ * Base class for DocumentsUI test cases.
+ */
+abstract class DocumentsClientTestCase extends InstrumentationTestCase {
+ private static final String TAG = "DocumentsClientTestCase";
+
+ protected UiDevice mDevice;
+ protected MyActivity mActivity;
+
+ protected static final long TIMEOUT = 30 * DateUtils.SECOND_IN_MILLIS;
+ protected static final int REQUEST_CODE = 42;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+
+ Configurator.getInstance().setToolType(MotionEvent.TOOL_TYPE_FINGER);
+
+ mDevice = UiDevice.getInstance(getInstrumentation());
+ mActivity = launchActivity(getInstrumentation().getTargetContext().getPackageName(),
+ MyActivity.class, null);
+ mDevice.waitForIdle();
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ super.tearDown();
+ mActivity.finish();
+ }
+
+ protected String getColumn(Uri uri, String column) {
+ final ContentResolver resolver = getInstrumentation().getContext().getContentResolver();
+ final Cursor cursor = resolver.query(uri, new String[] { column }, null, null, null);
+ try {
+ assertTrue(cursor.moveToFirst());
+ return cursor.getString(0);
+ } finally {
+ cursor.close();
+ }
+ }
+
+ protected byte[] readFully(Uri uri) throws IOException {
+ final InputStream in = getInstrumentation().getContext().getContentResolver()
+ .openInputStream(uri);
+ return readFully(in);
+ }
+
+ protected byte[] readTypedFully(Uri uri, String mimeType) throws IOException {
+ final AssetFileDescriptor descriptor =
+ getInstrumentation().getContext().getContentResolver()
+ .openTypedAssetFileDescriptor(uri, mimeType, null, null);
+ try (AutoCloseInputStream in = new AutoCloseInputStream(descriptor)) {
+ return readFully(in);
+ }
+ }
+
+ protected byte[] readFully(InputStream in) throws IOException {
+ try {
+ ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+ byte[] buffer = new byte[1024];
+ int count;
+ while ((count = in.read(buffer)) != -1) {
+ bytes.write(buffer, 0, count);
+ }
+ return bytes.toByteArray();
+ } finally {
+ in.close();
+ }
+ }
+
+ protected void writeFully(Uri uri, byte[] data) throws IOException {
+ OutputStream out = getInstrumentation().getContext().getContentResolver()
+ .openOutputStream(uri);
+ try {
+ out.write(data);
+ } finally {
+ out.close();
+ }
+ }
+
+ protected boolean supportedHardware() {
+ final PackageManager pm = getInstrumentation().getContext().getPackageManager();
+ if (pm.hasSystemFeature("android.hardware.type.television")
+ || pm.hasSystemFeature("android.hardware.type.watch")) {
+ return false;
+ }
+ return true;
+ }
+
+ protected void assertActivityFailed() {
+ final Result result = mActivity.getResult();
+ assertEquals(REQUEST_CODE, result.requestCode);
+ assertEquals(Activity.RESULT_CANCELED, result.resultCode);
+ assertNull(result.data);
+ }
+
+ protected Intent assertActivitySucceeded() {
+ final Result result = mActivity.getResult();
+ assertEquals(REQUEST_CODE, result.requestCode);
+ assertEquals(Activity.RESULT_OK, result.resultCode);
+ assertNotNull(result.data);
+ return result.data;
+ }
+
+ protected String executeShellCommand(String command) throws Exception {
+ final String result = runShellCommand(getInstrumentation(), command).trim();
+ Log.d(TAG, "Command '" + command + "' returned '" + result + "'");
+ return result;
+ }
+
+ protected void clearDocumentsUi() throws Exception {
+ executeShellCommand("pm clear com.android.documentsui");
+ }
+}
diff --git a/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/ScopedDirectoryAccessClientTest.java b/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/ScopedDirectoryAccessClientTest.java
new file mode 100644
index 0000000..3553bbf
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/ScopedDirectoryAccessClientTest.java
@@ -0,0 +1,307 @@
+/*
+ * Copyright (C) 2016 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.cts.documentclient;
+
+import static android.os.Environment.DIRECTORY_ALARMS;
+import static android.os.Environment.DIRECTORY_DCIM;
+import static android.os.Environment.DIRECTORY_DOCUMENTS;
+import static android.os.Environment.DIRECTORY_DOWNLOADS;
+import static android.os.Environment.DIRECTORY_MOVIES;
+import static android.os.Environment.DIRECTORY_MUSIC;
+import static android.os.Environment.DIRECTORY_NOTIFICATIONS;
+import static android.os.Environment.DIRECTORY_PICTURES;
+import static android.os.Environment.DIRECTORY_PODCASTS;
+import static android.os.Environment.DIRECTORY_RINGTONES;
+import static android.test.MoreAsserts.assertContainsRegex;
+import static android.test.MoreAsserts.assertNotEqual;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.storage.StorageManager;
+import android.os.storage.StorageVolume;
+import android.provider.DocumentsContract;
+import android.provider.DocumentsContract.Document;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.UiObject;
+import android.support.test.uiautomator.UiObjectNotFoundException;
+import android.support.test.uiautomator.UiSelector;
+import android.support.test.uiautomator.Until;
+import android.util.Log;
+
+/**
+ * Set of tests that verify behavior of the Scoped Directory Access API.
+ */
+public class ScopedDirectoryAccessClientTest extends DocumentsClientTestCase {
+ private static final String TAG = "ScopedDirectoryAccessClientTest";
+
+ private static final String[] STANDARD_DIRECTORIES = {
+ DIRECTORY_MUSIC,
+ DIRECTORY_PODCASTS,
+ DIRECTORY_RINGTONES,
+ DIRECTORY_ALARMS,
+ DIRECTORY_NOTIFICATIONS,
+ DIRECTORY_PICTURES,
+ DIRECTORY_MOVIES,
+ DIRECTORY_DOWNLOADS,
+ DIRECTORY_DCIM,
+ DIRECTORY_DOCUMENTS
+ };
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+
+ // DocumentsUI caches some info like whether a user rejects a request, so we need to clear
+ // its data before each test.
+ clearDocumentsUi();
+ }
+
+ public void testInvalidPath() throws Exception {
+ if (!supportedHardware()) return;
+
+ for (StorageVolume volume : getVolumes()) {
+ openExternalDirectoryInvalidPath(volume, "");
+ openExternalDirectoryInvalidPath(volume, "/dev/null");
+ openExternalDirectoryInvalidPath(volume, "/../");
+ openExternalDirectoryInvalidPath(volume, "/HiddenStuff");
+ }
+ }
+
+ public void testUserRejects() throws Exception {
+ if (!supportedHardware()) return;
+
+ final StorageVolume primaryVolume = getPrimaryVolume();
+
+ // Tests user clicking DENY button, for all valid directories.
+ for (String directory : STANDARD_DIRECTORIES) {
+ final UiAlertDialog dialog = openExternalDirectoryValidPath(primaryVolume, directory);
+ dialog.noButton.click();
+ assertActivityFailed();
+ }
+
+ // Also test user clicking back button - one directory is enough.
+ openExternalDirectoryValidPath(primaryVolume, DIRECTORY_PICTURES);
+ mDevice.pressBack();
+ assertActivityFailed();
+ }
+
+ public void testUserAccepts() throws Exception {
+ if (!supportedHardware()) return;
+
+ for (StorageVolume volume : getVolumes()) {
+ userAcceptsOpenExternalDirectoryTest(volume, DIRECTORY_PICTURES);
+ }
+ }
+
+ public void testUserAcceptsNewDirectory() throws Exception {
+ if (!supportedHardware()) return;
+
+ // TODO: figure out a better way to remove the directory.
+ final String command = "rm -rf /sdcard/" + DIRECTORY_PICTURES;
+ final String output = executeShellCommand(command);
+ if (!output.isEmpty()) {
+ fail("Command '" + command + "' failed: '" + output + "'");
+ }
+ userAcceptsOpenExternalDirectoryTest(getPrimaryVolume(), DIRECTORY_PICTURES);
+ }
+
+ public void testNotAskedAgain() throws Exception {
+ if (!supportedHardware()) return;
+
+ final StorageVolume volume = getPrimaryVolume();
+ final Uri grantedUri = userAcceptsOpenExternalDirectoryTest(volume, DIRECTORY_PICTURES);
+
+ // Calls it again - since the permission has been granted, it should return right away,
+ // without popping up the permissions dialog.
+ sendOpenExternalDirectoryIntent(volume, DIRECTORY_PICTURES);
+ final Intent newData = assertActivitySucceeded();
+ assertEquals(grantedUri, newData.getData());
+
+ // Make sure other directories still require user permission.
+ final Uri grantedUri2 = userAcceptsOpenExternalDirectoryTest(volume, DIRECTORY_ALARMS);
+ assertNotEqual(grantedUri, grantedUri2);
+ }
+
+ public void testDeniesOnceButAllowsAskingAgain() throws Exception {
+ if (!supportedHardware())return;
+
+ for (StorageVolume volume : getVolumes()) {
+ // Rejects the first attempt...
+ UiAlertDialog dialog = openExternalDirectoryValidPath(volume, DIRECTORY_DCIM);
+ dialog.assertDoNotAskAgainVisibility(false);
+ dialog.noButton.click();
+ assertActivityFailed();
+
+ // ...and the second.
+ dialog = openExternalDirectoryValidPath(volume, DIRECTORY_DCIM);
+ dialog.assertDoNotAskAgainVisibility(true);
+ dialog.noButton.click();
+ assertActivityFailed();
+
+ // Third time is a charm...
+ userAcceptsOpenExternalDirectoryTest(volume, DIRECTORY_DCIM);
+ }
+ }
+
+ public void testDeniesOnceForAll() throws Exception {
+ if (!supportedHardware()) return;
+
+ for (StorageVolume volume : getVolumes()) {
+ // Rejects the first attempt...
+ UiAlertDialog dialog = openExternalDirectoryValidPath(volume, DIRECTORY_RINGTONES);
+ dialog.assertDoNotAskAgainVisibility(false);
+ dialog.noButton.click();
+ assertActivityFailed();
+
+ // ...and the second, checking the box
+ dialog = openExternalDirectoryValidPath(volume, DIRECTORY_RINGTONES);
+ UiObject checkbox = dialog.assertDoNotAskAgainVisibility(true);
+ assertTrue("checkbox should not be checkable", checkbox.isCheckable());
+ assertFalse("checkbox should not be checked", checkbox.isChecked());
+ checkbox.click();
+ assertTrue("checkbox should be checked", checkbox.isChecked()); // Sanity check
+ assertFalse("allow button should be disabled", dialog.yesButton.isEnabled());
+
+ dialog.noButton.click();
+ assertActivityFailed();
+
+ // Third strike out...
+ sendOpenExternalDirectoryIntent(volume, DIRECTORY_RINGTONES);
+ assertActivityFailed();
+ }
+ }
+
+ private Uri userAcceptsOpenExternalDirectoryTest(StorageVolume volume, String directoryName)
+ throws Exception {
+ // Asserts dialog contain the proper message.
+ final UiAlertDialog dialog = openExternalDirectoryValidPath(volume, directoryName);
+ final String message = dialog.messageText.getText();
+ Log.v(TAG, "request permission message: " + message);
+ final Context context = getInstrumentation().getTargetContext();
+ final String appLabel = context.getPackageManager().getApplicationLabel(
+ context.getApplicationInfo()).toString();
+ assertContainsRegex("missing app label", appLabel, message);
+ assertContainsRegex("missing folder", directoryName, message);
+ assertContainsRegex("missing root", volume.getDescription(context), message);
+
+ // Call API...
+ dialog.yesButton.click();
+
+ // ...and get its response.
+ final Intent data = assertActivitySucceeded();
+ final Uri grantedUri = data.getData();
+
+ // Test granted permission directly by persisting it...
+ final ContentResolver resolver = getInstrumentation().getContext().getContentResolver();
+ final int modeFlags = data.getFlags()
+ & (Intent.FLAG_GRANT_READ_URI_PERMISSION
+ | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+ resolver.takePersistableUriPermission(grantedUri, modeFlags);
+
+ // ...and indirectly by creating some documents
+ final Uri doc = DocumentsContract.buildDocumentUriUsingTree(grantedUri,
+ DocumentsContract.getTreeDocumentId(grantedUri));
+ assertNotNull("could not get tree URI", doc);
+ final Uri pic = DocumentsContract.createDocument(resolver, doc, "image/png", "pic.png");
+ assertNotNull("could not create file (pic.png) on tree root", pic);
+ final Uri dir = DocumentsContract.createDocument(resolver, doc, Document.MIME_TYPE_DIR,
+ "my dir");
+ assertNotNull("could not create child dir (my dir)", pic);
+ final Uri dirPic = DocumentsContract.createDocument(resolver, dir, "image/png", "pic2.png");
+ assertNotNull("could not create file (pic.png) on child dir (my dir)", dirPic);
+
+ writeFully(pic, "pic".getBytes());
+ writeFully(dirPic, "dirPic".getBytes());
+
+ // Clean up created documents.
+ assertTrue("delete", DocumentsContract.deleteDocument(resolver, pic));
+ assertTrue("delete", DocumentsContract.deleteDocument(resolver, dirPic));
+ assertTrue("delete", DocumentsContract.deleteDocument(resolver, dir));
+
+ return grantedUri;
+ }
+
+ private void openExternalDirectoryInvalidPath(StorageVolume volume, String path) {
+ sendOpenExternalDirectoryIntent(volume, path);
+ assertActivityFailed();
+ }
+
+ private UiAlertDialog openExternalDirectoryValidPath(StorageVolume volume, String path)
+ throws UiObjectNotFoundException {
+ sendOpenExternalDirectoryIntent(volume, path);
+ return new UiAlertDialog();
+ }
+
+ private void sendOpenExternalDirectoryIntent(StorageVolume volume, String directoryName) {
+ final Intent intent = volume.createAccessIntent(directoryName);
+ mActivity.startActivityForResult(intent, REQUEST_CODE);
+ mDevice.waitForIdle();
+ }
+
+ private StorageVolume[] getVolumes() {
+ final StorageManager sm = (StorageManager)
+ getInstrumentation().getTargetContext().getSystemService(Context.STORAGE_SERVICE);
+ final StorageVolume[] volumes = sm.getVolumeList();
+ assertTrue("empty volumes", volumes.length > 0);
+ return volumes;
+ }
+
+ private StorageVolume getPrimaryVolume() {
+ final StorageManager sm = (StorageManager)
+ getInstrumentation().getTargetContext().getSystemService(Context.STORAGE_SERVICE);
+ return sm.getPrimaryVolume();
+ }
+
+ private final class UiAlertDialog {
+ final UiObject dialog;
+ final UiObject messageText;
+ final UiObject yesButton;
+ final UiObject noButton;
+
+ UiAlertDialog() throws UiObjectNotFoundException {
+ final String id = "android:id/parentPanel";
+ boolean gotIt = mDevice.wait(Until.hasObject(By.res(id)), TIMEOUT);
+ assertTrue("object with id '(" + id + "') not visible yet", gotIt);
+ dialog = mDevice.findObject(new UiSelector().resourceId(id));
+ assertTrue("object with id '(" + id + "') doesn't exist", dialog.exists());
+ messageText = dialog.getChild(
+ new UiSelector().resourceId("com.android.documentsui:id/message"));
+ yesButton = dialog.getChild(new UiSelector().resourceId("android:id/button1"));
+ noButton = dialog.getChild(new UiSelector().resourceId("android:id/button2"));
+ }
+
+ private UiObject getDoNotAskAgainCheckBox() throws UiObjectNotFoundException {
+ return dialog.getChild(
+ new UiSelector().resourceId("com.android.documentsui:id/do_not_ask_checkbox"));
+ }
+
+ UiObject assertDoNotAskAgainVisibility(boolean expectVisible) {
+ UiObject checkbox = null;
+ try {
+ checkbox = getDoNotAskAgainCheckBox();
+ assertEquals("Wrong value for 'DoNotAskAgain.exists()",
+ expectVisible, checkbox.exists());
+ } catch (UiObjectNotFoundException e) {
+ if (expectVisible) {
+ fail("'Do Not Ask Again' not found");
+ }
+ }
+ return checkbox;
+ }
+ }
+}
diff --git a/hostsidetests/appsecurity/test-apps/EncryptionApp/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/EncryptionApp/AndroidManifest.xml
index 824e285..b42414c 100644
--- a/hostsidetests/appsecurity/test-apps/EncryptionApp/AndroidManifest.xml
+++ b/hostsidetests/appsecurity/test-apps/EncryptionApp/AndroidManifest.xml
@@ -32,20 +32,20 @@
android:exported="true" />
<activity android:name=".AwareActivity"
- android:encryptionAware="true"
+ android:directBootAware="true"
android:exported="true" />
<receiver android:name=".AwareReceiver"
- android:encryptionAware="true"
+ android:directBootAware="true"
android:exported="true" />
<service android:name=".AwareService"
- android:encryptionAware="true"
+ android:directBootAware="true"
android:exported="true" />
<provider android:name=".AwareProvider"
android:authorities="com.android.cts.encryptionapp.aware"
- android:encryptionAware="true"
+ android:directBootAware="true"
android:exported="true" />
<uses-library android:name="android.test.runner" />
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/DeviceLoggingTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/DeviceLoggingTest.java
deleted file mode 100644
index 642915f..0000000
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/DeviceLoggingTest.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2016 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.cts.deviceowner;
-
-import android.auditing.SecurityLog.SecurityEvent;
-import android.os.UserHandle;
-
-import java.util.List;
-
-public class DeviceLoggingTest extends BaseDeviceOwnerTest {
-
- private static final String MESSAGE_ONLY_ONE_MANAGED_USER_ALLOWED =
- "There should only be one user, managed by Device Owner";
-
- /**
- * Test: setting device logging can only be done if there's one user on the device.
- */
- public void testSetDeviceLoggingEnabledNotPossibleIfMoreThanOneUserPresent() {
- try {
- mDevicePolicyManager.setDeviceLoggingEnabled(getWho(), true);
- fail("did not throw expected SecurityException");
- } catch (SecurityException e) {
- assertEquals(e.getMessage(), MESSAGE_ONLY_ONE_MANAGED_USER_ALLOWED);
- }
- }
-
- /**
- * Test: retrieving device logs can only be done if there's one user on the device.
- */
- public void testRetrievingDeviceLogsNotPossibleIfMoreThanOneUserPresent() {
- try {
- mDevicePolicyManager.retrieveDeviceLogs(getWho());
- fail("did not throw expected SecurityException");
- } catch (SecurityException e) {
- assertEquals(e.getMessage(), MESSAGE_ONLY_ONE_MANAGED_USER_ALLOWED);
- }
- }
-
- /**
- * Test: retrieving previous device logs can only be done if there's one user on the device.
- */
- public void testRetrievingPreviousDeviceLogsNotPossibleIfMoreThanOneUserPresent() {
- try {
- mDevicePolicyManager.retrievePreviousDeviceLogs(getWho());
- fail("did not throw expected SecurityException");
- } catch (SecurityException e) {
- assertEquals(e.getMessage(), MESSAGE_ONLY_ONE_MANAGED_USER_ALLOWED);
- }
- }
-
- /**
- * Test: retrieving device logs should be rate limited - subsequent attempts should return null.
- * TODO(mkarpinski): consider how we can test that the rate limiting is set to 2 hours.
- */
- public void testRetrievingDeviceLogsNotPossibleImmediatelyAfterPreviousSuccessfulRetrieval() {
- List<SecurityEvent> logs = mDevicePolicyManager.retrieveDeviceLogs(getWho());
- // if logs is null it means that that attempt was rate limited => test PASS
- if (logs != null) {
- assertNull(mDevicePolicyManager.retrieveDeviceLogs(getWho()));
- assertNull(mDevicePolicyManager.retrieveDeviceLogs(getWho()));
- }
- }
-}
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/HardwarePropertiesManagerTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/HardwarePropertiesManagerTest.java
new file mode 100644
index 0000000..f61c796
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/HardwarePropertiesManagerTest.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2016 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.cts.deviceowner;
+
+import android.content.Context;
+import android.os.CpuUsageInfo;
+import android.os.HardwarePropertiesManager;
+import android.os.SystemClock;
+
+import java.lang.Math;
+
+/**
+ * Test {@link HardwarePropertiesManager}
+ */
+public class HardwarePropertiesManagerTest extends BaseDeviceOwnerTest {
+ public static final int MAX_FAN_SPEED = 20000;
+ public static final int MAX_DEVICE_TEMPERATURE = 200;
+ public static final int MONITORING_ITERATION_NUMBER = 10;
+
+ // Time between checks in milliseconds.
+ public static final long SLEEP_TIME = 10;
+
+ private void checkFanSpeed(float speed) {
+ assertTrue(speed >= 0 && speed < MAX_FAN_SPEED);
+ }
+
+ private void checkDeviceTemp(float temp, float throttlingTemp, float shutdownTemp) {
+ // Check validity of current temperature.
+ assertTrue(Math.abs(temp) < MAX_DEVICE_TEMPERATURE
+ || temp == HardwarePropertiesManager.UNDEFINED_TEMPERATURE);
+
+ // Compare current temperature and shutdown threshold.
+ assertTrue(temp < shutdownTemp
+ || shutdownTemp == HardwarePropertiesManager.UNDEFINED_TEMPERATURE);
+ // Compare throttling and shutdown thresholds.
+ assertTrue(throttlingTemp < shutdownTemp
+ || throttlingTemp == HardwarePropertiesManager.UNDEFINED_TEMPERATURE
+ || shutdownTemp == HardwarePropertiesManager.UNDEFINED_TEMPERATURE);
+ }
+
+ private void checkCpuUsageInfo(CpuUsageInfo info) {
+ assertTrue(info == null || (info.getActive() >= 0 && info.getTotal() >= 0
+ && info.getTotal() >= info.getActive()));
+ }
+
+ private void checkFanSpeeds(float[] fanSpeeds) {
+ for (float speed : fanSpeeds) {
+ checkFanSpeed(speed);
+ }
+ }
+
+ private void checkTemps(float[] temps, float[] throttlingThresholds,
+ float[] shutdownThresholds) {
+ assertEquals(temps.length, throttlingThresholds.length);
+ assertEquals(temps.length, shutdownThresholds.length);
+ for (int i = 0; i < temps.length; ++i) {
+ checkDeviceTemp(temps[i], throttlingThresholds[i], shutdownThresholds[i]);
+ }
+ }
+
+ private void checkCpuUsages(CpuUsageInfo[] cpuUsages) {
+ for (CpuUsageInfo info : cpuUsages) {
+ checkCpuUsageInfo(info);
+ }
+ }
+
+ // Check validity of new array of fan speeds:
+ // the number of fans should be the same.
+ private void checkFanSpeeds(float[] speeds, float[] oldSpeeds) {
+ assertEquals(speeds.length, oldSpeeds.length);
+ }
+
+ // Check validity of new array of cpu usages:
+ // The number of CPUs should be the same and total/active time should not decrease.
+ private void checkCpuUsages(CpuUsageInfo[] infos,
+ CpuUsageInfo[] oldInfos) {
+ assertEquals(infos.length, oldInfos.length);
+ for (int i = 0; i < infos.length; ++i) {
+ assertTrue(oldInfos[i] == null || infos[i] == null
+ || (oldInfos[i].getActive() <= infos[i].getActive()
+ && oldInfos[i].getTotal() <= infos[i].getTotal()));
+ }
+ }
+
+ /**
+ * test points:
+ * 1. Get fan speeds, device temperatures and CPU usage information.
+ * 2. Check for validity.
+ * 3. Sleep.
+ * 4. Do it 10 times and compare with old ones.
+ */
+ public void testHardwarePropertiesManager() throws InterruptedException,
+ SecurityException {
+ HardwarePropertiesManager hm = (HardwarePropertiesManager) getContext().getSystemService(
+ Context.HARDWARE_PROPERTIES_SERVICE);
+
+ float[] oldFanSpeeds = hm.getFanSpeeds();
+
+ float[] cpuTemps = hm.getDeviceTemperatures(
+ HardwarePropertiesManager.DEVICE_TEMPERATURE_CPU,
+ HardwarePropertiesManager.TEMPERATURE_CURRENT);
+ float[] cpuThrottlingThresholds = hm.getDeviceTemperatures(
+ HardwarePropertiesManager.DEVICE_TEMPERATURE_CPU,
+ HardwarePropertiesManager.TEMPERATURE_THROTTLING);
+ float[] cpuShutdownThresholds = hm.getDeviceTemperatures(
+ HardwarePropertiesManager.DEVICE_TEMPERATURE_CPU,
+ HardwarePropertiesManager.TEMPERATURE_SHUTDOWN);
+
+ float[] gpuTemps = hm.getDeviceTemperatures(
+ HardwarePropertiesManager.DEVICE_TEMPERATURE_GPU,
+ HardwarePropertiesManager.TEMPERATURE_CURRENT);
+ float[] gpuThrottlingThresholds = hm.getDeviceTemperatures(
+ HardwarePropertiesManager.DEVICE_TEMPERATURE_GPU,
+ HardwarePropertiesManager.TEMPERATURE_THROTTLING);
+ float[] gpuShutdownThresholds = hm.getDeviceTemperatures(
+ HardwarePropertiesManager.DEVICE_TEMPERATURE_GPU,
+ HardwarePropertiesManager.TEMPERATURE_SHUTDOWN);
+
+ float[] batteryTemps = hm.getDeviceTemperatures(
+ HardwarePropertiesManager.DEVICE_TEMPERATURE_BATTERY,
+ HardwarePropertiesManager.TEMPERATURE_CURRENT);
+ float[] batteryThrottlingThresholds = hm.getDeviceTemperatures(
+ HardwarePropertiesManager.DEVICE_TEMPERATURE_BATTERY,
+ HardwarePropertiesManager.TEMPERATURE_THROTTLING);
+ float[] batteryShutdownThresholds = hm.getDeviceTemperatures(
+ HardwarePropertiesManager.DEVICE_TEMPERATURE_BATTERY,
+ HardwarePropertiesManager.TEMPERATURE_SHUTDOWN);
+
+ float[] skinTemps = hm.getDeviceTemperatures(
+ HardwarePropertiesManager.DEVICE_TEMPERATURE_SKIN,
+ HardwarePropertiesManager.TEMPERATURE_CURRENT);
+ float[] skinThrottlingThresholds = hm.getDeviceTemperatures(
+ HardwarePropertiesManager.DEVICE_TEMPERATURE_SKIN,
+ HardwarePropertiesManager.TEMPERATURE_THROTTLING);
+ float[] skinShutdownThresholds = hm.getDeviceTemperatures(
+ HardwarePropertiesManager.DEVICE_TEMPERATURE_SKIN,
+ HardwarePropertiesManager.TEMPERATURE_SHUTDOWN);
+
+ CpuUsageInfo[] oldCpuUsages = hm.getCpuUsages();
+
+ checkFanSpeeds(oldFanSpeeds);
+ checkTemps(cpuTemps, cpuThrottlingThresholds, cpuShutdownThresholds);
+ checkTemps(gpuTemps, gpuThrottlingThresholds, gpuShutdownThresholds);
+ checkTemps(batteryTemps, batteryThrottlingThresholds, batteryShutdownThresholds);
+ checkTemps(skinTemps, skinThrottlingThresholds, skinShutdownThresholds);
+ checkCpuUsages(oldCpuUsages);
+
+ for (int i = 0; i < MONITORING_ITERATION_NUMBER; i++) {
+ Thread.sleep(SLEEP_TIME);
+
+ float[] fanSpeeds = hm.getFanSpeeds();
+ cpuTemps = hm.getDeviceTemperatures(
+ HardwarePropertiesManager.DEVICE_TEMPERATURE_CPU,
+ HardwarePropertiesManager.TEMPERATURE_CURRENT);
+ gpuTemps = hm.getDeviceTemperatures(
+ HardwarePropertiesManager.DEVICE_TEMPERATURE_GPU,
+ HardwarePropertiesManager.TEMPERATURE_CURRENT);
+ batteryTemps = hm.getDeviceTemperatures(
+ HardwarePropertiesManager.DEVICE_TEMPERATURE_BATTERY,
+ HardwarePropertiesManager.TEMPERATURE_CURRENT);
+ skinTemps = hm.getDeviceTemperatures(
+ HardwarePropertiesManager.DEVICE_TEMPERATURE_SKIN,
+ HardwarePropertiesManager.TEMPERATURE_CURRENT);
+ CpuUsageInfo[] cpuUsages = hm.getCpuUsages();
+
+ checkFanSpeeds(fanSpeeds);
+ checkTemps(cpuTemps, cpuThrottlingThresholds, cpuShutdownThresholds);
+ checkTemps(gpuTemps, gpuThrottlingThresholds, gpuShutdownThresholds);
+ checkTemps(batteryTemps, batteryThrottlingThresholds, batteryShutdownThresholds);
+ checkTemps(skinTemps, skinThrottlingThresholds, skinShutdownThresholds);
+ checkCpuUsages(cpuUsages);
+
+ // No need to compare length of old and new temperature arrays:
+ // they are compared through throttling and shutdown threshold arrays lengths.
+ checkFanSpeeds(fanSpeeds, oldFanSpeeds);
+ checkCpuUsages(cpuUsages, oldCpuUsages);
+
+ oldFanSpeeds = fanSpeeds;
+ oldCpuUsages = cpuUsages;
+ }
+ }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SecurityLoggingTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SecurityLoggingTest.java
new file mode 100644
index 0000000..0c1f421
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SecurityLoggingTest.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2016 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.cts.deviceowner;
+
+import android.app.admin.SecurityLog.SecurityEvent;
+import android.os.UserHandle;
+
+import java.util.List;
+
+public class SecurityLoggingTest extends BaseDeviceOwnerTest {
+
+ private static final String MESSAGE_ONLY_ONE_MANAGED_USER_ALLOWED =
+ "There should only be one user, managed by Device Owner";
+
+ /**
+ * Test: setting security logging can only be done if there's one user on the device.
+ */
+ public void testSetSecurityLoggingEnabledNotPossibleIfMoreThanOneUserPresent() {
+ try {
+ mDevicePolicyManager.setSecurityLoggingEnabled(getWho(), true);
+ fail("did not throw expected SecurityException");
+ } catch (SecurityException e) {
+ assertEquals(e.getMessage(), MESSAGE_ONLY_ONE_MANAGED_USER_ALLOWED);
+ }
+ }
+
+ /**
+ * Test: retrieving security logs can only be done if there's one user on the device.
+ */
+ public void testRetrievingSecurityLogsNotPossibleIfMoreThanOneUserPresent() {
+ try {
+ mDevicePolicyManager.retrieveSecurityLogs(getWho());
+ fail("did not throw expected SecurityException");
+ } catch (SecurityException e) {
+ assertEquals(e.getMessage(), MESSAGE_ONLY_ONE_MANAGED_USER_ALLOWED);
+ }
+ }
+
+ /**
+ * Test: retrieving previous security logs can only be done if there's one user on the device.
+ */
+ public void testRetrievingPreviousSecurityLogsNotPossibleIfMoreThanOneUserPresent() {
+ try {
+ mDevicePolicyManager.retrievePreRebootSecurityLogs(getWho());
+ fail("did not throw expected SecurityException");
+ } catch (SecurityException e) {
+ assertEquals(e.getMessage(), MESSAGE_ONLY_ONE_MANAGED_USER_ALLOWED);
+ }
+ }
+
+ /**
+ * Test: retrieving security logs should be rate limited - subsequent attempts should return
+ * null.
+ */
+ public void testRetrievingSecurityLogsNotPossibleImmediatelyAfterPreviousSuccessfulRetrieval() {
+ List<SecurityEvent> logs = mDevicePolicyManager.retrieveSecurityLogs(getWho());
+ // if logs is null it means that that attempt was rate limited => test PASS
+ if (logs != null) {
+ assertNull(mDevicePolicyManager.retrieveSecurityLogs(getWho()));
+ assertNull(mDevicePolicyManager.retrieveSecurityLogs(getWho()));
+ }
+ }
+}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
index 6a22a5c..5fe6fb7 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
@@ -291,27 +291,27 @@
}
}
- public void testDeviceLoggingWithTwoUsers() throws Exception {
+ public void testSecurityLoggingWithTwoUsers() throws Exception {
if (!mHasFeature || getMaxNumberOfUsersSupported() < 2) {
return;
}
int userId = -1;
try {
userId = createUser();
- executeDeviceTestMethod(".DeviceLoggingTest",
- "testSetDeviceLoggingEnabledNotPossibleIfMoreThanOneUserPresent");
- executeDeviceTestMethod(".DeviceLoggingTest",
- "testRetrievingDeviceLogsNotPossibleIfMoreThanOneUserPresent");
- executeDeviceTestMethod(".DeviceLoggingTest",
- "testRetrievingPreviousDeviceLogsNotPossibleIfMoreThanOneUserPresent");
+ executeDeviceTestMethod(".SecurityLoggingTest",
+ "testSetSecurityLoggingEnabledNotPossibleIfMoreThanOneUserPresent");
+ executeDeviceTestMethod(".SecurityLoggingTest",
+ "testRetrievingSecurityLogsNotPossibleIfMoreThanOneUserPresent");
+ executeDeviceTestMethod(".SecurityLoggingTest",
+ "testRetrievingPreviousSecurityLogsNotPossibleIfMoreThanOneUserPresent");
} finally {
removeUser(userId);
}
}
- public void testDeviceLoggingWithSingleUser() throws Exception {
- executeDeviceTestMethod(".DeviceLoggingTest",
- "testRetrievingDeviceLogsNotPossibleImmediatelyAfterPreviousSuccessfulRetrieval");
+ public void testSecurityLoggingWithSingleUser() throws Exception {
+ executeDeviceTestMethod(".SecurityLoggingTest",
+ "testRetrievingSecurityLogsNotPossibleImmediatelyAfterPreviousSuccessfulRetrieval");
}
public void testLockTask() throws Exception {
@@ -357,6 +357,14 @@
}
}
+ // Execute HardwarePropertiesManagerTest as a device owner.
+ public void testHardwarePropertiesManagerAsDeviceOwner() throws Exception {
+ if (!mHasFeature)
+ return;
+
+ executeDeviceTestMethod(".HardwarePropertiesManagerTest", "testHardwarePropertiesManager");
+ }
+
private void executeDeviceOwnerTest(String testClassName) throws Exception {
if (!mHasFeature) {
return;
diff --git a/hostsidetests/net/AndroidTest.xml b/hostsidetests/net/AndroidTest.xml
index 4b6994a..9945805 100644
--- a/hostsidetests/net/AndroidTest.xml
+++ b/hostsidetests/net/AndroidTest.xml
@@ -16,5 +16,6 @@
<configuration description="Config for CTS net host test cases">
<test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
<option name="jar" value="CtsHostsideNetworkTests.jar" />
+ <option name="runtime-hint" value="3m56s" />
</test>
</configuration>
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
index def3439..adaaf84 100644
--- a/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
@@ -221,7 +221,7 @@
if (result.equals(expectedResult))
return;
Log.v(TAG, "Command '" + command + "' returned '" + result + " instead of '"
- + expectedResult + "' on attempt #; sleeping 1s before polling again");
+ + expectedResult + "' on attempt #" + i + "; sleeping 1s before trying again");
Thread.sleep(SECOND_IN_MS);
}
fail("Command '" + command + "' did not return '" + expectedResult + "' after " + maxTries
@@ -253,13 +253,12 @@
Log.i(TAG, "Setting wi-fi network " + netId + " metered status to " + metered);
final String setCommand = "cmd netpolicy set metered-network " + netId + " " + metered;
- final String result = executeShellCommand(setCommand);
- assertTrue("Command '" + setCommand + "' failed: " + result, result.isEmpty());
+ assertDelayedShellCommand(setCommand, "");
// Sanity check.
- final String newStatus = executeShellCommand("cmd netpolicy get metered-network " + netId);
- assertEquals("Metered status of wi-fi network " + netId + " not set properly",
- newStatus.trim(), Boolean.toString(metered));
+ final String getCommand = "cmd netpolicy get metered-network " + netId;
+ assertDelayedShellCommand(getCommand, Boolean.toString(metered));
+
return netId;
}
diff --git a/hostsidetests/services/activitymanager/AndroidTest.xml b/hostsidetests/services/activitymanager/AndroidTest.xml
index ce407a3..641fa09 100644
--- a/hostsidetests/services/activitymanager/AndroidTest.xml
+++ b/hostsidetests/services/activitymanager/AndroidTest.xml
@@ -20,5 +20,6 @@
</target_preparer>
<test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
<option name="jar" value="CtsServicesHostTestCases.jar" />
+ <option name="runtime-hint" value="4m7s" />
</test>
</configuration>
diff --git a/hostsidetests/services/activitymanager/app/AndroidManifest.xml b/hostsidetests/services/activitymanager/app/AndroidManifest.xml
index 8a2a448..39fb19f 100755
--- a/hostsidetests/services/activitymanager/app/AndroidManifest.xml
+++ b/hostsidetests/services/activitymanager/app/AndroidManifest.xml
@@ -24,6 +24,10 @@
android:resizeableActivity="true"
android:exported="true"
/>
+ <activity android:name=".NonResizeableActivity"
+ android:resizeableActivity="false"
+ android:exported="true"
+ />
<activity android:name=".DockedActivity"
android:resizeableActivity="true"
android:exported="true"
diff --git a/hostsidetests/services/activitymanager/app/src/android/server/app/NonResizeableActivity.java b/hostsidetests/services/activitymanager/app/src/android/server/app/NonResizeableActivity.java
new file mode 100644
index 0000000..6312b47
--- /dev/null
+++ b/hostsidetests/services/activitymanager/app/src/android/server/app/NonResizeableActivity.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2016 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 android.server.app;
+
+public class NonResizeableActivity extends AbstractLifecycleLogActivity {
+
+ private static final String TAG = NonResizeableActivity.class.getSimpleName();
+
+ @Override
+ protected String getTag() {
+ return TAG;
+ }
+}
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityAndWindowManagersState.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityAndWindowManagersState.java
index e74ecdf..63e1dbe 100644
--- a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityAndWindowManagersState.java
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityAndWindowManagersState.java
@@ -61,6 +61,9 @@
retry = false;
}
} while (retry && retriesLeft-- > 0);
+
+ assertSanity();
+ assertValidBounds();
}
private boolean shouldRetry(String[] waitForActivitiesVisible) {
@@ -114,7 +117,7 @@
assertTrue(msg, mWmState.containsStack(stackId));
}
- void assertDoesNotContainsStack(String msg, int stackId) throws Exception {
+ void assertDoesNotContainStack(String msg, int stackId) throws Exception {
assertFalse(msg, mAmState.containsStack(stackId));
assertFalse(msg, mWmState.containsStack(stackId));
}
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerActivityVisiblityTests.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerActivityVisiblityTests.java
index e077f7e..877e53b 100644
--- a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerActivityVisiblityTests.java
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerActivityVisiblityTests.java
@@ -32,7 +32,6 @@
mDevice.executeShellCommand(AM_START_HOME_ACTIVITY_COMMAND);
mAmWmState.computeState(mDevice, new String[] {VISIBLE_BEHIND_ACTIVITY});
- mAmWmState.assertSanity();
mAmWmState.assertContainsStack(
"Must contain fullscreen stack.", FULLSCREEN_WORKSPACE_STACK_ID);
mAmWmState.assertFrontStack("Home stack must be the front stack.", HOME_STACK_ID);
@@ -46,7 +45,6 @@
mAmWmState.computeState(mDevice,
new String[] {VISIBLE_BEHIND_ACTIVITY, TRANSLUCENT_ACTIVITY});
- mAmWmState.assertSanity();
mAmWmState.assertVisibility(VISIBLE_BEHIND_ACTIVITY, true);
mAmWmState.assertVisibility(TRANSLUCENT_ACTIVITY, true);
}
@@ -57,7 +55,6 @@
mAmWmState.computeState(mDevice,
new String[] {VISIBLE_BEHIND_ACTIVITY, TRANSLUCENT_ACTIVITY});
- mAmWmState.assertSanity();
mAmWmState.assertVisibility(VISIBLE_BEHIND_ACTIVITY, true);
mAmWmState.assertVisibility(TRANSLUCENT_ACTIVITY, true);
}
@@ -73,7 +70,6 @@
mDevice.executeShellCommand(AM_MOVE_TOP_ACTIVITY_TO_PINNED_STACK_COMMAND);
mAmWmState.computeState(mDevice, new String[] {PIP_ON_PIP_ACTIVITY, TRANSLUCENT_ACTIVITY});
- mAmWmState.assertSanity();
mAmWmState.assertFrontStack("Pinned stack must be the front stack.", PINNED_STACK_ID);
mAmWmState.assertVisibility(PIP_ON_PIP_ACTIVITY, true);
mAmWmState.assertVisibility(TRANSLUCENT_ACTIVITY, true);
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerDockedStackTests.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerDockedStackTests.java
index 840fb7f..58a7ae6 100644
--- a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerDockedStackTests.java
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerDockedStackTests.java
@@ -17,12 +17,14 @@
package android.server.cts;
import java.awt.Rectangle;
+import java.util.ArrayList;
import static com.android.ddmlib.Log.LogLevel.*;
public class ActivityManagerDockedStackTests extends ActivityManagerTestBase {
private static final String TEST_ACTIVITY_NAME = "TestActivity";
+ private static final String NON_RESIZEABLE_ACTIVITY_NAME = "NonResizeableActivity";
private static final String DOCKED_ACTIVITY_NAME = "DockedActivity";
private static final String LAUNCH_TO_SIDE_ACTIVITY_NAME = "LaunchToSideActivity";
private static final String NO_RELAUNCH_ACTIVITY_NAME = "NoRelaunchActivity";
@@ -30,31 +32,38 @@
private static final int TASK_SIZE = 600;
private static final int STACK_SIZE = 300;
- // TODO: Add test for non-resizeable activity.
-
public void testStackList() throws Exception {
mDevice.executeShellCommand(getAmStartCmd(TEST_ACTIVITY_NAME));
mAmWmState.computeState(mDevice, new String[] {TEST_ACTIVITY_NAME});
- mAmWmState.assertSanity();
mAmWmState.assertContainsStack("Must contain home stack.", HOME_STACK_ID);
mAmWmState.assertContainsStack(
"Must contain fullscreen stack.", FULLSCREEN_WORKSPACE_STACK_ID);
+ mAmWmState.assertDoesNotContainStack("Must not contain docked stack.", DOCKED_STACK_ID);
}
public void testDockActivity() throws Exception {
launchActivityInDockStack(TEST_ACTIVITY_NAME);
mAmWmState.computeState(mDevice, new String[] {TEST_ACTIVITY_NAME});
- mAmWmState.assertSanity();
mAmWmState.assertContainsStack("Must contain home stack.", HOME_STACK_ID);
mAmWmState.assertContainsStack("Must contain docked stack.", DOCKED_STACK_ID);
}
+ public void testNonResizeableNotDocked() throws Exception {
+ launchActivityInDockStack(NON_RESIZEABLE_ACTIVITY_NAME);
+ mAmWmState.computeState(mDevice, new String[] {NON_RESIZEABLE_ACTIVITY_NAME});
+
+ mAmWmState.assertContainsStack("Must contain home stack.", HOME_STACK_ID);
+ mAmWmState.assertDoesNotContainStack("Must not contain docked stack.", DOCKED_STACK_ID);
+ mAmWmState.assertFrontStack(
+ "Fullscreen stack must be front stack.", FULLSCREEN_WORKSPACE_STACK_ID);
+ }
+
public void testLaunchToSide() throws Exception {
launchActivityInDockStack(LAUNCH_TO_SIDE_ACTIVITY_NAME);
printStacksAndTasks();
launchActivityToSide(LAUNCH_TO_SIDE_ACTIVITY_NAME);
mAmWmState.computeState(mDevice, new String[] {LAUNCH_TO_SIDE_ACTIVITY_NAME});
- mAmWmState.assertSanity();
+
mAmWmState.assertContainsStack(
"Must contain fullscreen stack.", FULLSCREEN_WORKSPACE_STACK_ID);
mAmWmState.assertContainsStack("Must contain docked stack.", DOCKED_STACK_ID);
@@ -65,41 +74,32 @@
launchActivityToSide(LAUNCH_TO_SIDE_ACTIVITY_NAME);
final String[] waitForActivitiesVisible = new String[] {LAUNCH_TO_SIDE_ACTIVITY_NAME};
mAmWmState.computeState(mDevice, waitForActivitiesVisible);
- mAmWmState.assertSanity();
mAmWmState.assertContainsStack(
"Must contain fullscreen stack.", FULLSCREEN_WORKSPACE_STACK_ID);
mAmWmState.assertContainsStack("Must contain docked stack.", DOCKED_STACK_ID);
- // Rotate device single steps (90°) 0-1-2-3
+ // Rotate device single steps (90°) 0-1-2-3.
+ // Each time we compute the state we implicitly assert valid bounds.
setDeviceRotation(0);
mAmWmState.computeState(mDevice, waitForActivitiesVisible);
- mAmWmState.assertValidBounds();
setDeviceRotation(1);
mAmWmState.computeState(mDevice, waitForActivitiesVisible);
- mAmWmState.assertValidBounds();
setDeviceRotation(2);
mAmWmState.computeState(mDevice, waitForActivitiesVisible);
- mAmWmState.assertValidBounds();
setDeviceRotation(3);
mAmWmState.computeState(mDevice, waitForActivitiesVisible);
- mAmWmState.assertValidBounds();
// Double steps (180°) We ended the single step at 3. So, we jump directly to 1 for double
// step. So, we are testing 3-1-3 for one side and 0-2-0 for the other side.
setDeviceRotation(1);
mAmWmState.computeState(mDevice, waitForActivitiesVisible);
- mAmWmState.assertValidBounds();
setDeviceRotation(3);
mAmWmState.computeState(mDevice, waitForActivitiesVisible);
- mAmWmState.assertValidBounds();
setDeviceRotation(0);
mAmWmState.computeState(mDevice, waitForActivitiesVisible);
- mAmWmState.assertValidBounds();
setDeviceRotation(2);
mAmWmState.computeState(mDevice, waitForActivitiesVisible);
- mAmWmState.assertValidBounds();
setDeviceRotation(0);
mAmWmState.computeState(mDevice, waitForActivitiesVisible);
- mAmWmState.assertValidBounds();
}
public void testRotationWhenDockedWhileLocked() throws Exception {
@@ -116,25 +116,21 @@
setDeviceRotation(0);
unlockDevice();
mAmWmState.computeState(mDevice, waitForActivitiesVisible);
- mAmWmState.assertValidBounds();
lockDevice();
setDeviceRotation(1);
unlockDevice();
mAmWmState.computeState(mDevice, waitForActivitiesVisible);
- mAmWmState.assertValidBounds();
lockDevice();
setDeviceRotation(2);
unlockDevice();
mAmWmState.computeState(mDevice, waitForActivitiesVisible);
- mAmWmState.assertValidBounds();
lockDevice();
setDeviceRotation(3);
unlockDevice();
mAmWmState.computeState(mDevice, waitForActivitiesVisible);
- mAmWmState.assertValidBounds();
}
public void testResizeDockedStack() throws Exception {
@@ -142,7 +138,6 @@
launchActivityInDockStack(DOCKED_ACTIVITY_NAME);
resizeDockedStack(STACK_SIZE, STACK_SIZE, TASK_SIZE, TASK_SIZE);
mAmWmState.computeState(mDevice, new String[] {TEST_ACTIVITY_NAME, DOCKED_ACTIVITY_NAME});
- mAmWmState.assertSanity();
mAmWmState.assertContainsStack("Must contain docked stack", DOCKED_STACK_ID);
mAmWmState.assertContainsStack("Must contain fullscreen stack",
FULLSCREEN_WORKSPACE_STACK_ID);
@@ -164,7 +159,6 @@
mAmWmState.computeState(mDevice,
new String[]{TEST_ACTIVITY_NAME, NO_RELAUNCH_ACTIVITY_NAME});
- mAmWmState.assertSanity();
final Rectangle initialDockBounds =
mAmWmState.getWmState().getStack(DOCKED_STACK_ID).getBounds();
@@ -180,7 +174,6 @@
mAmWmState.computeState(mDevice,
new String[]{TEST_ACTIVITY_NAME, NO_RELAUNCH_ACTIVITY_NAME});
- mAmWmState.assertSanity();
assertActivityLifecycle(TEST_ACTIVITY_NAME, true);
assertActivityLifecycle(NO_RELAUNCH_ACTIVITY_NAME, false);
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerFreeformStackTests.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerFreeformStackTests.java
index 786e8e1..f86d9ec 100644
--- a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerFreeformStackTests.java
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerFreeformStackTests.java
@@ -17,6 +17,7 @@
package android.server.cts;
import java.awt.Rectangle;
+import java.util.ArrayList;
public class ActivityManagerFreeformStackTests extends ActivityManagerTestBase {
@@ -28,6 +29,7 @@
// NOTE: Launching the FreeformActivity will automatically launch the TestActivity
// with bounds (0, 0, 500, 500)
private static final String FREEFORM_ACTIVITY = "FreeformActivity";
+ private static final String NON_RESIZEABLE_ACTIVITY = "NonResizeableActivity";
private static final String NO_RELAUNCH_ACTIVITY = "NoRelaunchActivity";
public void testFreeformWindowManagementSupport() throws Exception {
@@ -35,11 +37,9 @@
launchActivityInStack(FREEFORM_ACTIVITY, FREEFORM_WORKSPACE_STACK_ID);
mAmWmState.computeState(mDevice, new String[] {FREEFORM_ACTIVITY});
- mAmWmState.assertSanity();
- mAmWmState.assertValidBounds();
if (!supportsFreeform()) {
- mAmWmState.assertDoesNotContainsStack(
+ mAmWmState.assertDoesNotContainStack(
"Must not contain freeform stack.", FREEFORM_WORKSPACE_STACK_ID);
return;
}
@@ -54,15 +54,25 @@
mAmWmState.getAmState().getTaskByActivityName(TEST_ACTIVITY).getBounds());
}
+ public void testNonResizeableActivityNotLaunchedToFreeform() throws Exception {
+ launchActivityInStack(NON_RESIZEABLE_ACTIVITY, FREEFORM_WORKSPACE_STACK_ID);
+
+ mAmWmState.computeState(mDevice, new String[] {NON_RESIZEABLE_ACTIVITY});
+
+ mAmWmState.assertFrontStack(
+ "Fullscreen stack must be the front stack.", FULLSCREEN_WORKSPACE_STACK_ID);
+ mAmWmState.assertDoesNotContainStack(
+ "Must not contain freeform stack.", FREEFORM_WORKSPACE_STACK_ID);
+ }
+
public void testActivityLifeCycleOnResizeFreeformTask() throws Exception {
launchActivityInStack(TEST_ACTIVITY, FREEFORM_WORKSPACE_STACK_ID);
launchActivityInStack(NO_RELAUNCH_ACTIVITY, FREEFORM_WORKSPACE_STACK_ID);
mAmWmState.computeState(mDevice, new String[]{TEST_ACTIVITY, NO_RELAUNCH_ACTIVITY});
- mAmWmState.assertSanity();
if (!supportsFreeform()) {
- mAmWmState.assertDoesNotContainsStack(
+ mAmWmState.assertDoesNotContainStack(
"Must not contain freeform stack.", FREEFORM_WORKSPACE_STACK_ID);
return;
}
@@ -73,7 +83,6 @@
TEST_TASK_OFFSET_2, TEST_TASK_OFFSET_2, TEST_TASK_SIZE_1, TEST_TASK_SIZE_2);
mAmWmState.computeState(mDevice, new String[]{TEST_ACTIVITY, NO_RELAUNCH_ACTIVITY});
- mAmWmState.assertSanity();
clearLogcat();
resizeActivityTask(TEST_ACTIVITY,
@@ -81,7 +90,6 @@
resizeActivityTask(NO_RELAUNCH_ACTIVITY,
TEST_TASK_OFFSET_2, TEST_TASK_OFFSET_2, TEST_TASK_SIZE_2, TEST_TASK_SIZE_1);
mAmWmState.computeState(mDevice, new String[]{TEST_ACTIVITY, NO_RELAUNCH_ACTIVITY});
- mAmWmState.assertSanity();
assertActivityLifecycle(TEST_ACTIVITY, true);
assertActivityLifecycle(NO_RELAUNCH_ACTIVITY, false);
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerManifestLayoutTests.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerManifestLayoutTests.java
index bae3c6e..f0008eb 100644
--- a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerManifestLayoutTests.java
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerManifestLayoutTests.java
@@ -146,8 +146,6 @@
mAmWmState.computeState(mDevice, true /* visibleOnly */, new String[] {activityName});
- mAmWmState.assertSanity();
-
mAmWmState.assertFocusedWindow("Test window must be the front window.", windowName);
mAmWmState.getWmState().getMatchingWindowState(windowName, mTempWindowList);
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerPinnedStackTests.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerPinnedStackTests.java
index 4250404..c57b648 100644
--- a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerPinnedStackTests.java
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerPinnedStackTests.java
@@ -52,8 +52,6 @@
}
mAmWmState.computeState(mDevice, new String[] {topActiviyName});
- mAmWmState.assertSanity();
- mAmWmState.assertValidBounds();
if (supportsPip()) {
final String windowName = getWindowName(topActiviyName);
@@ -81,7 +79,7 @@
"Pinned window can't be focused window.", windowName);
}
} else {
- mAmWmState.assertDoesNotContainsStack(
+ mAmWmState.assertDoesNotContainStack(
"Must not contain pinned stack.", PINNED_STACK_ID);
}
}
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerReplaceWindowTests.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerReplaceWindowTests.java
index 298a759..624128b 100644
--- a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerReplaceWindowTests.java
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerReplaceWindowTests.java
@@ -86,8 +86,6 @@
throws Exception {
mAmWmState.computeState(mDevice, visibleOnly, new String[] {activityName});
- mAmWmState.assertSanity();
-
mAmWmState.assertFocusedWindow("Test window must be the front window.",
windowName);
diff --git a/hostsidetests/systemui/Android.mk b/hostsidetests/systemui/Android.mk
index 1c0dd06..41f05ef 100644
--- a/hostsidetests/systemui/Android.mk
+++ b/hostsidetests/systemui/Android.mk
@@ -28,6 +28,8 @@
LOCAL_CTS_TEST_PACKAGE := android.host.systemui
+LOCAL_CTS_MODULE_CONFIG := $(LOCAL_PATH)/Old$(CTS_MODULE_TEST_CONFIG)
+
LOCAL_SDK_VERSION := current
# Tag this module as a cts test artifact
diff --git a/hostsidetests/systemui/OldAndroidTest.xml b/hostsidetests/systemui/OldAndroidTest.xml
new file mode 100644
index 0000000..2efcb94
--- /dev/null
+++ b/hostsidetests/systemui/OldAndroidTest.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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="Config for CTS System UI host test cases">
+
+ <include name="common-config" />
+ <!-- This will tell tradefed to install the test apk. -->
+ <option name="cts-apk-installer:test-file-name" value="CtsSystemUiDeviceApp.apk" />
+</configuration>
diff --git a/hostsidetests/theme/AndroidTest.xml b/hostsidetests/theme/AndroidTest.xml
index 516df3d..50418ec 100644
--- a/hostsidetests/theme/AndroidTest.xml
+++ b/hostsidetests/theme/AndroidTest.xml
@@ -20,5 +20,6 @@
</target_preparer>
<test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
<option name="jar" value="CtsThemeHostTestCases.jar" />
+ <option name="runtime-hint" value="5h2m34s" />
</test>
</configuration>
diff --git a/tests/accessibilityservice/AndroidTest.xml b/tests/accessibilityservice/AndroidTest.xml
index 1287524..fe261dc 100644
--- a/tests/accessibilityservice/AndroidTest.xml
+++ b/tests/accessibilityservice/AndroidTest.xml
@@ -20,5 +20,6 @@
</target_preparer>
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.accessibilityservice.cts" />
+ <option name="runtime-hint" value="2m12s" />
</test>
</configuration>
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDispatchTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDispatchTest.java
index 2a17486..52af854 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDispatchTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDispatchTest.java
@@ -17,16 +17,19 @@
import android.accessibilityservice.AccessibilityService;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.accessibilityservice.GestureDescription;
+import android.accessibilityservice.GestureDescription.Builder;
+import android.accessibilityservice.GestureDescription.StrokeDescription;
import android.app.UiAutomation;
import android.content.ContentResolver;
import android.content.Context;
+import android.graphics.Matrix;
+import android.graphics.Path;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.os.SystemClock;
import android.provider.Settings;
import android.test.ActivityInstrumentationTestCase2;
-import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
@@ -96,7 +99,7 @@
final int clickYInsideView = 20;
int clickX = clickXInsideView + mViewBounds.left;
int clickY = clickYInsideView + mViewBounds.top;
- GestureDescription click = GestureDescription.createClick(clickX, clickY);
+ GestureDescription click = createClick(clickX, clickY);
assertTrue(StubGestureAccessibilityService.sConnectedInstance
.doDispatchGesture(click, mCallback, null));
mCallback.assertGestureCompletes(GESTURE_COMPLETION_TIMEOUT);
@@ -144,7 +147,7 @@
final int clickYInsideView = 20;
int clickX = clickXInsideView + mViewBounds.left;
int clickY = clickYInsideView + mViewBounds.top;
- GestureDescription longClick = GestureDescription.createLongClick(clickX, clickY);
+ GestureDescription longClick = createLongClick(clickX, clickY);
assertTrue(StubGestureAccessibilityService.sConnectedInstance
.doDispatchGesture(longClick, mCallback, null));
mCallback.assertGestureCompletes(
@@ -186,8 +189,7 @@
int gestureTime = 500;
float swipeTolerance = 2.0f;
- GestureDescription swipe = GestureDescription
- .createSwipe(startX, startY, endX, endY, gestureTime);
+ GestureDescription swipe = createSwipe(startX, startY, endX, endY, gestureTime);
assertTrue(StubGestureAccessibilityService.sConnectedInstance
.doDispatchGesture(swipe, mCallback, null));
mCallback.assertGestureCompletes(gestureTime + GESTURE_COMPLETION_TIMEOUT);
@@ -231,8 +233,7 @@
int endY = endYInsideView + mViewBounds.top;
int gestureTime = 1000;
- GestureDescription swipe = GestureDescription
- .createSwipe(startX, startY, endX, endY, gestureTime);
+ GestureDescription swipe = createSwipe(startX, startY, endX, endY, gestureTime);
assertTrue(StubGestureAccessibilityService.sConnectedInstance
.doDispatchGesture(swipe, mCallback, null));
mCallback.assertGestureCompletes(gestureTime + GESTURE_COMPLETION_TIMEOUT);
@@ -269,7 +270,7 @@
int gestureTime = 500;
float pinchTolerance = 2.0f;
- GestureDescription pinch = GestureDescription.createPinch(centerX, centerY, startSpacing,
+ GestureDescription pinch = createPinch(centerX, centerY, startSpacing,
endSpacing, 45.0F, gestureTime);
assertTrue(StubGestureAccessibilityService.sConnectedInstance
.doDispatchGesture(pinch, mCallback, null));
@@ -481,4 +482,84 @@
}
}
}
+
+ private GestureDescription createClick(int x, int y) {
+ Path clickPath = new Path();
+ clickPath.moveTo(x, y);
+ clickPath.lineTo(x + 1, y);
+ GestureDescription.StrokeDescription clickStroke =
+ new GestureDescription.StrokeDescription(clickPath, 0, ViewConfiguration.getTapTimeout());
+ GestureDescription.Builder clickBuilder = new GestureDescription.Builder();
+ clickBuilder.addStroke(clickStroke);
+ return clickBuilder.build();
+ }
+
+ private GestureDescription createLongClick(int x, int y) {
+ Path clickPath = new Path();
+ clickPath.moveTo(x, y);
+ clickPath.lineTo(x + 1, y);
+ int longPressTime = ViewConfiguration.getLongPressTimeout();
+
+ GestureDescription.StrokeDescription longClickStroke =
+ new GestureDescription.StrokeDescription(clickPath, 0, longPressTime + (longPressTime / 2));
+ GestureDescription.Builder longClickBuilder = new GestureDescription.Builder();
+ longClickBuilder.addStroke(longClickStroke);
+ return longClickBuilder.build();
+ }
+
+ private GestureDescription createSwipe(
+ int startX, int startY, int endX, int endY, long duration) {
+ Path swipePath = new Path();
+ swipePath.moveTo(startX, startY);
+ swipePath.lineTo(endX, endY);
+
+ GestureDescription.StrokeDescription swipeStroke = new GestureDescription.StrokeDescription(swipePath, 0, duration);
+ GestureDescription.Builder swipeBuilder = new GestureDescription.Builder();
+ swipeBuilder.addStroke(swipeStroke);
+ return swipeBuilder.build();
+ }
+
+ private GestureDescription createPinch(int centerX, int centerY, int startSpacing,
+ int endSpacing, float orientation, long duration) {
+ if ((startSpacing < 0) || (endSpacing < 0)) {
+ throw new IllegalArgumentException("Pinch spacing cannot be negative");
+ }
+ float[] startPoint1 = new float[2];
+ float[] endPoint1 = new float[2];
+ float[] startPoint2 = new float[2];
+ float[] endPoint2 = new float[2];
+
+ /* Build points for a horizontal gesture centered at the origin */
+ startPoint1[0] = startSpacing / 2;
+ startPoint1[1] = 0;
+ endPoint1[0] = endSpacing / 2;
+ endPoint1[1] = 0;
+ startPoint2[0] = -startSpacing / 2;
+ startPoint2[1] = 0;
+ endPoint2[0] = -endSpacing / 2;
+ endPoint2[1] = 0;
+
+ /* Rotate and translate the points */
+ Matrix matrix = new Matrix();
+ matrix.setRotate(orientation);
+ matrix.postTranslate(centerX, centerY);
+ matrix.mapPoints(startPoint1);
+ matrix.mapPoints(endPoint1);
+ matrix.mapPoints(startPoint2);
+ matrix.mapPoints(endPoint2);
+
+ Path path1 = new Path();
+ path1.moveTo(startPoint1[0], startPoint1[1]);
+ path1.lineTo(endPoint1[0], endPoint1[1]);
+ Path path2 = new Path();
+ path2.moveTo(startPoint2[0], startPoint2[1]);
+ path2.lineTo(endPoint2[0], endPoint2[1]);
+
+ GestureDescription.StrokeDescription path1Stroke = new GestureDescription.StrokeDescription(path1, 0, duration);
+ GestureDescription.StrokeDescription path2Stroke = new GestureDescription.StrokeDescription(path2, 0, duration);
+ GestureDescription.Builder swipeBuilder = new GestureDescription.Builder();
+ swipeBuilder.addStroke(path1Stroke);
+ swipeBuilder.addStroke(path2Stroke);
+ return swipeBuilder.build();
+ }
}
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/GestureDescriptionTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/GestureDescriptionTest.java
index b696cba..b3fa9d2 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/GestureDescriptionTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/GestureDescriptionTest.java
@@ -119,7 +119,7 @@
public void testAddStroke_allowUpToMaxPaths() {
GestureDescription.Builder gestureBuilder = new GestureDescription.Builder();
- for (int i = 0; i < GestureDescription.MAX_STROKE_COUNT; i++) {
+ for (int i = 0; i < GestureDescription.getMaxStrokeCount(); i++) {
Path path = new Path();
path.moveTo(i, i);
path.lineTo(10 + i, 10 + i);
@@ -144,7 +144,7 @@
GestureDescription.Builder gestureBuilder = new GestureDescription.Builder();
try {
gestureBuilder.addStroke(new GestureDescription.StrokeDescription(
- path, 0, GestureDescription.MAX_GESTURE_DURATION_MS + 1));
+ path, 0, GestureDescription.getMaxGestureDuration() + 1));
fail("Missing exception for adding stroke with duration too long.");
} catch (RuntimeException e) {
}
@@ -159,151 +159,6 @@
}
}
-
- public void testClickAt_negativeX_shouldThrow() {
- try {
- GestureDescription.createClick(-1, 0);
- fail("Missing exception for clicking at negative x coordinate.");
- } catch (IllegalArgumentException e) {
- }
- }
-
- public void testClickAt_negativeY_shouldThrow() {
- try {
- GestureDescription.createClick(0, -1);
- fail("Missing exception for clicking at negative y coordinate.");
- } catch (IllegalArgumentException e) {
- }
- }
-
- public void testLongClickAt_negativeX_shouldThrow() {
- try {
- GestureDescription.createLongClick(-1, 0);
- fail("Missing exception for long clicking at negative x coordinate.");
- } catch (IllegalArgumentException e) {
- }
- }
-
- public void testLongClickAt_negativeY_shouldThrow() {
- try {
- GestureDescription.createLongClick(0, -1);
- fail("Missing exception for long clicking at negative y coordinate.");
- } catch (IllegalArgumentException e) {
- }
- }
-
- public void testZeroDurationSwipe_shouldThrow() {
- try {
- GestureDescription.createSwipe(0, 0, 100, 100, 0);
- fail("Missing exception for creating zero duration swipe.");
- } catch (IllegalArgumentException e) {
- }
- }
-
- public void testNegativeDurationSwipe_shouldThrow() {
- try {
- GestureDescription.createSwipe(0, 0, 100, 100, -1);
- fail("Missing exception for creating negative duration swipe.");
- } catch (IllegalArgumentException e) {
- }
- }
-
- public void testZeroLengthSwipe_shouldThrow() {
- try {
- GestureDescription.createSwipe(0, 0, 0, 0, 10);
- fail("Missing exception for creating zero-length swipe.");
- } catch (IllegalArgumentException e) {
- }
- }
-
- public void testSwipe_negativeStartX_shouldThrow() {
- try {
- GestureDescription.createSwipe(-1, 0, 0, 0, 10);
- fail("Missing exception for creating swipe with negative starting x.");
- } catch (IllegalArgumentException e) {
- }
- }
-
- public void testSwipe_negativeStartY_shouldThrow() {
- try {
- GestureDescription.createSwipe(0, -1, 0, 0, 10);
- fail("Missing exception for creating swipe with negative starting y.");
- } catch (IllegalArgumentException e) {
- }
- }
-
- public void testSwipe_negativeEndX_shouldThrow() {
- try {
- GestureDescription.createSwipe(0, 0, -1, 0, 10);
- fail("Missing exception for creating swipe with negative ending x.");
- } catch (IllegalArgumentException e) {
- }
- }
-
- public void testSwipe_negativeEndY_shouldThrow() {
- try {
- GestureDescription.createSwipe(0, 0, 0, -1, 10);
- fail("Missing exception for creating swipe with negative ending y.");
- } catch (IllegalArgumentException e) {
- }
- }
-
- public void testZeroDurationPinch_shouldBeNull() {
- try {
- GestureDescription.createPinch(100, 100, 50, 75, 0, 0);
- fail("Missing exception for creating pinch with zero duration.");
- } catch (IllegalArgumentException e) {
- }
- }
-
- public void testNegativeDurationPinch_shouldBeNull() {
- try {
- GestureDescription.createPinch(100, 100, 50, 75, 0, -1);
- fail("Missing exception for creating pinch with negative duration.");
- } catch (IllegalArgumentException e) {
- }
- }
-
- public void testZeroLengthPinch_shouldThrow() {
- try {
- GestureDescription.createPinch(100, 100, 50, 50, 0, 100);
- fail("Missing exception for creating pinch with zero length.");
- } catch (IllegalArgumentException e) {
- }
- }
-
- public void testPinch_negativeCenterX_shouldThrow() {
- try {
- GestureDescription.createPinch(-100, 100, 50, 75, 0, 100);
- fail("Missing exception for creating pinch with negative center x.");
- } catch (IllegalArgumentException e) {
- }
- }
-
- public void testPinch_negativeCenterY_shouldThrow() {
- try {
- GestureDescription.createPinch(100, -100, 50, 75, 0, 100);
- fail("Missing exception for creating pinch with negative center y.");
- } catch (IllegalArgumentException e) {
- }
- }
-
- public void testPinch_negativeStartSpacing_shouldThrow() {
- try {
- GestureDescription.createPinch(100, 100, -50, 75, 0, 100);
- fail("Missing exception for creating pinch with negative start spacing.");
- } catch (IllegalArgumentException e) {
- }
- }
-
- public void testPinch_negativeEndSpacing_shouldThrow() {
- try {
- GestureDescription.createPinch(100, 100, 50, -75, 0, 100);
- fail("Missing exception for creating pinch with negative end spacing.");
- } catch (IllegalArgumentException e) {
- }
- }
-
public void testStrokeDescriptionGetters_workAsExpected() {
int x = 100;
int startY = 100;
diff --git a/tests/admin/Android.mk b/tests/admin/Android.mk
index 7933004..e12cc94 100644
--- a/tests/admin/Android.mk
+++ b/tests/admin/Android.mk
@@ -20,7 +20,8 @@
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner mockito-target
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ ctstestrunner mockito-target platform-test-annotations
LOCAL_SRC_FILES := $(call all-java-files-under, src)
@@ -37,4 +38,4 @@
include $(BUILD_CTS_PACKAGE)
-include $(call all-makefiles-under,$(LOCAL_PATH))
\ No newline at end of file
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/admin/src/android/admin/cts/DeviceAdminReceiverTest.java b/tests/admin/src/android/admin/cts/DeviceAdminReceiverTest.java
index 9b80b33..81ea503 100644
--- a/tests/admin/src/android/admin/cts/DeviceAdminReceiverTest.java
+++ b/tests/admin/src/android/admin/cts/DeviceAdminReceiverTest.java
@@ -20,6 +20,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
+import android.platform.test.annotations.Presubmit;
import android.test.AndroidTestCase;
import android.util.Log;
@@ -62,6 +63,7 @@
mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN);
}
+ @Presubmit
public void testOnReceive() {
if (!mDeviceAdmin) {
Log.w(TAG, "Skipping testOnReceive");
diff --git a/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java b/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java
index 57d22dd..543a385 100644
--- a/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java
+++ b/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java
@@ -122,52 +122,52 @@
}
}
- public void testSetDeviceLoggingEnabled_failIfNotDeviceOwner() {
+ public void testSetSecurityLoggingEnabled_failIfNotDeviceOwner() {
if (!mDeviceAdmin) {
- Log.w(TAG, "Skipping testSetDeviceLoggingEnabled_failIfNotDeviceOwner");
+ Log.w(TAG, "Skipping testSetSecurityLoggingEnabled_failIfNotDeviceOwner");
return;
}
try {
- mDevicePolicyManager.setDeviceLoggingEnabled(mComponent, true);
+ mDevicePolicyManager.setSecurityLoggingEnabled(mComponent, true);
fail("did not throw expected SecurityException");
} catch (SecurityException e) {
assertDeviceOwnerMessage(e.getMessage());
}
}
- public void testGetDeviceLoggingEnabled_failIfNotDeviceOwner() {
+ public void testIsSecurityLoggingEnabled_failIfNotDeviceOwner() {
if (!mDeviceAdmin) {
- Log.w(TAG, "Skipping testGetDeviceLoggingEnabled_failIfNotDeviceOwner");
+ Log.w(TAG, "Skipping testIsSecurityLoggingEnabled_failIfNotDeviceOwner");
return;
}
try {
- mDevicePolicyManager.getDeviceLoggingEnabled(mComponent);
+ mDevicePolicyManager.isSecurityLoggingEnabled(mComponent);
fail("did not throw expected SecurityException");
} catch (SecurityException e) {
assertDeviceOwnerMessage(e.getMessage());
}
}
- public void testRetrieveDeviceLogs_failIfNotDeviceOwner() {
+ public void testRetrieveSecurityLogs_failIfNotDeviceOwner() {
if (!mDeviceAdmin) {
- Log.w(TAG, "Skipping testRetrieveDeviceLogs_failIfNotDeviceOwner");
+ Log.w(TAG, "Skipping testRetrieveSecurityLogs_failIfNotDeviceOwner");
return;
}
try {
- mDevicePolicyManager.retrieveDeviceLogs(mComponent);
+ mDevicePolicyManager.retrieveSecurityLogs(mComponent);
fail("did not throw expected SecurityException");
} catch (SecurityException e) {
assertDeviceOwnerMessage(e.getMessage());
}
}
- public void testRetrievePreviousDeviceLogs_failIfNotDeviceOwner() {
+ public void testRetrievePreRebootSecurityLogs_failIfNotDeviceOwner() {
if (!mDeviceAdmin) {
- Log.w(TAG, "Skipping testRetrievePreviousDeviceLogs_failIfNotDeviceOwner");
+ Log.w(TAG, "Skipping testRetrievePreRebootSecurityLogs_failIfNotDeviceOwner");
return;
}
try {
- mDevicePolicyManager.retrievePreviousDeviceLogs(mComponent);
+ mDevicePolicyManager.retrievePreRebootSecurityLogs(mComponent);
fail("did not throw expected SecurityException");
} catch (SecurityException e) {
assertDeviceOwnerMessage(e.getMessage());
diff --git a/tests/app/AndroidTest.xml b/tests/app/AndroidTest.xml
index acbc9e7..6487bd7 100644
--- a/tests/app/AndroidTest.xml
+++ b/tests/app/AndroidTest.xml
@@ -23,7 +23,7 @@
</target_preparer>
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.app.cts" />
- <option name="runtime-hint" value="3m8s" />
+ <option name="runtime-hint" value="6m38s" />
</test>
</configuration>
diff --git a/tests/camera/src/android/hardware/camera2/cts/AllocationTest.java b/tests/camera/src/android/hardware/camera2/cts/AllocationTest.java
index e6a13ff..2969753 100644
--- a/tests/camera/src/android/hardware/camera2/cts/AllocationTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/AllocationTest.java
@@ -95,8 +95,6 @@
super.setContext(context);
mCameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
assertNotNull("Can't connect to camera manager!", mCameraManager);
-
- RenderScriptSingleton.setContext(context);
}
@Override
@@ -111,6 +109,8 @@
mCameraIterable = new CameraIterable();
mSizeIterable = new SizeIterable();
mResultIterable = new ResultIterable();
+
+ RenderScriptSingleton.setContext(getContext());
}
@Override
@@ -470,15 +470,14 @@
@Override
public void run(final Size size) throws CameraAccessException {
// Create a script graph that converts YUV to RGB
- final ScriptGraph scriptGraph = ScriptGraph.create()
+ try (ScriptGraph scriptGraph = ScriptGraph.create()
.configureInputWithSurface(size, YUV_420_888)
.chainScript(ScriptYuvToRgb.class)
- .buildGraph();
+ .buildGraph()) {
- if (VERBOSE) Log.v(TAG, "Prepared ScriptYuvToRgb for size " + size);
+ if (VERBOSE) Log.v(TAG, "Prepared ScriptYuvToRgb for size " + size);
- // Run the graph against camera input and validate we get some input
- try {
+ // Run the graph against camera input and validate we get some input
CaptureRequest request =
configureAndCreateRequestForSurface(scriptGraph.getInputSurface()).build();
@@ -495,8 +494,6 @@
});
stopCapture();
- } finally {
- scriptGraph.close();
}
}
});
@@ -536,36 +533,37 @@
final Size maxSize = getMaxSize(
getSupportedSizeForFormat(YUV_420_888, camera.getId(), mCameraManager));
- ScriptGraph scriptGraph = createGraphForYuvCroppedMeans(maxSize);
+ try (ScriptGraph scriptGraph = createGraphForYuvCroppedMeans(maxSize)) {
- CaptureRequest.Builder req =
- configureAndCreateRequestForSurface(scriptGraph.getInputSurface());
+ CaptureRequest.Builder req =
+ configureAndCreateRequestForSurface(scriptGraph.getInputSurface());
- // Take a shot with very low ISO and exposure time. Expect it to be black.
- int minimumSensitivity = staticInfo.getSensitivityMinimumOrDefault();
- long minimumExposure = staticInfo.getExposureMinimumOrDefault();
- setManualCaptureRequest(req, minimumSensitivity, minimumExposure);
+ // Take a shot with very low ISO and exposure time. Expect it to be black.
+ int minimumSensitivity = staticInfo.getSensitivityMinimumOrDefault();
+ long minimumExposure = staticInfo.getExposureMinimumOrDefault();
+ setManualCaptureRequest(req, minimumSensitivity, minimumExposure);
- CaptureRequest lowIsoExposureShot = req.build();
- captureSingleShotAndExecute(lowIsoExposureShot, scriptGraph);
+ CaptureRequest lowIsoExposureShot = req.build();
+ captureSingleShotAndExecute(lowIsoExposureShot, scriptGraph);
- float[] blackMeans = convertPixelYuvToRgb(scriptGraph.getOutputData());
+ float[] blackMeans = convertPixelYuvToRgb(scriptGraph.getOutputData());
- // Take a shot with very high ISO and exposure time. Expect it to be white.
- int maximumSensitivity = staticInfo.getSensitivityMaximumOrDefault();
- long maximumExposure = staticInfo.getExposureMaximumOrDefault();
- setManualCaptureRequest(req, maximumSensitivity, maximumExposure);
+ // Take a shot with very high ISO and exposure time. Expect it to be white.
+ int maximumSensitivity = staticInfo.getSensitivityMaximumOrDefault();
+ long maximumExposure = staticInfo.getExposureMaximumOrDefault();
+ setManualCaptureRequest(req, maximumSensitivity, maximumExposure);
- CaptureRequest highIsoExposureShot = req.build();
- captureSingleShotAndExecute(highIsoExposureShot, scriptGraph);
+ CaptureRequest highIsoExposureShot = req.build();
+ captureSingleShotAndExecute(highIsoExposureShot, scriptGraph);
- float[] whiteMeans = convertPixelYuvToRgb(scriptGraph.getOutputData());
+ float[] whiteMeans = convertPixelYuvToRgb(scriptGraph.getOutputData());
- // low iso + low exposure (first shot)
- assertArrayWithinUpperBound("Black means too high", blackMeans, THRESHOLD_LOW);
+ // low iso + low exposure (first shot)
+ assertArrayWithinUpperBound("Black means too high", blackMeans, THRESHOLD_LOW);
- // high iso + high exposure (second shot)
- assertArrayWithinLowerBound("White means too low", whiteMeans, THRESHOLD_HIGH);
+ // high iso + high exposure (second shot)
+ assertArrayWithinLowerBound("White means too low", whiteMeans, THRESHOLD_HIGH);
+ }
}
});
}
@@ -608,48 +606,49 @@
sensitivities[i] = sensitivityMin + delta * i;
}
- ScriptGraph scriptGraph = createGraphForYuvCroppedMeans(maxSize);
+ try (ScriptGraph scriptGraph = createGraphForYuvCroppedMeans(maxSize)) {
- CaptureRequest.Builder req =
- configureAndCreateRequestForSurface(scriptGraph.getInputSurface());
+ CaptureRequest.Builder req =
+ configureAndCreateRequestForSurface(scriptGraph.getInputSurface());
- // Take burst shots with increasing sensitivity one after other.
- for (int i = 0; i < NUM_STEPS; ++i) {
- setManualCaptureRequest(req, sensitivities[i], EXPOSURE_TIME_NS);
- captureSingleShotAndExecute(req.build(), scriptGraph);
- float[] means = convertPixelYuvToRgb(scriptGraph.getOutputData());
- rgbMeans.add(means);
+ // Take burst shots with increasing sensitivity one after other.
+ for (int i = 0; i < NUM_STEPS; ++i) {
+ setManualCaptureRequest(req, sensitivities[i], EXPOSURE_TIME_NS);
+ captureSingleShotAndExecute(req.build(), scriptGraph);
+ float[] means = convertPixelYuvToRgb(scriptGraph.getOutputData());
+ rgbMeans.add(means);
- if (VERBOSE) {
- Log.v(TAG, "testParamSensitivity - captured image " + i +
- " with RGB means: " + Arrays.toString(means));
+ if (VERBOSE) {
+ Log.v(TAG, "testParamSensitivity - captured image " + i +
+ " with RGB means: " + Arrays.toString(means));
+ }
}
- }
- // Test that every consecutive image gets brighter.
- for (int i = 0; i < rgbMeans.size() - 1; ++i) {
- float[] curMeans = rgbMeans.get(i);
- float[] nextMeans = rgbMeans.get(i+1);
+ // Test that every consecutive image gets brighter.
+ for (int i = 0; i < rgbMeans.size() - 1; ++i) {
+ float[] curMeans = rgbMeans.get(i);
+ float[] nextMeans = rgbMeans.get(i+1);
- assertArrayNotGreater(
- String.format("Shot with sensitivity %d should not have higher " +
- "average means than shot with sensitivity %d",
- sensitivities[i], sensitivities[i+1]),
- curMeans, nextMeans);
- }
+ assertArrayNotGreater(
+ String.format("Shot with sensitivity %d should not have higher " +
+ "average means than shot with sensitivity %d",
+ sensitivities[i], sensitivities[i+1]),
+ curMeans, nextMeans);
+ }
- // Test the min-max diff and ratios are within expected thresholds
- float[] lastMeans = rgbMeans.get(NUM_STEPS - 1);
- float[] firstMeans = rgbMeans.get(/*location*/0);
- for (int i = 0; i < RGB_CHANNELS; ++i) {
- assertTrue(
- String.format("Sensitivity max-min diff too small (max=%f, min=%f)",
- lastMeans[i], firstMeans[i]),
- lastMeans[i] - firstMeans[i] > THRESHOLD_MAX_MIN_DIFF);
- assertTrue(
- String.format("Sensitivity max-min ratio too small (max=%f, min=%f)",
- lastMeans[i], firstMeans[i]),
- lastMeans[i] / firstMeans[i] > THRESHOLD_MAX_MIN_RATIO);
+ // Test the min-max diff and ratios are within expected thresholds
+ float[] lastMeans = rgbMeans.get(NUM_STEPS - 1);
+ float[] firstMeans = rgbMeans.get(/*location*/0);
+ for (int i = 0; i < RGB_CHANNELS; ++i) {
+ assertTrue(
+ String.format("Sensitivity max-min diff too small (max=%f, min=%f)",
+ lastMeans[i], firstMeans[i]),
+ lastMeans[i] - firstMeans[i] > THRESHOLD_MAX_MIN_DIFF);
+ assertTrue(
+ String.format("Sensitivity max-min ratio too small (max=%f, min=%f)",
+ lastMeans[i], firstMeans[i]),
+ lastMeans[i] / firstMeans[i] > THRESHOLD_MAX_MIN_RATIO);
+ }
}
}
});
diff --git a/tests/camera/src/android/hardware/camera2/cts/CameraTestUtils.java b/tests/camera/src/android/hardware/camera2/cts/CameraTestUtils.java
index 8324490..35e792b 100644
--- a/tests/camera/src/android/hardware/camera2/cts/CameraTestUtils.java
+++ b/tests/camera/src/android/hardware/camera2/cts/CameraTestUtils.java
@@ -2079,7 +2079,8 @@
exifFocalLength, EXIF_FOCAL_LENGTH_ERROR_MARGIN);
// More checks for focal length.
collector.expectEquals("Exif focal length should match capture result",
- validateFocalLength(result, staticInfo, collector), exifFocalLength);
+ validateFocalLength(result, staticInfo, collector),
+ exifFocalLength, EXIF_FOCAL_LENGTH_ERROR_MARGIN);
// TAG_EXPOSURE_TIME
// ExifInterface API gives exposure time value in the form of float instead of rational
@@ -2110,7 +2111,8 @@
apertureValue, EXIF_APERTURE_ERROR_MARGIN);
// More checks for aperture.
collector.expectEquals("Exif aperture length should match capture result",
- validateAperture(result, staticInfo, collector), apertureValue);
+ validateAperture(result, staticInfo, collector),
+ apertureValue, EXIF_APERTURE_ERROR_MARGIN);
}
}
diff --git a/tests/camera/src/android/hardware/camera2/cts/DngCreatorTest.java b/tests/camera/src/android/hardware/camera2/cts/DngCreatorTest.java
index a9f0008..02bb348 100644
--- a/tests/camera/src/android/hardware/camera2/cts/DngCreatorTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/DngCreatorTest.java
@@ -97,6 +97,8 @@
@Override
protected void setUp() throws Exception {
+ RenderScriptSingleton.setContext(getContext());
+
super.setUp();
}
@@ -110,8 +112,6 @@
@Override
public synchronized void setContext(Context context) {
super.setContext(context);
-
- RenderScriptSingleton.setContext(context);
}
/**
diff --git a/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java b/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
index 81767a6..4d9a145 100644
--- a/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
@@ -539,11 +539,22 @@
(maxJpegSize.getWidth() <= maxYuvSize.getWidth() &&
maxJpegSize.getHeight() <= maxYuvSize.getHeight()) : false;
+ float croppedWidth = (float)sensorSize.getWidth();
+ float croppedHeight = (float)sensorSize.getHeight();
+ float sensorAspectRatio = (float)sensorSize.getWidth() / (float)sensorSize.getHeight();
+ float maxYuvAspectRatio = (float)maxYuvSize.getWidth() / (float)maxYuvSize.getHeight();
+ if (sensorAspectRatio < maxYuvAspectRatio) {
+ croppedHeight = (float)sensorSize.getWidth() / maxYuvAspectRatio;
+ } else if (sensorAspectRatio > maxYuvAspectRatio) {
+ croppedWidth = (float)sensorSize.getHeight() * maxYuvAspectRatio;
+ }
+ Size croppedSensorSize = new Size((int)croppedWidth, (int)croppedHeight);
+
boolean maxYuvMatchSensor =
- (maxYuvSize.getWidth() <= sensorSize.getWidth() * (1.0 + SIZE_ERROR_MARGIN) &&
- maxYuvSize.getWidth() >= sensorSize.getWidth() * (1.0 - SIZE_ERROR_MARGIN) &&
- maxYuvSize.getHeight() <= sensorSize.getHeight() * (1.0 + SIZE_ERROR_MARGIN) &&
- maxYuvSize.getHeight() >= sensorSize.getHeight() * (1.0 - SIZE_ERROR_MARGIN));
+ (maxYuvSize.getWidth() <= croppedSensorSize.getWidth() * (1.0 + SIZE_ERROR_MARGIN) &&
+ maxYuvSize.getWidth() >= croppedSensorSize.getWidth() * (1.0 - SIZE_ERROR_MARGIN) &&
+ maxYuvSize.getHeight() <= croppedSensorSize.getHeight() * (1.0 + SIZE_ERROR_MARGIN) &&
+ maxYuvSize.getHeight() >= croppedSensorSize.getHeight() * (1.0 - SIZE_ERROR_MARGIN));
// No need to do null check since framework will generate the key if HAL don't supply
boolean haveAeLock = CameraTestUtils.getValueNotNull(
@@ -627,8 +638,9 @@
haveFastSyncLatency);
assertTrue(
String.format("BURST-capable camera device %s max YUV size %s should be" +
- "close to active array size %s",
- mIds[counter], maxYuvSize.toString(), sensorSize.toString()),
+ "close to active array size %s or cropped active array size %s",
+ mIds[counter], maxYuvSize.toString(), sensorSize.toString(),
+ croppedSensorSize.toString()),
maxYuvMatchSensor);
assertTrue(
String.format("BURST-capable camera device %s does not support AE lock",
diff --git a/tests/camera/src/android/hardware/camera2/cts/StaticMetadataTest.java b/tests/camera/src/android/hardware/camera2/cts/StaticMetadataTest.java
index 3f2d886..8ee0a41 100644
--- a/tests/camera/src/android/hardware/camera2/cts/StaticMetadataTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/StaticMetadataTest.java
@@ -116,9 +116,19 @@
// Max jpeg resolution must be very close to sensor resolution
Size[] jpegSizes = mStaticInfo.getJpegOutputSizesChecked();
Size maxJpegSize = CameraTestUtils.getMaxSize(jpegSizes);
+ float croppedWidth = (float)sensorSize.getWidth();
+ float croppedHeight = (float)sensorSize.getHeight();
+ float sensorAspectRatio = (float)sensorSize.getWidth() / (float)sensorSize.getHeight();
+ float maxJpegAspectRatio = (float)maxJpegSize.getWidth() / (float)maxJpegSize.getHeight();
+ if (sensorAspectRatio < maxJpegAspectRatio) {
+ croppedHeight = (float)sensorSize.getWidth() / maxJpegAspectRatio;
+ } else if (sensorAspectRatio > maxJpegAspectRatio) {
+ croppedWidth = (float)sensorSize.getHeight() * maxJpegAspectRatio;
+ }
+ Size croppedSensorSize = new Size((int)croppedWidth, (int)croppedHeight);
mCollector.expectSizesAreSimilar(
- "Active array size and max JPEG size should be similar",
- sensorSize, maxJpegSize, SIZE_ERROR_MARGIN);
+ "Active array size or cropped active array size and max JPEG size should be similar",
+ croppedSensorSize, maxJpegSize, SIZE_ERROR_MARGIN);
}
// TODO: test all the keys mandatory for all capability devices.
diff --git a/tests/expectations/knownfailures.txt b/tests/expectations/knownfailures.txt
index 2d1443a..56475fd 100644
--- a/tests/expectations/knownfailures.txt
+++ b/tests/expectations/knownfailures.txt
@@ -31,13 +31,6 @@
bug: 17595050
},
{
- description: "test fails on devices with no telephony",
- names: [
- "android.calllog.cts.CallLogBackupTest#testSingleCallBackup"
- ],
- bug: 23776099
-},
-{
description: "test fails on some devices",
names: [
"android.dumpsys.cts.DumpsysHostTest#testBatterystatsOutput",
diff --git a/tests/filesystem/AndroidTest.xml b/tests/filesystem/AndroidTest.xml
index 1962357..d05134d 100644
--- a/tests/filesystem/AndroidTest.xml
+++ b/tests/filesystem/AndroidTest.xml
@@ -20,6 +20,6 @@
</target_preparer>
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.filesystem.cts" />
- <option name="runtime-hint" value="9m" />
+ <option name="runtime-hint" value="22m48s" />
</test>
-</configuration>
\ No newline at end of file
+</configuration>
diff --git a/tests/signature/src/android/signature/cts/JDiffClassDescription.java b/tests/signature/src/android/signature/cts/JDiffClassDescription.java
index e39e18a..2e13650 100644
--- a/tests/signature/src/android/signature/cts/JDiffClassDescription.java
+++ b/tests/signature/src/android/signature/cts/JDiffClassDescription.java
@@ -462,7 +462,7 @@
* @param apiMethod the method read from the api file.
* @param reflectedMethod the method found via reflections.
*/
- private boolean areMethodModifiedCompatibile(JDiffMethod apiMethod ,
+ private boolean areMethodsModifiedCompatible(JDiffMethod apiMethod ,
Method reflectedMethod) {
// If the apiMethod isn't synchronized
@@ -479,7 +479,7 @@
int mod1 = reflectedMethod.getModifiers() & ~ignoredMods;
int mod2 = apiMethod.mModifier & ~ignoredMods;
- // We can ignore FINAL for final classes
+ // We can ignore FINAL for classes
if ((mModifier & Modifier.FINAL) != 0) {
mod1 &= ~Modifier.FINAL;
mod2 &= ~Modifier.FINAL;
@@ -495,10 +495,6 @@
private void checkMethodCompliance() {
for (JDiffMethod method : jDiffMethods) {
try {
- // this is because jdiff think a method in an interface is not abstract
- if (JDiffType.INTERFACE.equals(mClassType)) {
- method.mModifier |= Modifier.ABSTRACT;
- }
Method m = findMatchingMethod(method);
if (m == null) {
@@ -522,7 +518,7 @@
return;
}
- if (!areMethodModifiedCompatibile(method, m)) {
+ if (!areMethodsModifiedCompatible(method, m)) {
mResultObserver.notifyFailure(FailureType.MISMATCH_METHOD,
method.toReadableString(mAbsoluteClassName),
"Non-compatible method found when looking for " +
@@ -545,35 +541,62 @@
* @param method the reflected method to compare
* @return true, if both methods are the same
*/
- private boolean matches(JDiffMethod jDiffMethod, Method method) {
+ private boolean matches(JDiffMethod jDiffMethod, Method reflectedMethod) {
// If the method names aren't equal, the methods can't match.
- if (jDiffMethod.mName.equals(method.getName())) {
- String jdiffReturnType = jDiffMethod.mReturnType;
- String reflectionReturnType = typeToString(method.getGenericReturnType());
- List<String> jdiffParamList = jDiffMethod.mParamList;
-
- // Next, compare the return types of the two methods. If
- // they aren't equal, the methods can't match.
- if (jdiffReturnType.equals(reflectionReturnType)) {
- Type[] params = method.getGenericParameterTypes();
- // Next, check the method parameters. If they have
- // different number of parameters, the two methods
- // can't match.
- if (jdiffParamList.size() == params.length) {
- // If any of the parameters don't match, the
- // methods can't match.
- for (int i = 0; i < jdiffParamList.size(); i++) {
- if (!compareParam(jdiffParamList.get(i), params[i])) {
- return false;
- }
- }
- // We've passed all the tests, the methods do
- // match.
- return true;
- }
- }
+ if (!jDiffMethod.mName.equals(reflectedMethod.getName())) {
+ return false;
}
- return false;
+ String jdiffReturnType = jDiffMethod.mReturnType;
+ String reflectionReturnType = typeToString(reflectedMethod.getGenericReturnType());
+ List<String> jdiffParamList = jDiffMethod.mParamList;
+
+ // Next, compare the return types of the two methods. If
+ // they aren't equal, the methods can't match.
+ if (!jdiffReturnType.equals(reflectionReturnType)) {
+ return false;
+ }
+
+ Type[] params = reflectedMethod.getGenericParameterTypes();
+
+ // Next, check the method parameters. If they have different
+ // parameter lengths, the two methods can't match.
+ if (jdiffParamList.size() != params.length) {
+ return false;
+ }
+
+ boolean piecewiseParamsMatch = true;
+
+ // Compare method parameters piecewise and return true if they all match.
+ for (int i = 0; i < jdiffParamList.size(); i++) {
+ piecewiseParamsMatch &= compareParam(jdiffParamList.get(i), params[i]);
+ }
+ if (piecewiseParamsMatch) {
+ return true;
+ }
+
+ /** NOTE: There are cases where piecewise method parameter checking
+ * fails even though the strings are equal, so compare entire strings
+ * against each other. This is not done by default to avoid a
+ * TransactionTooLargeException.
+ * Additionally, this can fail anyway due to extra
+ * information dug up by reflection.
+ *
+ * TODO: fix parameter equality checking and reflection matching
+ * See https://b.corp.google.com/issues/27726349
+ */
+
+ StringBuilder reflectedMethodParams = new StringBuilder("");
+ StringBuilder jdiffMethodParams = new StringBuilder("");
+
+ for (int i = 0; i < jdiffParamList.size(); i++) {
+ jdiffMethodParams.append(jdiffParamList.get(i));
+ reflectedMethodParams.append(params[i]);
+ }
+
+ String jDiffFName = jdiffMethodParams.toString();
+ String refName = reflectedMethodParams.toString();
+
+ return jDiffFName.equals(refName);
}
/**
diff --git a/tests/tests/accounts/Android.mk b/tests/tests/accounts/Android.mk
index fccdb86..dc17e0e 100644
--- a/tests/tests/accounts/Android.mk
+++ b/tests/tests/accounts/Android.mk
@@ -21,7 +21,8 @@
# and when built explicitly put it in the data partition
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-LOCAL_STATIC_JAVA_LIBRARIES := CtsAccountTestsCommon ctstestrunner
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ CtsAccountTestsCommon ctstestrunner platform-test-annotations
LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/tests/tests/accounts/src/android/accounts/cts/AccountManagerTest.java b/tests/tests/accounts/src/android/accounts/cts/AccountManagerTest.java
index dd1f51a..3520d9c 100644
--- a/tests/tests/accounts/src/android/accounts/cts/AccountManagerTest.java
+++ b/tests/tests/accounts/src/android/accounts/cts/AccountManagerTest.java
@@ -32,6 +32,7 @@
import android.os.HandlerThread;
import android.os.Looper;
import android.os.StrictMode;
+import android.platform.test.annotations.Presubmit;
import android.test.ActivityInstrumentationTestCase2;
import java.io.IOException;
@@ -1440,6 +1441,7 @@
/**
* Test confirmCredentials()
*/
+ @Presubmit
public void testConfirmCredentials() throws IOException, AuthenticatorException,
OperationCanceledException {
diff --git a/tests/tests/calllog/src/android/calllog/cts/CallLogBackupTest.java b/tests/tests/calllog/src/android/calllog/cts/CallLogBackupTest.java
index 5b0e0c7..695a138 100644
--- a/tests/tests/calllog/src/android/calllog/cts/CallLogBackupTest.java
+++ b/tests/tests/calllog/src/android/calllog/cts/CallLogBackupTest.java
@@ -19,9 +19,11 @@
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.database.Cursor;
import android.provider.CallLog;
import android.provider.CallLog.Calls;
+import android.provider.Settings;
import android.test.InstrumentationTestCase;
import android.util.Log;
@@ -53,6 +55,7 @@
private static final String LOCAL_BACKUP_COMPONENT =
"android/com.android.internal.backup.LocalTransport";
private static final String CALLLOG_BACKUP_PACKAGE = "com.android.providers.calllogbackup";
+ private static final String ALT_CALLLOG_BACKUP_PACKAGE = "com.android.calllogbackup";
private static final String TEST_NUMBER = "555-1234";
private static final int CALL_START_TIME = 0;
@@ -88,9 +91,18 @@
int presentation;
}
+ private String mCallLogBackupPackageName;
+
@Override
protected void setUp() throws Exception {
super.setUp();
+ PackageManager pm = getContext().getPackageManager();
+ try {
+ pm.getPackageInfo(CALLLOG_BACKUP_PACKAGE, 0);
+ mCallLogBackupPackageName = CALLLOG_BACKUP_PACKAGE;
+ } catch (PackageManager.NameNotFoundException e) {
+ mCallLogBackupPackageName = ALT_CALLLOG_BACKUP_PACKAGE;
+ }
}
/**
@@ -103,16 +115,23 @@
* 6) Verify that we the call from step (2)
*/
public void testSingleCallBackup() throws Exception {
+ if (!getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+ Log.i(TAG, "Skipping calllog tests: no telephony feature");
+ return;
+ }
// This CTS test depends on the local transport and so if it is not present,
// skip the test with success.
if (!hasBackupTransport(LOCAL_BACKUP_COMPONENT)) {
- Log.i(TAG, "skipping calllog tests");
+ Log.i(TAG, "skipping calllog tests: no local transport");
return;
}
// Turn on backup and set to the local backup agent.
boolean previouslyEnabled = enableBackup(true /* enable */);
String oldTransport = setBackupTransport(LOCAL_BACKUP_COMPONENT);
+ int previousFullDataBackupAware = Settings.Secure.getInt(getContext().getContentResolver(),
+ "user_full_data_backup_aware", 0);
+ enableFullDataBackupAware(1);
// Clear the call log
Log.i(TAG, "Clearing the call log");
@@ -125,7 +144,7 @@
// Run backup for the call log (saves the single call).
Log.i(TAG, "Running backup");
- runBackupFor(CALLLOG_BACKUP_PACKAGE);
+ runBackupFor(mCallLogBackupPackageName);
Thread.sleep(TIMEOUT_BACKUP); // time for backup
// Clear the call log and verify that it is empty
@@ -135,7 +154,7 @@
// Restore from the previous backup and verify we have the new call again.
Log.i(TAG, "Restoring the single call");
- runRestoreFor(CALLLOG_BACKUP_PACKAGE);
+ runRestoreFor(mCallLogBackupPackageName);
Thread.sleep(TIMEOUT_BACKUP); // time for restore
verifyCall();
@@ -144,6 +163,7 @@
Log.i(TAG, "Reseting backup");
setBackupTransport(oldTransport);
enableBackup(previouslyEnabled);
+ enableFullDataBackupAware(previousFullDataBackupAware);
}
private Call verifyCall() {
@@ -183,6 +203,10 @@
exec("bmgr restore " + packageName);
}
+ private void enableFullDataBackupAware(int status) throws Exception {
+ exec("settings put secure user_full_data_backup_aware " + status);
+ }
+
private String setBackupTransport(String transport) throws Exception {
String output = exec("bmgr transport " + transport);
Pattern pattern = Pattern.compile("\\(formerly (.*)\\)$");
diff --git a/tests/tests/car/src/android/car/cts/CarAudioManagerTest.java b/tests/tests/car/src/android/car/cts/CarAudioManagerTest.java
new file mode 100644
index 0000000..cec1db6
--- /dev/null
+++ b/tests/tests/car/src/android/car/cts/CarAudioManagerTest.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2016 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 android.car.cts;
+
+import android.car.Car;
+import android.car.media.CarAudioManager;
+import android.media.AudioAttributes;
+
+/** Unit tests for {@link CarAudioManager}. */
+public class CarAudioManagerTest extends CarApiTestBase {
+ private static final String TAG = CarAudioManagerTest.class.getSimpleName();
+ private CarAudioManager mManager;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mManager = (CarAudioManager) getCar().getCarManager(Car.AUDIO_SERVICE);
+ assertNotNull(mManager);
+ }
+
+ public void testGetAudioAttributesForCarUsageForMusic() throws Exception {
+ AudioAttributes.Builder musicBuilder = new AudioAttributes.Builder();
+ musicBuilder.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
+ .setUsage(AudioAttributes.USAGE_MEDIA);
+
+ assertEquals(musicBuilder.build(), mManager.getAudioAttributesForCarUsage(
+ CarAudioManager.CAR_AUDIO_USAGE_MUSIC));
+ }
+
+ public void testGetAudioAttributesForCarUsageForUnknown() throws Exception {
+ AudioAttributes.Builder unknownBuilder = new AudioAttributes.Builder();
+ unknownBuilder.setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
+ .setUsage(AudioAttributes.USAGE_UNKNOWN);
+
+ assertEquals(unknownBuilder.build(), mManager.getAudioAttributesForCarUsage(10007));
+ }
+}
diff --git a/tests/tests/car/src/android/car/cts/CarPackageManagerTest.java b/tests/tests/car/src/android/car/cts/CarPackageManagerTest.java
index 2865710..dc5fe0a 100644
--- a/tests/tests/car/src/android/car/cts/CarPackageManagerTest.java
+++ b/tests/tests/car/src/android/car/cts/CarPackageManagerTest.java
@@ -18,16 +18,21 @@
import android.car.Car;
import android.car.CarNotConnectedException;
import android.car.content.pm.CarPackageManager;
-import android.telecom.TelecomManager;
-import android.util.Log;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
-import java.util.ArrayList;
import java.util.List;
-import java.util.concurrent.ExecutionException;
public class CarPackageManagerTest extends CarApiTestBase {
private CarPackageManager mCarPm;
+ private static String TAG = CarPackageManagerTest.class.getSimpleName();
+
+ /** Name of the meta-data attribute for the automotive application XML resource */
+ private static final String METADATA_ATTRIBUTE = "android.car.application";
+
@Override
protected void setUp() throws Exception {
@@ -39,8 +44,6 @@
assertFalse(mCarPm.isActivityAllowedWhileDriving("com.basic.package", "DummyActivity"));
// Real system activity is not allowed as well.
assertFalse(mCarPm.isActivityAllowedWhileDriving("com.android.phone", "CallActivity"));
- assertTrue(mCarPm.isActivityAllowedWhileDriving(
- "com.google.android.car.media", "com.google.android.car.media.MediaProxyActivity"));
try {
mCarPm.isActivityAllowedWhileDriving("com.android.settings", null);
@@ -62,6 +65,32 @@
}
}
+ public void testSystemActivitiesAllowed() throws CarNotConnectedException {
+ List<PackageInfo> packages = getContext().getPackageManager().getInstalledPackages(
+ PackageManager.GET_ACTIVITIES | PackageManager.GET_META_DATA);
+
+ for (PackageInfo info : packages) {
+ if (info.applicationInfo == null) {
+ continue;
+ }
+ if ((info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0 ||
+ ((info.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0)) {
+
+ Bundle metaData = info.applicationInfo.metaData;
+ if (metaData == null || metaData.getInt(METADATA_ATTRIBUTE, 0) == 0) {
+ continue; // No car metadata, ignoring this app.
+ }
+
+ if (info.activities != null && info.activities.length > 0) {
+ String activity = info.activities[0].name;
+ String packageName = info.packageName;
+ assertTrue("Failed for package: " + packageName + ", activity: " + activity,
+ mCarPm.isActivityAllowedWhileDriving(packageName, activity));
+ }
+ }
+ }
+ }
+
public void testServiceAllowedWhileDriving() throws Exception {
assertFalse(mCarPm.isServiceAllowedWhileDriving("com.basic.package", ""));
assertTrue(mCarPm.isServiceAllowedWhileDriving("com.android.settings", "Any"));
@@ -75,4 +104,5 @@
// Expected.
}
}
+
}
diff --git a/tests/tests/content/src/android/content/cts/ContextTest.java b/tests/tests/content/src/android/content/cts/ContextTest.java
index c988f77..4cb85cc 100644
--- a/tests/tests/content/src/android/content/cts/ContextTest.java
+++ b/tests/tests/content/src/android/content/cts/ContextTest.java
@@ -16,10 +16,6 @@
package android.content.cts;
-import android.content.cts.R;
-
-import org.xmlpull.v1.XmlPullParserException;
-
import android.content.Context;
import android.content.cts.util.XmlUtils;
import android.content.res.ColorStateList;
@@ -34,6 +30,8 @@
import android.util.Xml;
import android.view.WindowManager;
+import org.xmlpull.v1.XmlPullParserException;
+
import java.io.File;
import java.io.IOException;
@@ -90,11 +88,11 @@
* they don't have file-based encryption, so that apps can go through a
* backup/restore cycle between FBE and non-FBE devices.
*/
- public void testCreateDeviceEncryptedStorageContext() throws Exception {
- final Context deviceContext = mContext.createDeviceEncryptedStorageContext();
+ public void testCreateDeviceProtectedStorageContext() throws Exception {
+ final Context deviceContext = mContext.createDeviceProtectedStorageContext();
- assertFalse(mContext.isDeviceEncryptedStorage());
- assertTrue(deviceContext.isDeviceEncryptedStorage());
+ assertFalse(mContext.isDeviceProtectedStorage());
+ assertTrue(deviceContext.isDeviceProtectedStorage());
final File defaultFile = new File(mContext.getFilesDir(), "test");
final File deviceFile = new File(deviceContext.getFilesDir(), "test");
@@ -108,21 +106,21 @@
assertTrue(deviceFile.exists());
}
- public void testMigrateSharedPreferencesFrom() throws Exception {
- final Context deviceContext = mContext.createDeviceEncryptedStorageContext();
+ public void testMoveSharedPreferencesFrom() throws Exception {
+ final Context deviceContext = mContext.createDeviceProtectedStorageContext();
mContext.getSharedPreferences("test", Context.MODE_PRIVATE).edit().putInt("answer", 42)
.commit();
// Verify that we can migrate
- assertTrue(deviceContext.migrateSharedPreferencesFrom(mContext, "test"));
+ assertTrue(deviceContext.moveSharedPreferencesFrom(mContext, "test"));
assertEquals(0, mContext.getSharedPreferences("test", Context.MODE_PRIVATE)
.getInt("answer", 0));
assertEquals(42, deviceContext.getSharedPreferences("test", Context.MODE_PRIVATE)
.getInt("answer", 0));
// Trying to migrate again when already done is a no-op
- assertTrue(deviceContext.migrateSharedPreferencesFrom(mContext, "test"));
+ assertTrue(deviceContext.moveSharedPreferencesFrom(mContext, "test"));
assertEquals(0, mContext.getSharedPreferences("test", Context.MODE_PRIVATE)
.getInt("answer", 0));
assertEquals(42, deviceContext.getSharedPreferences("test", Context.MODE_PRIVATE)
@@ -132,7 +130,7 @@
deviceContext.getSharedPreferences("test", Context.MODE_PRIVATE).edit()
.putInt("question", 24).commit();
- assertTrue(mContext.migrateSharedPreferencesFrom(deviceContext, "test"));
+ assertTrue(mContext.moveSharedPreferencesFrom(deviceContext, "test"));
assertEquals(42, mContext.getSharedPreferences("test", Context.MODE_PRIVATE)
.getInt("answer", 0));
assertEquals(24, mContext.getSharedPreferences("test", Context.MODE_PRIVATE)
@@ -143,8 +141,8 @@
.getInt("question", 0));
}
- public void testMigrateDatabaseFrom() throws Exception {
- final Context deviceContext = mContext.createDeviceEncryptedStorageContext();
+ public void testMoveDatabaseFrom() throws Exception {
+ final Context deviceContext = mContext.createDeviceProtectedStorageContext();
SQLiteDatabase db = mContext.openOrCreateDatabase("test.db",
Context.MODE_PRIVATE | Context.MODE_ENABLE_WRITE_AHEAD_LOGGING, null);
@@ -154,7 +152,7 @@
db.close();
// Verify that we can migrate
- assertTrue(deviceContext.migrateDatabaseFrom(mContext, "test.db"));
+ assertTrue(deviceContext.moveDatabaseFrom(mContext, "test.db"));
db = deviceContext.openOrCreateDatabase("test.db",
Context.MODE_PRIVATE | Context.MODE_ENABLE_WRITE_AHEAD_LOGGING, null);
Cursor c = db.query("list", null, null, null, null, null, null);
@@ -168,10 +166,10 @@
db.close();
// Trying to migrate again when already done is a no-op
- assertTrue(deviceContext.migrateDatabaseFrom(mContext, "test.db"));
+ assertTrue(deviceContext.moveDatabaseFrom(mContext, "test.db"));
// Verify that we can migrate back
- assertTrue(mContext.migrateDatabaseFrom(deviceContext, "test.db"));
+ assertTrue(mContext.moveDatabaseFrom(deviceContext, "test.db"));
db = mContext.openOrCreateDatabase("test.db",
Context.MODE_PRIVATE | Context.MODE_ENABLE_WRITE_AHEAD_LOGGING, null);
c = db.query("list", null, null, null, null, null, null);
diff --git a/tests/tests/display/Android.mk b/tests/tests/display/Android.mk
index 2b81ec1..5de5610 100644
--- a/tests/tests/display/Android.mk
+++ b/tests/tests/display/Android.mk
@@ -27,7 +27,7 @@
LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-test platform-test-annotations
# Tag this module as a cts test artifact
LOCAL_COMPATIBILITY_SUITE := cts
diff --git a/tests/tests/display/src/android/display/cts/DisplayTest.java b/tests/tests/display/src/android/display/cts/DisplayTest.java
index 1f9f8d1..1d1db2b 100644
--- a/tests/tests/display/src/android/display/cts/DisplayTest.java
+++ b/tests/tests/display/src/android/display/cts/DisplayTest.java
@@ -28,6 +28,7 @@
import android.os.Handler;
import android.os.Looper;
import android.os.ParcelFileDescriptor;
+import android.platform.test.annotations.Presubmit;
import android.test.InstrumentationTestCase;
import android.util.DisplayMetrics;
import android.view.Display;
@@ -139,6 +140,7 @@
/**
* Verify that the WindowManager returns the default display.
*/
+ @Presubmit
public void testDefaultDisplay() {
assertEquals(Display.DEFAULT_DISPLAY, mWindowManager.getDefaultDisplay().getDisplayId());
}
diff --git a/tests/tests/dpi/Android.mk b/tests/tests/dpi/Android.mk
index 0c158121..3f4cde5 100644
--- a/tests/tests/dpi/Android.mk
+++ b/tests/tests/dpi/Android.mk
@@ -17,7 +17,7 @@
include $(CLEAR_VARS)
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner platform-test-annotations
LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/tests/tests/dpi/src/android/dpi/cts/ConfigurationTest.java b/tests/tests/dpi/src/android/dpi/cts/ConfigurationTest.java
index e722646..fc38fdd 100644
--- a/tests/tests/dpi/src/android/dpi/cts/ConfigurationTest.java
+++ b/tests/tests/dpi/src/android/dpi/cts/ConfigurationTest.java
@@ -18,6 +18,7 @@
import android.content.Context;
import android.content.pm.PackageManager;
+import android.platform.test.annotations.Presubmit;
import android.test.AndroidTestCase;
import android.util.DisplayMetrics;
import android.view.Display;
@@ -31,6 +32,7 @@
*/
public class ConfigurationTest extends AndroidTestCase {
+ @Presubmit
public void testScreenConfiguration() {
WindowManager windowManager =
(WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
diff --git a/tests/tests/externalservice/Android.mk b/tests/tests/externalservice/Android.mk
index 3adfc34..c438dd6 100644
--- a/tests/tests/externalservice/Android.mk
+++ b/tests/tests/externalservice/Android.mk
@@ -36,7 +36,7 @@
LOCAL_PACKAGE_NAME := CtsExternalServiceTestCases
-LOCAL_SDK_VERSION := system_current
+LOCAL_SDK_VERSION := current
include $(BUILD_CTS_PACKAGE)
include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/externalservice/service/Android.mk b/tests/tests/externalservice/service/Android.mk
index 68e9d1a..9541b0e 100644
--- a/tests/tests/externalservice/service/Android.mk
+++ b/tests/tests/externalservice/service/Android.mk
@@ -30,6 +30,6 @@
# Tag this module as a cts test artifact
LOCAL_COMPATIBILITY_SUITE := cts
-LOCAL_SDK_VERSION := system_current
+LOCAL_SDK_VERSION := current
include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/tests/tests/externalservice/src/android/externalservice/cts/ExternalServiceTest.java b/tests/tests/externalservice/src/android/externalservice/cts/ExternalServiceTest.java
index b80b2ff..37c8613 100644
--- a/tests/tests/externalservice/src/android/externalservice/cts/ExternalServiceTest.java
+++ b/tests/tests/externalservice/src/android/externalservice/cts/ExternalServiceTest.java
@@ -31,7 +31,6 @@
import android.os.RemoteException;
import android.test.AndroidTestCase;
import android.util.Log;
-import android.util.MutableInt;
import android.externalservice.common.ServiceMessages;
@@ -140,15 +139,13 @@
// Check the identity of the service.
Messenger remote = new Messenger(mConnection.service);
- MutableInt uid = new MutableInt(0);
- MutableInt pid = new MutableInt(0);
- StringBuilder pkg = new StringBuilder();
- assertTrue(identifyService(remote, uid, pid, pkg));
+ ServiceIdentity id = identifyService(remote);
+ assertNotNull(id);
- assertFalse(uid.value == 0 || pid.value == 0);
- assertNotEquals(Process.myUid(), uid.value);
- assertNotEquals(Process.myPid(), pid.value);
- assertEquals(getContext().getPackageName(), pkg.toString());
+ assertFalse(id.uid == 0 || id.pid == 0);
+ assertNotEquals(Process.myUid(), id.uid);
+ assertNotEquals(Process.myPid(), id.pid);
+ assertEquals(getContext().getPackageName(), id.packageName);
}
/** Tests that the APK providing the externalService can bind the service itself, and that
@@ -165,11 +162,9 @@
// Get the identity of the creator.
Messenger remoteCreator = new Messenger(creatorConnection.service);
- MutableInt creatorUid = new MutableInt(0);
- MutableInt creatorPid = new MutableInt(0);
- StringBuilder creatorPkg = new StringBuilder();
- assertTrue(identifyService(remoteCreator, creatorUid, creatorPid, creatorPkg));
- assertFalse(creatorUid.value == 0 || creatorPid.value == 0);
+ ServiceIdentity creatorId = identifyService(remoteCreator);
+ assertNotNull(creatorId);
+ assertFalse(creatorId.uid == 0 || creatorId.pid == 0);
// Have the creator actually start its service.
final Message creatorMsg =
@@ -201,12 +196,9 @@
// Get the connection to the creator's service.
assertNotNull(creatorMsg.obj);
Messenger remoteCreatorService = (Messenger) creatorMsg.obj;
- MutableInt creatorServiceUid = new MutableInt(0);
- MutableInt creatorServicePid = new MutableInt(0);
- StringBuilder creatorServicePkg = new StringBuilder();
- assertTrue(identifyService(remoteCreatorService, creatorServiceUid, creatorServicePid,
- creatorServicePkg));
- assertFalse(creatorServiceUid.value == 0 || creatorPid.value == 0);
+ ServiceIdentity creatorServiceId = identifyService(remoteCreatorService);
+ assertNotNull(creatorServiceId);
+ assertFalse(creatorServiceId.uid == 0 || creatorId.pid == 0);
// Create an external service from this (the test) process.
intent = new Intent();
@@ -216,37 +208,34 @@
assertTrue(getContext().bindService(intent, mConnection,
Context.BIND_AUTO_CREATE | Context.BIND_EXTERNAL_SERVICE));
assertTrue(mCondition.block(CONDITION_TIMEOUT));
- MutableInt serviceUid = new MutableInt(0);
- MutableInt servicePid = new MutableInt(0);
- StringBuilder servicePkg = new StringBuilder();
- assertTrue(identifyService(new Messenger(mConnection.service), serviceUid, servicePid,
- servicePkg));
- assertFalse(serviceUid.value == 0 || servicePid.value == 0);
+ ServiceIdentity serviceId = identifyService(new Messenger(mConnection.service));
+ assertNotNull(serviceId);
+ assertFalse(serviceId.uid == 0 || serviceId.pid == 0);
// Make sure that all the processes are unique.
int myUid = Process.myUid();
int myPid = Process.myPid();
String myPkg = getContext().getPackageName();
- assertNotEquals(myUid, creatorUid.value);
- assertNotEquals(myUid, creatorServiceUid.value);
- assertNotEquals(myUid, serviceUid.value);
- assertNotEquals(myPid, creatorPid.value);
- assertNotEquals(myPid, creatorServicePid.value);
- assertNotEquals(myPid, servicePid.value);
+ assertNotEquals(myUid, creatorId.uid);
+ assertNotEquals(myUid, creatorServiceId.uid);
+ assertNotEquals(myUid, serviceId.uid);
+ assertNotEquals(myPid, creatorId.pid);
+ assertNotEquals(myPid, creatorServiceId.pid);
+ assertNotEquals(myPid, serviceId.pid);
- assertNotEquals(creatorUid.value, creatorServiceUid.value);
- assertNotEquals(creatorUid.value, serviceUid.value);
- assertNotEquals(creatorPid.value, creatorServicePid.value);
- assertNotEquals(creatorPid.value, servicePid.value);
+ assertNotEquals(creatorId.uid, creatorServiceId.uid);
+ assertNotEquals(creatorId.uid, serviceId.uid);
+ assertNotEquals(creatorId.pid, creatorServiceId.pid);
+ assertNotEquals(creatorId.pid, serviceId.pid);
- assertNotEquals(creatorServiceUid.value, serviceUid.value);
- assertNotEquals(creatorServicePid.value, servicePid.value);
+ assertNotEquals(creatorServiceId.uid, serviceId.uid);
+ assertNotEquals(creatorServiceId.pid, serviceId.pid);
- assertNotEquals(myPkg, creatorPkg.toString());
- assertNotEquals(myPkg, creatorServicePkg.toString());
- assertEquals(creatorPkg.toString(), creatorServicePkg.toString());
- assertEquals(myPkg, servicePkg.toString());
+ assertNotEquals(myPkg, creatorId.packageName);
+ assertNotEquals(myPkg, creatorServiceId.packageName);
+ assertEquals(creatorId.packageName, creatorServiceId.packageName);
+ assertEquals(myPkg, serviceId.packageName);
getContext().unbindService(creatorConnection);
}
@@ -264,11 +253,9 @@
assertTrue(mCondition.block(CONDITION_TIMEOUT));
- MutableInt uidOne = new MutableInt(0);
- MutableInt pidOne = new MutableInt(0);
- StringBuilder pkgOne = new StringBuilder();
- assertTrue(identifyService(new Messenger(initialConn.service), uidOne, pidOne, pkgOne));
- assertFalse(uidOne.value == 0 || pidOne.value == 0);
+ ServiceIdentity idOne = identifyService(new Messenger(initialConn.service));
+ assertNotNull(idOne);
+ assertFalse(idOne.uid == 0 || idOne.pid == 0);
// Bind the service with a different priority.
mCondition.close();
@@ -279,38 +266,41 @@
assertTrue(mCondition.block(CONDITION_TIMEOUT));
- MutableInt uidTwo = new MutableInt(0);
- MutableInt pidTwo = new MutableInt(0);
- StringBuilder pkgTwo = new StringBuilder();
- Messenger prioMessenger = new Messenger(prioConn.service);
- assertTrue(identifyService(prioMessenger, uidTwo, pidTwo, pkgTwo));
- assertFalse(uidTwo.value == 0 || pidTwo.value == 0);
+ ServiceIdentity idTwo = identifyService(new Messenger(prioConn.service));
+ assertNotNull(idTwo);
+ assertFalse(idTwo.uid == 0 || idTwo.pid == 0);
- assertEquals(uidOne.value, uidTwo.value);
- assertEquals(pidOne.value, pidTwo.value);
- assertEquals(pkgOne.toString(), pkgTwo.toString());
- assertNotEquals(Process.myUid(), uidOne.value);
- assertNotEquals(Process.myPid(), pidOne.value);
- assertEquals(getContext().getPackageName(), pkgOne.toString());
+ assertEquals(idOne.uid, idTwo.uid);
+ assertEquals(idOne.pid, idTwo.pid);
+ assertEquals(idOne.packageName, idTwo.packageName);
+ assertNotEquals(Process.myUid(), idOne.uid);
+ assertNotEquals(Process.myPid(), idOne.pid);
+ assertEquals(getContext().getPackageName(), idOne.packageName);
getContext().unbindService(prioConn);
getContext().unbindService(initialConn);
}
- /** Given a Messenger, this will message the service to retrieve its UID, PID, and package name,
- * storing the results in the mutable parameters. */
- private boolean identifyService(Messenger service, final MutableInt uid, final MutableInt pid,
- final StringBuilder packageName) {
+ /** Contains information about the security principal of a Service. */
+ private static class ServiceIdentity {
+ int uid;
+ int pid;
+ String packageName;
+ }
+
+ /** Given a Messenger, this will message the service to retrieve its UID, PID, and package name.
+ * On success, returns a ServiceIdentity. On failure, returns null. */
+ private ServiceIdentity identifyService(Messenger service) {
+ final ServiceIdentity id = new ServiceIdentity();
Handler handler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
Log.d(TAG, "Received message: " + msg);
switch (msg.what) {
case ServiceMessages.MSG_IDENTIFY_RESPONSE:
- uid.value = msg.arg1;
- pid.value = msg.arg2;
- packageName.append(
- msg.getData().getString(ServiceMessages.IDENTIFY_PACKAGE));
+ id.uid = msg.arg1;
+ id.pid = msg.arg2;
+ id.packageName = msg.getData().getString(ServiceMessages.IDENTIFY_PACKAGE);
mCondition.open();
break;
}
@@ -326,10 +316,12 @@
service.send(msg);
} catch (RemoteException e) {
fail("Unexpected remote exception: " + e);
- return false;
+ return null;
}
- return mCondition.block(CONDITION_TIMEOUT);
+ if (!mCondition.block(CONDITION_TIMEOUT))
+ return null;
+ return id;
}
private class Connection implements ServiceConnection {
diff --git a/tests/tests/graphics/res/color/fill_gradient_linear_clamp.xml b/tests/tests/graphics/res/color/fill_gradient_linear_clamp.xml
new file mode 100644
index 0000000..56d9fc8
--- /dev/null
+++ b/tests/tests/graphics/res/color/fill_gradient_linear_clamp.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 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.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+ android:angle="90"
+ android:startColor="?attr/themeColor"
+ android:endColor="#0f0"
+ android:centerColor="#00ff0000"
+ android:startX="0"
+ android:startY="0"
+ android:endX="50"
+ android:endY="50"
+ android:type="linear"
+ android:tileMode="clamp">
+</gradient>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/color/fill_gradient_linear_item_overlap_mirror.xml b/tests/tests/graphics/res/color/fill_gradient_linear_item_overlap_mirror.xml
new file mode 100644
index 0000000..009eb52
--- /dev/null
+++ b/tests/tests/graphics/res/color/fill_gradient_linear_item_overlap_mirror.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 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.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+ android:angle="90"
+ android:startColor="?attr/themeColor"
+ android:endColor="#0f0"
+ android:centerColor="#f00"
+ android:startX="0"
+ android:startY="0"
+ android:endX="50"
+ android:endY="50"
+ android:type="linear"
+ android:tileMode="mirror">
+ <item android:offset="0.1" android:color="?attr/themeColor"/>
+ <item android:offset="0.4" android:color="#f00"/>
+ <item android:offset="0.4" android:color="#fff"/>
+ <item android:offset="0.9" android:color="#0f0"/>
+</gradient>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/color/fill_gradient_linear_item_repeat.xml b/tests/tests/graphics/res/color/fill_gradient_linear_item_repeat.xml
new file mode 100644
index 0000000..c89e981
--- /dev/null
+++ b/tests/tests/graphics/res/color/fill_gradient_linear_item_repeat.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 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.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+ android:angle="90"
+ android:startColor="?attr/themeColor"
+ android:endColor="#0f0"
+ android:centerColor="#f00"
+ android:startX="0"
+ android:startY="0"
+ android:endX="50"
+ android:endY="50"
+ android:type="linear"
+ android:tileMode="repeat">
+ <item android:offset="0.1" android:color="?attr/themeColor"/>
+ <item android:offset="0.4" android:color="#fff"/>
+ <item android:offset="0.9" android:color="#0f0"/>
+</gradient>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/color/fill_gradient_radial_clamp.xml b/tests/tests/graphics/res/color/fill_gradient_radial_clamp.xml
new file mode 100644
index 0000000..ff29134
--- /dev/null
+++ b/tests/tests/graphics/res/color/fill_gradient_radial_clamp.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 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.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+ android:centerColor="#ff0000"
+ android:endColor="#0f0"
+ android:centerX="300"
+ android:centerY="300"
+ android:gradientRadius="50"
+ android:startColor="?attr/themeColor"
+ android:type="radial"
+ android:tileMode="clamp">
+</gradient>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/color/fill_gradient_radial_item_repeat.xml b/tests/tests/graphics/res/color/fill_gradient_radial_item_repeat.xml
new file mode 100644
index 0000000..d17fc48
--- /dev/null
+++ b/tests/tests/graphics/res/color/fill_gradient_radial_item_repeat.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 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.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+ android:centerColor="#ff0000"
+ android:endColor="#ff0000ff"
+ android:centerX="300"
+ android:centerY="300"
+ android:gradientRadius="50"
+ android:startColor="#ffffffff"
+ android:type="radial"
+ android:tileMode="repeat">
+ <item android:offset="0.1" android:color="?attr/themeColor"/>
+ <item android:offset="0.4" android:color="#fff"/>
+ <item android:offset="0.9" android:color="#0f0"/>
+</gradient>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/color/fill_gradient_radial_item_short_mirror.xml b/tests/tests/graphics/res/color/fill_gradient_radial_item_short_mirror.xml
new file mode 100644
index 0000000..1aa110c
--- /dev/null
+++ b/tests/tests/graphics/res/color/fill_gradient_radial_item_short_mirror.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 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.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+ android:centerX="300"
+ android:centerY="300"
+ android:gradientRadius="50"
+ android:type="radial"
+ android:tileMode="mirror">
+ <item android:offset="0.1" android:color="?attr/themeColor"/>
+ <item android:offset="0.9" android:color="#0f0"/>
+</gradient>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/color/fill_gradient_sweep_clamp.xml b/tests/tests/graphics/res/color/fill_gradient_sweep_clamp.xml
new file mode 100644
index 0000000..80f39f3
--- /dev/null
+++ b/tests/tests/graphics/res/color/fill_gradient_sweep_clamp.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 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.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+ android:centerColor="#ff0000"
+ android:endColor="#ff0000ff"
+ android:centerX="500"
+ android:centerY="500"
+ android:gradientRadius="10"
+ android:startColor="#ffffffff"
+ android:type="sweep"
+ android:tileMode="clamp">
+</gradient>
diff --git a/tests/tests/graphics/res/color/fill_gradient_sweep_item_long_mirror.xml b/tests/tests/graphics/res/color/fill_gradient_sweep_item_long_mirror.xml
new file mode 100644
index 0000000..2a73a4f
--- /dev/null
+++ b/tests/tests/graphics/res/color/fill_gradient_sweep_item_long_mirror.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 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.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+ android:centerX="500"
+ android:centerY="500"
+ android:gradientRadius="10"
+ android:type="sweep"
+ android:tileMode="mirror">
+ <item android:offset="-0.3" android:color="#f00"/>
+ <item android:offset="0.1" android:color="?attr/themeColor"/>
+ <item android:offset="0.4" android:color="#0f0"/>
+ <item android:offset="0.6" android:color="#00f"/>
+ <item android:offset="0.7" android:color="#0f0"/>
+ <item android:offset="1.5" android:color="#00f"/>
+</gradient>
diff --git a/tests/tests/graphics/res/color/fill_gradient_sweep_item_repeat.xml b/tests/tests/graphics/res/color/fill_gradient_sweep_item_repeat.xml
new file mode 100644
index 0000000..62e6f66
--- /dev/null
+++ b/tests/tests/graphics/res/color/fill_gradient_sweep_item_repeat.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 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.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+ android:centerColor="#ff0000"
+ android:endColor="#ff0000ff"
+ android:centerX="500"
+ android:centerY="500"
+ android:gradientRadius="10"
+ android:startColor="#ffffffff"
+ android:type="sweep"
+ android:tileMode="repeat">
+ <item android:offset="0.1" android:color="?attr/themeColor"/>
+ <item android:offset="0.4" android:color="#fff"/>
+ <item android:offset="0.9" android:color="#0f0"/>
+</gradient>
diff --git a/tests/tests/graphics/res/color/stroke_gradient_clamp.xml b/tests/tests/graphics/res/color/stroke_gradient_clamp.xml
new file mode 100644
index 0000000..3d746e7
--- /dev/null
+++ b/tests/tests/graphics/res/color/stroke_gradient_clamp.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 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.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+ android:angle="90"
+ android:centerColor="#7f7f7f"
+ android:endColor="#ffffff"
+ android:startColor="#000000"
+ android:startX="0"
+ android:endX="50"
+ android:startY="0"
+ android:endY="0"
+ android:type="linear"
+ android:tileMode="clamp">
+</gradient>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/color/stroke_gradient_item_alpha_mirror.xml b/tests/tests/graphics/res/color/stroke_gradient_item_alpha_mirror.xml
new file mode 100644
index 0000000..352a2fd
--- /dev/null
+++ b/tests/tests/graphics/res/color/stroke_gradient_item_alpha_mirror.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 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.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+ android:startX="0"
+ android:endX="50"
+ android:startY="0"
+ android:endY="0"
+ android:type="linear"
+ android:tileMode="mirror">
+ <item android:offset="0.1" android:color="#f00"/>
+ <item android:offset="0.2" android:color="#2f0f"/>
+ <item android:offset="0.9" android:color="#f00f"/>
+</gradient>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/color/stroke_gradient_item_repeat.xml b/tests/tests/graphics/res/color/stroke_gradient_item_repeat.xml
new file mode 100644
index 0000000..42281d1
--- /dev/null
+++ b/tests/tests/graphics/res/color/stroke_gradient_item_repeat.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 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.
+ */
+-->
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+ android:angle="90"
+ android:centerColor="#7f7f7f"
+ android:endColor="#ffffff"
+ android:startColor="#000000"
+ android:startX="0"
+ android:endX="50"
+ android:startY="0"
+ android:endY="0"
+ android:type="linear"
+ android:tileMode="repeat">
+ <item android:offset="0.1" android:color="#f00"/>
+ <item android:offset="0.2" android:color="#f0f"/>
+ <item android:offset="0.9" android:color="#f00f"/>
+</gradient>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_filltype_evenodd_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_filltype_evenodd_golden.png
new file mode 100644
index 0000000..bef75d4
--- /dev/null
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_filltype_evenodd_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_filltype_nonzero_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_filltype_nonzero_golden.png
new file mode 100644
index 0000000..85cf20b
--- /dev/null
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_filltype_nonzero_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_1_clamp_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_1_clamp_golden.png
new file mode 100644
index 0000000..a137784
--- /dev/null
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_1_clamp_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_2_repeat_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_2_repeat_golden.png
new file mode 100644
index 0000000..40432cd
--- /dev/null
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_2_repeat_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_3_mirror_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_3_mirror_golden.png
new file mode 100644
index 0000000..9f1b257
--- /dev/null
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_3_mirror_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable/vector_icon_filltype_evenodd.xml b/tests/tests/graphics/res/drawable/vector_icon_filltype_evenodd.xml
new file mode 100644
index 0000000..d5d86d8
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/vector_icon_filltype_evenodd.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 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.
+ */
+-->
+<vector android:height="24dp" android:viewportHeight="400.0"
+ android:viewportWidth="1200.0" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+ <path android:fillType="evenOdd"
+ android:fillColor="#f00"
+ android:pathData="M250,75L323,301 131,161 369,161 177,301z"
+ android:strokeColor="#000" android:strokeWidth="3"/>
+ <path android:fillType="evenOdd"
+ android:fillColor="#f00"
+ android:pathData="M600,81A107,107 0,0 1,600 295A107,107 0,0 1,600 81zM600,139A49,49 0,0 1,600 237A49,49 0,0 1,600 139z"
+ android:strokeColor="#000" android:strokeWidth="3"/>
+ <path android:fillType="evenOdd"
+ android:fillColor="#f00"
+ android:pathData="M950,81A107,107 0,0 1,950 295A107,107 0,0 1,950 81zM950,139A49,49 0,0 0,950 237A49,49 0,0 0,950 139z"
+ android:strokeColor="#000" android:strokeWidth="3"/>
+</vector>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/drawable/vector_icon_filltype_nonzero.xml b/tests/tests/graphics/res/drawable/vector_icon_filltype_nonzero.xml
new file mode 100644
index 0000000..9754e4b
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/vector_icon_filltype_nonzero.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 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.
+ */
+-->
+<vector android:height="24dp" android:viewportHeight="400.0"
+ android:viewportWidth="1200.0" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+ <path android:fillType="nonZero"
+ android:fillColor="#f00"
+ android:pathData="M250,75L323,301 131,161 369,161 177,301z"
+ android:strokeColor="#000" android:strokeWidth="3"/>
+ <path android:fillType="nonZero"
+ android:fillColor="#f00"
+ android:pathData="M600,81A107,107 0,0 1,600 295A107,107 0,0 1,600 81zM600,139A49,49 0,0 1,600 237A49,49 0,0 1,600 139z"
+ android:strokeColor="#000" android:strokeWidth="3"/>
+ <path android:fillType="nonZero"
+ android:fillColor="#f00"
+ android:pathData="M950,81A107,107 0,0 1,950 295A107,107 0,0 1,950 81zM950,139A49,49 0,0 0,950 237A49,49 0,0 0,950 139z"
+ android:strokeColor="#000" android:strokeWidth="3"/>
+</vector>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/drawable/vector_icon_gradient_1_clamp.xml b/tests/tests/graphics/res/drawable/vector_icon_gradient_1_clamp.xml
new file mode 100644
index 0000000..2fa440a
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/vector_icon_gradient_1_clamp.xml
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 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.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="64dp"
+ android:width="64dp"
+ android:viewportHeight="400"
+ android:viewportWidth="400" >
+
+<group android:name="backgroundGroup"
+ android:scaleX="0.5"
+ android:scaleY="0.5">
+ <path
+ android:name="background1"
+ android:fillColor="@color/fill_gradient_linear_clamp"
+ android:pathData="M 0,0 l 200,0 l 0, 200 l -200, 0 z" />
+ <path
+ android:name="background2"
+ android:fillColor="@color/fill_gradient_radial_clamp"
+ android:pathData="M 200,200 l 200,0 l 0, 200 l -200, 0 z" />
+ <path
+ android:name="background3"
+ android:fillColor="@color/fill_gradient_sweep_clamp"
+ android:pathData="M 400,400 l 200,0 l 0, 200 l -200, 0 z" />
+</group>
+<group
+ android:name="translateToCenterGroup"
+ android:translateX="50.0"
+ android:translateY="90.0" >
+ <path
+ android:name="twoLines"
+ android:pathData="@string/twoLinePathData"
+ android:strokeColor="@color/stroke_gradient_clamp"
+ android:strokeWidth="20" />
+
+ <group
+ android:name="rotationGroup"
+ android:pivotX="0.0"
+ android:pivotY="0.0"
+ android:rotation="-45.0">
+ <path
+ android:name="twoLines1"
+ android:pathData="@string/twoLinePathData"
+ android:strokeColor="@color/stroke_gradient_clamp"
+ android:strokeWidth="20" />
+
+ <group
+ android:name="translateGroup"
+ android:translateX="130.0"
+ android:translateY="160.0">
+ <group android:name="scaleGroup" >
+ <path
+ android:name="twoLines3"
+ android:pathData="@string/twoLinePathData"
+ android:strokeColor="@color/stroke_gradient_clamp"
+ android:strokeWidth="20" />
+ </group>
+ </group>
+
+ <group
+ android:name="translateGroupHalf"
+ android:translateX="65.0"
+ android:translateY="80.0">
+ <group android:name="scaleGroup" >
+ <path
+ android:name="twoLines2"
+ android:pathData="@string/twoLinePathData"
+ android:fillColor="@color/fill_gradient_linear_clamp"
+ android:strokeColor="@color/stroke_gradient_clamp"
+ android:strokeWidth="20" />
+ </group>
+ </group>
+ </group>
+</group>
+
+</vector>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/drawable/vector_icon_gradient_2_repeat.xml b/tests/tests/graphics/res/drawable/vector_icon_gradient_2_repeat.xml
new file mode 100644
index 0000000..5a43f80
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/vector_icon_gradient_2_repeat.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 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.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="64dp"
+ android:width="64dp"
+ android:viewportHeight="400"
+ android:viewportWidth="400" >
+
+<group android:name="backgroundGroup"
+ android:scaleX="0.5"
+ android:scaleY="0.5">
+ <path
+ android:name="background1"
+ android:fillColor="@color/fill_gradient_linear_item_repeat"
+ android:pathData="M 0,0 l 200,0 l 0, 200 l -200, 0 z" />
+ <path
+ android:name="background2"
+ android:fillColor="@color/fill_gradient_radial_item_repeat"
+ android:pathData="M 200,200 l 200,0 l 0, 200 l -200, 0 z" />
+ <path
+ android:name="background3"
+ android:fillColor="@color/fill_gradient_sweep_item_repeat"
+ android:pathData="M 400,400 l 200,0 l 0, 200 l -200, 0 z" />
+</group>
+<group
+ android:name="translateToCenterGroup"
+ android:translateX="50.0"
+ android:translateY="90.0" >
+ <path
+ android:name="twoLines"
+ android:pathData="@string/twoLinePathData"
+ android:strokeColor="@color/stroke_gradient_item_repeat"
+ android:strokeWidth="20" />
+
+ <group
+ android:name="rotationGroup"
+ android:pivotX="0.0"
+ android:pivotY="0.0"
+ android:rotation="-45.0">
+ <path
+ android:name="twoLines1"
+ android:pathData="@string/twoLinePathData"
+ android:strokeColor="@color/stroke_gradient_item_repeat"
+ android:strokeWidth="20" />
+
+ <group
+ android:name="translateGroup"
+ android:translateX="130.0"
+ android:translateY="160.0">
+ <group android:name="scaleGroup" >
+ <path
+ android:name="twoLines3"
+ android:pathData="@string/twoLinePathData"
+ android:strokeColor="@color/stroke_gradient_item_repeat"
+ android:strokeWidth="20" />
+ </group>
+ </group>
+
+ <group
+ android:name="translateGroupHalf"
+ android:translateX="65.0"
+ android:translateY="80.0">
+ <group android:name="scaleGroup" >
+ <path
+ android:name="twoLines2"
+ android:pathData="@string/twoLinePathData"
+ android:strokeColor="@color/stroke_gradient_item_repeat"
+ android:strokeWidth="20" />
+ </group>
+ </group>
+ </group>
+</group>
+
+</vector>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/drawable/vector_icon_gradient_3_mirror.xml b/tests/tests/graphics/res/drawable/vector_icon_gradient_3_mirror.xml
new file mode 100644
index 0000000..e8de7c2
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/vector_icon_gradient_3_mirror.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 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.
+ */
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="64dp"
+ android:width="64dp"
+ android:viewportHeight="400"
+ android:viewportWidth="400" >
+
+<group android:name="backgroundGroup"
+ android:scaleX="0.5"
+ android:scaleY="0.5">
+ <path
+ android:name="background1"
+ android:fillColor="@color/fill_gradient_linear_item_overlap_mirror"
+ android:pathData="M 0,0 l 200,0 l 0, 200 l -200, 0 z" />
+ <path
+ android:name="background2"
+ android:fillColor="@color/fill_gradient_radial_item_short_mirror"
+ android:pathData="M 200,200 l 200,0 l 0, 200 l -200, 0 z" />
+ <path
+ android:name="background3"
+ android:fillColor="@color/fill_gradient_sweep_item_long_mirror"
+ android:pathData="M 400,400 l 200,0 l 0, 200 l -200, 0 z" />
+</group>
+<group
+ android:name="translateToCenterGroup"
+ android:translateX="50.0"
+ android:translateY="90.0" >
+ <path
+ android:name="twoLines"
+ android:pathData="@string/twoLinePathData"
+ android:strokeColor="@color/stroke_gradient_item_alpha_mirror"
+ android:strokeWidth="20" />
+
+ <group
+ android:name="rotationGroup"
+ android:pivotX="0.0"
+ android:pivotY="0.0"
+ android:rotation="-45.0">
+ <path
+ android:name="twoLines1"
+ android:pathData="@string/twoLinePathData"
+ android:strokeColor="@color/stroke_gradient_item_alpha_mirror"
+ android:strokeWidth="20" />
+
+ <group
+ android:name="translateGroup"
+ android:translateX="130.0"
+ android:translateY="160.0">
+ <group android:name="scaleGroup" >
+ <path
+ android:name="twoLines3"
+ android:pathData="@string/twoLinePathData"
+ android:strokeColor="@color/stroke_gradient_item_alpha_mirror"
+ android:strokeWidth="20" />
+ </group>
+ </group>
+
+ <group
+ android:name="translateGroupHalf"
+ android:translateX="65.0"
+ android:translateY="80.0">
+ <group android:name="scaleGroup" >
+ <path
+ android:name="twoLines2"
+ android:pathData="@string/twoLinePathData"
+ android:strokeColor="@color/stroke_gradient_item_alpha"
+ android:strokeWidth="20" />
+ </group>
+ </group>
+ </group>
+</group>
+
+</vector>
\ No newline at end of file
diff --git a/tests/tests/graphics/src/android/graphics/cts/AvoidXfermodeTest.java b/tests/tests/graphics/src/android/graphics/cts/AvoidXfermodeTest.java
deleted file mode 100644
index beb3621..0000000
--- a/tests/tests/graphics/src/android/graphics/cts/AvoidXfermodeTest.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2009 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 android.graphics.cts;
-
-import android.graphics.AvoidXfermode;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.Bitmap.Config;
-
-import junit.framework.TestCase;
-
-public class AvoidXfermodeTest extends TestCase {
- /*
- * ToBeFixed: This test ought to work with a TOLERANCE of 0. See bug 2034547.
- */
- private static final int TOLERANCE = 255;
- private static final int BASE_SIZE = 50;
- private static final int BITMAP_HEIGHT = BASE_SIZE * 2;
- private static final int BITMAP_WIDTH = BASE_SIZE * 2;
-
- public void testAvoidXfermode() {
- Paint greenPaint;
- Paint redAvoidingGreenPaint;
- Paint blueTargetingGreenPaint;
- greenPaint = new Paint();
- greenPaint.setColor(Color.GREEN);
- AvoidXfermode avoidMode =
- new AvoidXfermode(greenPaint.getColor(), TOLERANCE, AvoidXfermode.Mode.AVOID);
- redAvoidingGreenPaint = new Paint();
- redAvoidingGreenPaint.setColor(Color.RED);
- redAvoidingGreenPaint.setXfermode(avoidMode);
- AvoidXfermode targetMode =
- new AvoidXfermode(greenPaint.getColor(), TOLERANCE, AvoidXfermode.Mode.TARGET);
- blueTargetingGreenPaint = new Paint();
- blueTargetingGreenPaint.setColor(Color.BLUE);
- blueTargetingGreenPaint.setXfermode(targetMode);
-
- Bitmap b = Bitmap.createBitmap(BITMAP_WIDTH, BITMAP_HEIGHT, Config.ARGB_8888);
- b.eraseColor(Color.BLACK);
- Canvas canvas = new Canvas(b);
- // vertical bar on the left
- canvas.drawRect(0f, 0f, BASE_SIZE, 2 * BASE_SIZE, greenPaint);
- // horizontal bar on top
- canvas.drawRect(0f, 0f, 2 * BASE_SIZE, BASE_SIZE, redAvoidingGreenPaint);
- // horizontal bar at bottom
- canvas.drawRect(0f, BASE_SIZE, 2 * BASE_SIZE, 2 * BASE_SIZE, blueTargetingGreenPaint);
-
- assertEquals(Color.GREEN, b.getPixel(BASE_SIZE / 2, BASE_SIZE / 2));
- assertEquals(Color.RED, b.getPixel(BASE_SIZE + BASE_SIZE / 2, BASE_SIZE / 2));
- assertEquals(Color.BLUE, b.getPixel(BASE_SIZE / 2, BASE_SIZE + BASE_SIZE / 2));
- assertEquals(Color.BLACK, b.getPixel(BASE_SIZE + BASE_SIZE / 2, BASE_SIZE + BASE_SIZE / 2));
- }
-}
diff --git a/tests/tests/graphics/src/android/graphics/cts/AvoidXfermode_ModeTest.java b/tests/tests/graphics/src/android/graphics/cts/AvoidXfermode_ModeTest.java
deleted file mode 100644
index 8704e6f..0000000
--- a/tests/tests/graphics/src/android/graphics/cts/AvoidXfermode_ModeTest.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2008 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 android.graphics.cts;
-
-import android.graphics.AvoidXfermode;
-import android.graphics.AvoidXfermode.Mode;
-import android.test.AndroidTestCase;
-
-public class AvoidXfermode_ModeTest extends AndroidTestCase{
-
- public void testValueOf(){
- assertEquals(Mode.AVOID, Mode.valueOf("AVOID"));
- assertEquals(Mode.TARGET, Mode.valueOf("TARGET"));
- }
-
- public void testValues(){
- Mode[] mode = Mode.values();
-
- assertEquals(2, mode.length);
- assertEquals(Mode.AVOID, mode[0]);
- assertEquals(Mode.TARGET, mode[1]);
-
- //Mode is used as a argument here for all the methods that use it
- assertNotNull(new AvoidXfermode(10, 24, Mode.AVOID));
- assertNotNull(new AvoidXfermode(10, 24, Mode.TARGET));
- }
-}
diff --git a/tests/tests/graphics/src/android/graphics/cts/ComposeShaderTest.java b/tests/tests/graphics/src/android/graphics/cts/ComposeShaderTest.java
index 1a2164a..b44faff 100644
--- a/tests/tests/graphics/src/android/graphics/cts/ComposeShaderTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/ComposeShaderTest.java
@@ -23,8 +23,8 @@
import android.graphics.ComposeShader;
import android.graphics.LinearGradient;
import android.graphics.Paint;
-import android.graphics.PixelXorXfermode;
import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
import android.graphics.Shader;
import android.graphics.Xfermode;
import android.graphics.Bitmap.Config;
@@ -71,17 +71,17 @@
}
public void testXfermode() {
- Bitmap greenBitmap = Bitmap.createBitmap(1, 1, Config.ARGB_8888);
- greenBitmap.eraseColor(Color.GREEN);
+ Bitmap redBitmap = Bitmap.createBitmap(1, 1, Config.ARGB_8888);
+ redBitmap.eraseColor(Color.RED);
Bitmap cyanBitmap = Bitmap.createBitmap(1, 1, Config.ARGB_8888);
cyanBitmap.eraseColor(Color.CYAN);
- BitmapShader blueShader = new BitmapShader(greenBitmap, TileMode.CLAMP, TileMode.CLAMP);
- BitmapShader redShader = new BitmapShader(cyanBitmap, TileMode.CLAMP, TileMode.CLAMP);
+ BitmapShader redShader = new BitmapShader(redBitmap, TileMode.CLAMP, TileMode.CLAMP);
+ BitmapShader cyanShader = new BitmapShader(cyanBitmap, TileMode.CLAMP, TileMode.CLAMP);
- PixelXorXfermode xferMode = new PixelXorXfermode(Color.WHITE);
+ PorterDuffXfermode xferMode = new PorterDuffXfermode(PorterDuff.Mode.ADD);
- ComposeShader shader = new ComposeShader(blueShader, redShader, xferMode);
+ ComposeShader shader = new ComposeShader(redShader, cyanShader, xferMode);
Bitmap bitmap = Bitmap.createBitmap(1, 1, Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
@@ -89,7 +89,7 @@
paint.setShader(shader);
canvas.drawPaint(paint);
- // white ^ green ^ cyan = yellow
- assertEquals(Color.YELLOW, bitmap.getPixel(0, 0));
+ // green + cyan = white
+ assertEquals(Color.WHITE, bitmap.getPixel(0, 0));
}
}
diff --git a/tests/tests/graphics/src/android/graphics/cts/OutlineTest.java b/tests/tests/graphics/src/android/graphics/cts/OutlineTest.java
index 0dcff12..4b01916 100644
--- a/tests/tests/graphics/src/android/graphics/cts/OutlineTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/OutlineTest.java
@@ -20,16 +20,19 @@
import android.graphics.Path;
import android.graphics.Rect;
import android.test.suitebuilder.annotation.SmallTest;
-import junit.framework.TestCase;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
@SmallTest
-public class OutlineTest extends TestCase {
+public class OutlineTest {
@Test
public void testDefaults() {
Outline outline = new Outline();
- assertEquals(0.0f, outline.getAlpha());
+ assertEquals(0.0f, outline.getAlpha(), 0.0f);
assertTrue(outline.isEmpty());
Rect outRect = new Rect();
assertFalse(outline.getRect(outRect));
@@ -41,19 +44,19 @@
Outline outline = new Outline();
outline.setAlpha(1.0f);
- assertEquals(1.0f, outline.getAlpha());
+ assertEquals(1.0f, outline.getAlpha(), 0.0f);
outline.setAlpha(0.0f);
- assertEquals(0.0f, outline.getAlpha());
+ assertEquals(0.0f, outline.getAlpha(), 0.0f);
outline.setAlpha(0.45f);
- assertEquals(0.45f, outline.getAlpha());
+ assertEquals(0.45f, outline.getAlpha(), 0.0f);
// define out of range getter/setter behavior: (note will be clamped in native when consumed)
outline.setAlpha(4f);
- assertEquals(4f, outline.getAlpha());
+ assertEquals(4f, outline.getAlpha(), 0.0f);
outline.setAlpha(-30f);
- assertEquals(-30f, outline.getAlpha());
+ assertEquals(-30f, outline.getAlpha(), 0.0f);
}
@Test
@@ -101,14 +104,14 @@
assertFalse(outline.isEmpty());
assertTrue(outline.getRect(outRect));
assertEquals(new Rect(10, 10, 20, 20), outRect);
- assertEquals(5f, outline.getRadius());
+ assertEquals(5f, outline.getRadius(), 0.0f);
assertTrue(outline.canClip());
outline.setRoundRect(new Rect(10, 10, 20, 20), 4f);
assertFalse(outline.isEmpty());
assertTrue(outline.getRect(outRect));
assertEquals(new Rect(10, 10, 20, 20), outRect);
- assertEquals(4f, outline.getRadius());
+ assertEquals(4f, outline.getRadius(), 0.0f);
assertTrue(outline.canClip());
}
@@ -154,12 +157,12 @@
Rect outRect = new Rect();
outline.setRoundRect(15, 10, 45, 40, 30.0f);
- assertEquals(30.0f, outline.getRadius());
+ assertEquals(30.0f, outline.getRadius(), 0.0f);
assertTrue(outline.getRect(outRect));
assertEquals(new Rect(15, 10, 45, 40), outRect);
outline.setRect(5, 10, 15, 20);
- assertEquals(0.0f, outline.getRadius());
+ assertEquals(0.0f, outline.getRadius(), 0.0f);
assertTrue(outline.getRect(outRect));
assertEquals(new Rect(5, 10, 15, 20), outRect);
diff --git a/tests/tests/graphics/src/android/graphics/cts/PixelXorXfermodeTest.java b/tests/tests/graphics/src/android/graphics/cts/PixelXorXfermodeTest.java
deleted file mode 100644
index e2d68da..0000000
--- a/tests/tests/graphics/src/android/graphics/cts/PixelXorXfermodeTest.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2008 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 android.graphics.cts;
-
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.PixelXorXfermode;
-import android.graphics.Bitmap.Config;
-import android.test.AndroidTestCase;
-
-public class PixelXorXfermodeTest extends AndroidTestCase {
-
- public void testPixelXorXfermode() {
- int width = 100;
- int height = 100;
- Bitmap b1 = Bitmap.createBitmap(width / 2, height, Config.ARGB_8888);
- b1.eraseColor(Color.WHITE);
- Bitmap b2 = Bitmap.createBitmap(width, height / 2, Config.ARGB_8888);
- b2.eraseColor(Color.CYAN);
-
- Bitmap target = Bitmap.createBitmap(width, height, Config.ARGB_8888);
- target.eraseColor(Color.BLACK);
- Canvas canvas = new Canvas(target);
- Paint p = new Paint();
- canvas.drawBitmap(b1, 0, 0, p);
- p.setXfermode(new PixelXorXfermode(Color.GREEN));
- canvas.drawBitmap(b2, 0, height / 2, p);
- assertEquals(Color.WHITE, target.getPixel(width / 4, height / 4));
- // white ^ green ^ cyan = yellow
- assertEquals(Color.YELLOW, target.getPixel(width / 4, height * 3 / 4));
- // black ^ green ^ cyan = blue
- assertEquals(Color.BLUE, target.getPixel(width * 3 / 4, height * 3 / 4));
-
- // XOR transfer always results in an opaque image
- p.setXfermode(new PixelXorXfermode(alphaColor(Color.GREEN, 25)));
- target.eraseColor(alphaColor(Color.BLACK, 42));
- p.setColor(alphaColor(Color.CYAN, 5));
- canvas.drawPaint(p);
- // result is always opaque, even though all inputs have alpha
- assertEquals(255, Color.alpha(target.getPixel(0, 0)));
- }
-
- private int alphaColor(int color, int alpha) {
- int red = Color.red(color);
- int green = Color.green(color);
- int blue = Color.blue(color);
- return Color.argb(alpha, red, green, blue);
- }
-}
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/VectorDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/VectorDrawableTest.java
index ac1d9b3..a39c18f 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/VectorDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/VectorDrawableTest.java
@@ -46,7 +46,10 @@
public class VectorDrawableTest extends AndroidTestCase {
private static final String LOGTAG = "VectorDrawableTest";
- private static final int[] ICON_RES_IDS = new int[] {
+ // Separate the test assets into different groups such that we could isolate the issue faster.
+ // Some new APIs or bug fixes only exist in particular os version, such that we name the tests
+ // and associated assets with OS code name L, M, N etc...
+ private static final int[] BASIC_ICON_RES_IDS = new int[]{
R.drawable.vector_icon_create,
R.drawable.vector_icon_delete,
R.drawable.vector_icon_heart,
@@ -59,6 +62,24 @@
R.drawable.vector_icon_repeated_a_1,
R.drawable.vector_icon_repeated_a_2,
R.drawable.vector_icon_clip_path_1,
+ };
+
+ private static final int[] BASIC_GOLDEN_IMAGES = new int[] {
+ R.drawable.vector_icon_create_golden,
+ R.drawable.vector_icon_delete_golden,
+ R.drawable.vector_icon_heart_golden,
+ R.drawable.vector_icon_schedule_golden,
+ R.drawable.vector_icon_settings_golden,
+ R.drawable.vector_icon_random_path_1_golden,
+ R.drawable.vector_icon_random_path_2_golden,
+ R.drawable.vector_icon_repeated_cq_golden,
+ R.drawable.vector_icon_repeated_st_golden,
+ R.drawable.vector_icon_repeated_a_1_golden,
+ R.drawable.vector_icon_repeated_a_2_golden,
+ R.drawable.vector_icon_clip_path_1_golden,
+ };
+
+ private static final int[] L_M_ICON_RES_IDS = new int[] {
R.drawable.vector_icon_transformation_1,
R.drawable.vector_icon_transformation_2,
R.drawable.vector_icon_transformation_3,
@@ -72,23 +93,9 @@
R.drawable.vector_icon_stroke_3,
R.drawable.vector_icon_scale_1,
R.drawable.vector_icon_scale_2,
- R.drawable.vector_icon_implicit_lineto,
- R.drawable.vector_icon_arcto,
};
- private static final int[] GOLDEN_IMAGES = new int[] {
- R.drawable.vector_icon_create_golden,
- R.drawable.vector_icon_delete_golden,
- R.drawable.vector_icon_heart_golden,
- R.drawable.vector_icon_schedule_golden,
- R.drawable.vector_icon_settings_golden,
- R.drawable.vector_icon_random_path_1_golden,
- R.drawable.vector_icon_random_path_2_golden,
- R.drawable.vector_icon_repeated_cq_golden,
- R.drawable.vector_icon_repeated_st_golden,
- R.drawable.vector_icon_repeated_a_1_golden,
- R.drawable.vector_icon_repeated_a_2_golden,
- R.drawable.vector_icon_clip_path_1_golden,
+ private static final int[] L_M_GOLDEN_IMAGES = new int[] {
R.drawable.vector_icon_transformation_1_golden,
R.drawable.vector_icon_transformation_2_golden,
R.drawable.vector_icon_transformation_3_golden,
@@ -102,20 +109,38 @@
R.drawable.vector_icon_stroke_3_golden,
R.drawable.vector_icon_scale_1_golden,
R.drawable.vector_icon_scale_2_golden,
+ };
+
+ private static final int[] N_ICON_RES_IDS = new int[] {
+ R.drawable.vector_icon_implicit_lineto,
+ R.drawable.vector_icon_arcto,
+ R.drawable.vector_icon_filltype_nonzero,
+ R.drawable.vector_icon_filltype_evenodd,
+ };
+
+ private static final int[] N_GOLDEN_IMAGES = new int[] {
R.drawable.vector_icon_implicit_lineto_golden,
R.drawable.vector_icon_arcto_golden,
+ R.drawable.vector_icon_filltype_nonzero_golden,
+ R.drawable.vector_icon_filltype_evenodd_golden,
};
private static final int[] GRADIENT_ICON_RES_IDS = new int[] {
R.drawable.vector_icon_gradient_1,
R.drawable.vector_icon_gradient_2,
R.drawable.vector_icon_gradient_3,
+ R.drawable.vector_icon_gradient_1_clamp,
+ R.drawable.vector_icon_gradient_2_repeat,
+ R.drawable.vector_icon_gradient_3_mirror,
};
private static final int[] GRADIENT_GOLDEN_IMAGES = new int[] {
R.drawable.vector_icon_gradient_1_golden,
R.drawable.vector_icon_gradient_2_golden,
R.drawable.vector_icon_gradient_3_golden,
+ R.drawable.vector_icon_gradient_1_clamp_golden,
+ R.drawable.vector_icon_gradient_2_repeat_golden,
+ R.drawable.vector_icon_gradient_3_mirror_golden,
};
private static final int[] STATEFUL_RES_IDS = new int[] {
@@ -163,8 +188,18 @@
}
@MediumTest
- public void testSimpleVectorDrawables() throws XmlPullParserException, IOException {
- verifyVectorDrawables(ICON_RES_IDS, GOLDEN_IMAGES, null);
+ public void testBasicVectorDrawables() throws XmlPullParserException, IOException {
+ verifyVectorDrawables(BASIC_ICON_RES_IDS, BASIC_GOLDEN_IMAGES, null);
+ }
+
+ @MediumTest
+ public void testLMVectorDrawables() throws XmlPullParserException, IOException {
+ verifyVectorDrawables(L_M_ICON_RES_IDS, L_M_GOLDEN_IMAGES, null);
+ }
+
+ @MediumTest
+ public void testNVectorDrawables() throws XmlPullParserException, IOException {
+ verifyVectorDrawables(N_ICON_RES_IDS, N_GOLDEN_IMAGES, null);
}
@MediumTest
diff --git a/tests/tests/hardware/Android.mk b/tests/tests/hardware/Android.mk
index 45aef43..a59c5f4 100644
--- a/tests/tests/hardware/Android.mk
+++ b/tests/tests/hardware/Android.mk
@@ -24,7 +24,8 @@
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil compatibility-device-util
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ ctsdeviceutil compatibility-device-util platform-test-annotations
LOCAL_SDK_VERSION := current
@@ -52,7 +53,13 @@
# Tag this module as a cts test artifact
LOCAL_COMPATIBILITY_SUITE := cts
-LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil compatibility-device-util ctstestrunner mockito-target android-ex-camera2
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ ctsdeviceutil \
+ compatibility-device-util \
+ ctstestrunner \
+ mockito-target \
+ android-ex-camera2 \
+ platform-test-annotations
LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
diff --git a/tests/tests/hardware/AndroidTest.xml b/tests/tests/hardware/AndroidTest.xml
index 14027dd..68131d1 100644
--- a/tests/tests/hardware/AndroidTest.xml
+++ b/tests/tests/hardware/AndroidTest.xml
@@ -26,6 +26,7 @@
</target_preparer>
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.hardware.cts" />
+ <option name="runtime-hint" value="47m28s" />
</test>
</configuration>
diff --git a/tests/tests/hardware/src/android/hardware/cts/GeomagneticFieldTest.java b/tests/tests/hardware/src/android/hardware/cts/GeomagneticFieldTest.java
index dc927b6..75d7b7c 100644
--- a/tests/tests/hardware/src/android/hardware/cts/GeomagneticFieldTest.java
+++ b/tests/tests/hardware/src/android/hardware/cts/GeomagneticFieldTest.java
@@ -16,8 +16,8 @@
package android.hardware.cts;
-
import android.hardware.GeomagneticField;
+import android.platform.test.annotations.Presubmit;
import android.test.AndroidTestCase;
import java.util.GregorianCalendar;
@@ -29,6 +29,7 @@
private static final float ALTITUDE_OF_CHENGDU = 500f;
private static final long TEST_TIME = new GregorianCalendar(2010, 5, 1).getTimeInMillis();
+ @Presubmit
public void testGeomagneticField() {
GeomagneticField geomagneticField = new GeomagneticField(LATITUDE_OF_CHENGDU,
LONGITUDE_OF_CHENGDU, ALTITUDE_OF_CHENGDU, TEST_TIME);
diff --git a/tests/tests/hardware/src/android/hardware/cts/SensorBatchingFifoTest.java b/tests/tests/hardware/src/android/hardware/cts/SensorBatchingFifoTest.java
index 2443004..1db2d51 100644
--- a/tests/tests/hardware/src/android/hardware/cts/SensorBatchingFifoTest.java
+++ b/tests/tests/hardware/src/android/hardware/cts/SensorBatchingFifoTest.java
@@ -24,6 +24,7 @@
import android.hardware.cts.helpers.TestSensorEnvironment;
import android.hardware.cts.helpers.sensoroperations.TestSensorOperation;
import android.hardware.cts.helpers.sensorverification.FifoLengthVerification;
+import android.platform.test.annotations.Presubmit;
import java.util.concurrent.TimeUnit;
@@ -46,6 +47,7 @@
PackageManager.FEATURE_HIFI_SENSORS);
}
+ @Presubmit
public void testAccelerometerFifoLength() throws Throwable {
if (!mHasHifiSensors) return;
runBatchingSensorFifoTest(
diff --git a/tests/tests/hardware/src/android/hardware/cts/SensorIntegrationTests.java b/tests/tests/hardware/src/android/hardware/cts/SensorIntegrationTests.java
index 302ce72..bcd1734 100644
--- a/tests/tests/hardware/src/android/hardware/cts/SensorIntegrationTests.java
+++ b/tests/tests/hardware/src/android/hardware/cts/SensorIntegrationTests.java
@@ -90,6 +90,7 @@
context,
sensorType,
shouldEmulateSensorUnderLoad(),
+ true, /* isIntegrationTest */
sensor.getMinDelay(),
MAX_REPORTING_LATENCY_US);
TestSensorOperation batchingOperation =
@@ -143,6 +144,7 @@
context,
sensorType,
shouldEmulateSensorUnderLoad(),
+ true, /* isIntegrationTest */
generateSamplingRateInUs(sensorType),
generateReportLatencyInUs());
TestSensorOperation sensorOperation =
diff --git a/tests/tests/hardware/src/android/hardware/cts/SensorTest.java b/tests/tests/hardware/src/android/hardware/cts/SensorTest.java
index 2bbf053..95a76b8 100644
--- a/tests/tests/hardware/src/android/hardware/cts/SensorTest.java
+++ b/tests/tests/hardware/src/android/hardware/cts/SensorTest.java
@@ -44,6 +44,7 @@
import android.os.HandlerThread;
import android.os.PowerManager;
import android.os.SystemClock;
+import android.platform.test.annotations.Presubmit;
import android.util.Log;
import java.util.ArrayList;
@@ -200,6 +201,7 @@
// Some sensors like proximity, significant motion etc. are defined as wake-up sensors by
// default. Check if the wake-up flag is set correctly.
+ @Presubmit
public void testWakeUpFlags() {
final int TYPE_WAKE_GESTURE = 23;
final int TYPE_GLANCE_GESTURE = 24;
@@ -241,6 +243,7 @@
}
}
+ @Presubmit
public void testSensorStringTypes() {
for (Sensor sensor : mSensorList) {
if (sensor.getType() < MAX_OFFICIAL_ANDROID_SENSOR_TYPE &&
@@ -314,10 +317,14 @@
// TODO: remove when parameterized tests are supported (see SensorBatchingTests.java)
@TimeoutReq(minutes=20)
public void testBatchAndFlush() throws Exception {
+ // TODO - replace this constant once method to do so is made available
+ final int SENSOR_TYPE_DEVICE_PRIVATE_BASE = 0x10000;
SensorCtsHelper.sleep(3, TimeUnit.SECONDS);
ArrayList<Throwable> errorsFound = new ArrayList<>();
for (Sensor sensor : mSensorList) {
- verifyRegisterListenerCallFlush(sensor, null /* handler */, errorsFound);
+ if (sensor.getType() < SENSOR_TYPE_DEVICE_PRIVATE_BASE) {
+ verifyRegisterListenerCallFlush(sensor, null /* handler */, errorsFound);
+ }
}
assertOnErrors(errorsFound);
}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorEnvironment.java b/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorEnvironment.java
index 47c8313..6ef7938 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorEnvironment.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorEnvironment.java
@@ -23,6 +23,8 @@
import java.util.concurrent.TimeUnit;
+/* TODO: Refactor constructors into a builder */
+
/**
* A class that encapsulates base environment information for the {@link SensorOperation}.
* The environment is self contained and carries its state around all the sensor test framework.
@@ -41,6 +43,7 @@
private final int mSamplingPeriodUs;
private final int mMaxReportLatencyUs;
private final boolean mIsDeviceSuspendTest;
+ private final boolean mIsIntegrationTest;
/**
* Constructs an environment for sensor testing.
@@ -131,6 +134,34 @@
* Constructs an environment for sensor testing.
*
* @param context The context for the test
+ * @param sensorType The type of the sensor under test
+ * @param sensorMightHaveMoreListeners Whether the sensor under test is acting under load
+ * @param isIntegrationTest Whether this is an integration test (more than one sensor actived)
+ * @param samplingPeriodUs The requested collection period for the sensor under test
+ * @param maxReportLatencyUs The requested collection report latency for the sensor under test
+ *
+ * @deprecated Use variants with {@link Sensor} objects.
+ */
+ @Deprecated
+ public TestSensorEnvironment(
+ Context context,
+ int sensorType,
+ boolean sensorMightHaveMoreListeners,
+ boolean isIntegrationTest,
+ int samplingPeriodUs,
+ int maxReportLatencyUs) {
+ this(context,
+ getSensor(context, sensorType),
+ sensorMightHaveMoreListeners,
+ isIntegrationTest,
+ samplingPeriodUs,
+ maxReportLatencyUs);
+ }
+
+ /**
+ * Constructs an environment for sensor testing.
+ *
+ * @param context The context for the test
* @param sensor The sensor under test
* @param samplingPeriodUs The requested collection period for the sensor under test
* @param maxReportLatencyUs The requested collection report latency for the sensor under test
@@ -176,15 +207,46 @@
Context context,
Sensor sensor,
boolean sensorMightHaveMoreListeners,
+ boolean isIntegrationTest,
+ int samplingPeriodUs,
+ int maxReportLatencyUs) {
+ this(context,
+ sensor,
+ sensorMightHaveMoreListeners,
+ samplingPeriodUs,
+ maxReportLatencyUs,
+ false /* isDeviceSuspendTest */,
+ isIntegrationTest);
+ }
+
+ public TestSensorEnvironment(
+ Context context,
+ Sensor sensor,
+ boolean sensorMightHaveMoreListeners,
int samplingPeriodUs,
int maxReportLatencyUs,
boolean isDeviceSuspendTest) {
+ this(context, sensor, sensorMightHaveMoreListeners,
+ samplingPeriodUs, maxReportLatencyUs,
+ false /* isDeviceSuspendTest */,
+ false /* isIntegrationTest */);
+ }
+
+ public TestSensorEnvironment(
+ Context context,
+ Sensor sensor,
+ boolean sensorMightHaveMoreListeners,
+ int samplingPeriodUs,
+ int maxReportLatencyUs,
+ boolean isDeviceSuspendTest,
+ boolean isIntegrationTest) {
mContext = context;
mSensor = sensor;
mSensorMightHaveMoreListeners = sensorMightHaveMoreListeners;
mSamplingPeriodUs = samplingPeriodUs;
mMaxReportLatencyUs = maxReportLatencyUs;
mIsDeviceSuspendTest = isDeviceSuspendTest;
+ mIsIntegrationTest = isIntegrationTest;
}
/**
@@ -265,6 +327,7 @@
}
/**
+ * Calculate the maximum expected sampling period in us.
* @return The maximum acceptable actual sampling period of this sensor.
* For continuous sensors, this is higher than {@link #getExpectedSamplingPeriodUs()}
* because sensors are allowed to run up to 10% slower than requested.
@@ -282,6 +345,20 @@
return (int) (expectedSamplingPeriodUs / MAXIMUM_EXPECTED_SAMPLING_FREQUENCY_MULTIPLIER);
}
+
+ /**
+ * Calculate the allowed sensor start delay.
+ *
+ * CDD Section 7.3:
+ * MUST report the first sensor sample within 400 milliseconds + 2 * sample_time of the
+ * sensor being activated. It is acceptable for this sample to have an accuracy of 0.
+ *
+ * [CDD] Keep this updated with CDD.
+ */
+ public long getAllowedSensorStartDelay() {
+ return TimeUnit.MILLISECONDS.toMicros(400) + 2 * getMaximumExpectedSamplingPeriodUs();
+ }
+
/**
* @return The number of axes in the coordinate system of the sensor under test.
*/
@@ -378,5 +455,9 @@
public boolean isDeviceSuspendTest() {
return mIsDeviceSuspendTest;
}
+
+ public boolean isIntegrationTest() {
+ return mIsIntegrationTest;
+ }
}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorEventListener.java b/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorEventListener.java
index dbe7c15..2da6a3b 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorEventListener.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorEventListener.java
@@ -194,7 +194,8 @@
* It will overwrite the file if it already exists, the file is created in a relative directory
* named 'events' under the sensor test directory (part of external storage).
*/
- public void logCollectedEventsToFile(String fileName, long deviceWakeUpTimeMs)
+ public void logCollectedEventsToFile(String fileName, long deviceWakeUpTimeMs,
+ long testStartTimeMs, long testStopTimeMs)
throws IOException {
StringBuilder builder = new StringBuilder();
builder.append("Sensor='").append(mEnvironment.getSensor()).append("', ");
@@ -203,7 +204,11 @@
builder.append("RequestedSamplingPeriod=")
.append(mEnvironment.getRequestedSamplingPeriodUs()).append("us, ");
builder.append("MaxReportLatency=")
- .append(mEnvironment.getMaxReportLatencyUs()).append("us");
+ .append(mEnvironment.getMaxReportLatencyUs()).append("us, ");
+ builder.append("StartedTimestamp=")
+ .append(testStartTimeMs).append("ms, ");
+ builder.append("StoppedTimestamp=")
+ .append(testStopTimeMs).append("ms");
synchronized (mCollectedEvents) {
int i = 0, j = 0;
while (i < mCollectedEvents.size() && j < mTimeStampFlushCompleteEvents.size()) {
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/TestSensorOperation.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/TestSensorOperation.java
index 779bb49..5ef2d3c 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/TestSensorOperation.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/TestSensorOperation.java
@@ -66,6 +66,8 @@
private final Executor mExecutor;
private final Handler mHandler;
private long mDeviceWakeUpTimeMs = -1;
+ private long mStartTimeMs = -1;
+ private long mStopTimeMs = -1;
/**
* An interface that defines an abstraction for operations to be performed by the
@@ -124,20 +126,21 @@
getStats().addValue("sensor_name", mEnvironment.getSensor().getName());
TestSensorEventListener listener = new TestSensorEventListener(mEnvironment, mHandler);
+ mStartTimeMs = SystemClock.elapsedRealtime();
if (mEnvironment.isDeviceSuspendTest()) {
SuspendStateMonitor suspendStateMonitor = new SuspendStateMonitor();
- long startTimeMs = SystemClock.elapsedRealtime();
// Device should go into suspend here.
mExecutor.execute(mSensorManager, listener);
- long endTimeMs = SystemClock.elapsedRealtime();
+ mStopTimeMs = SystemClock.elapsedRealtime();
// Check if the device has gone into suspend during test execution.
mDeviceWakeUpTimeMs = suspendStateMonitor.getLastWakeUpTime();
suspendStateMonitor.cancel();
Assert.assertTrue("Device did not go into suspend during test execution",
- startTimeMs < mDeviceWakeUpTimeMs &&
- mDeviceWakeUpTimeMs < endTimeMs);
+ mStartTimeMs < mDeviceWakeUpTimeMs &&
+ mDeviceWakeUpTimeMs < mStopTimeMs);
} else {
mExecutor.execute(mSensorManager, listener);
+ mStopTimeMs = SystemClock.elapsedRealtime();
}
boolean failed = false;
@@ -147,8 +150,8 @@
failed |= evaluateResults(collectedEvents, verification, sb);
}
+ trySaveCollectedEvents(parent, listener);
if (failed) {
- trySaveCollectedEvents(parent, listener);
String msg = SensorCtsHelper
.formatAssertionMessage("VerifySensorOperation", mEnvironment, sb.toString());
getStats().addValue(SensorStats.ERROR, msg);
@@ -213,7 +216,8 @@
}
try {
- listener.logCollectedEventsToFile(sanitizedFileName, mDeviceWakeUpTimeMs);
+ listener.logCollectedEventsToFile(sanitizedFileName, mDeviceWakeUpTimeMs,
+ mStartTimeMs, mStopTimeMs);
} catch (IOException e) {
Log.w(TAG, "Unable to save collected events to file: " + sanitizedFileName, e);
}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventBasicVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventBasicVerification.java
index 1e82b78..670c065 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventBasicVerification.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventBasicVerification.java
@@ -18,6 +18,7 @@
import junit.framework.Assert;
+import android.os.Build;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.cts.helpers.SensorStats;
@@ -28,15 +29,23 @@
import java.util.concurrent.TimeUnit;
/**
- * A {@link ISensorVerification} which verifies if the collected sensor events have any obvious
+ * A {@link ISensorVerification} which verifies if the collected sensor events have any obvious
* problems, such as no sample, wrong sensor type, etc.
*/
public class EventBasicVerification extends AbstractSensorVerification {
public static final String PASSED_KEY = "event_basic_passed";
- private static final long ALLOWED_SENSOR_DELIVERING_DELAY_US =
+ // allowed time from registration to sensor start sampling
+ private static final long ALLOWED_SENSOR_START_DELAY_US =
TimeUnit.MILLISECONDS.toMicros(1000);
+ // allowed time for entire sensor system to send sample to test app
+ private static final long ALLOWED_SENSOR_EVENT_LATENCY_US =
+ TimeUnit.MILLISECONDS.toMicros(1000);
+
+ // mercy added for recently added test. remove this mercy factor for next letter release.
+ private final float NUM_EVENT_MERCY_FACTOR; // 0~1, 0 means most strict
+
private final long mExpectedMinNumEvent;
private final Object mSensor;
private long mNumEvent;
@@ -56,6 +65,12 @@
mNumEvent = 0;
mWrongSensorObserved = false;
+
+ if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
+ NUM_EVENT_MERCY_FACTOR = 0;
+ } else {
+ NUM_EVENT_MERCY_FACTOR = 0.3f;
+ }
}
/**
@@ -69,25 +84,79 @@
TestSensorEnvironment environment,
long testDurationUs) {
- long minTestDurationUs;
- long batchUs = environment.getMaxReportLatencyUs();
+ // The calculation is still OK if sampleUs is not the actual sensor hardware
+ // sample period since the actual sample period by definition only goes smaller, which
+ // result in more samples.
long sampleUs = environment.getExpectedSamplingPeriodUs();
- if (batchUs > 0) {
- // test duration deduct allowed delivering latency and portion of time to deliver batch
- // (which will be 10% of the batching time)
- long effectiveTime = testDurationUs - ALLOWED_SENSOR_DELIVERING_DELAY_US - batchUs/10;
- // allow part of last batch to be partially delivered (>80%)
- minTestDurationUs = Math.max(
- effectiveTime/batchUs * batchUs - batchUs/5,
- environment.getExpectedSamplingPeriodUs());
+ long askedBatchUs = environment.getMaxReportLatencyUs();
+
+ long reservedFifoUs = sampleUs * environment.getSensor().getFifoReservedEventCount(); //>=0
+
+ // max() prevent loop-hole if HAL specify smaller max fifo than reserved fifo.
+ long maximumFifoUs = Math.max(
+ sampleUs * environment.getSensor().getFifoMaxEventCount(), reservedFifoUs); //>=0
+
+ long effectiveDurationUs = Math.max(testDurationUs -
+ Math.max(ALLOWED_SENSOR_START_DELAY_US, environment.getAllowedSensorStartDelay()) -
+ ALLOWED_SENSOR_EVENT_LATENCY_US, 0);
+
+ boolean isSingleSensorTest = !environment.isIntegrationTest();
+
+ long expectedMinUs;
+ if (isSingleSensorTest) {
+ // When the sensor under test is the only one active, max fifo size is assumed to be
+ // available.
+ long expectedBatchUs = Math.min(maximumFifoUs, askedBatchUs);
+ if (expectedBatchUs > 0) {
+ // This sensor should be running in batching mode.
+ expectedMinUs =
+ effectiveDurationUs / expectedBatchUs * expectedBatchUs
+ - expectedBatchUs / 5;
+ } else {
+ // streaming, allow actual rate to be as slow as 80% of the asked rate.
+ expectedMinUs = effectiveDurationUs * 4 / 5;
+ }
} else {
- minTestDurationUs =
- Math.max(testDurationUs - ALLOWED_SENSOR_DELIVERING_DELAY_US,
- environment.getExpectedSamplingPeriodUs());
- }
+ // More convoluted case. Batch size can vary from reserved fifo length to max fifo size.
+ long minBatchUs = Math.min(reservedFifoUs, askedBatchUs);
+ long maxBatchUs = Math.min(maximumFifoUs, askedBatchUs);
- long expectedMinNumEvent = minTestDurationUs / environment.getExpectedSamplingPeriodUs();
+ // The worst scenario happens when the sensor batch time being just above half of the
+ // test time, then the test can only receive one batch which halves the expected number
+ // of samples. The expected number of samples received have a lower bound like the
+ // figure below.
+ //
+ // expected samples
+ // ^
+ // | ______
+ // |\ /
+ // | \ /
+ // | \ /
+ // | \ /
+ // | \ /
+ // | \ /
+ // | \/
+ // |
+ // |
+ // |
+ // |
+ // +------------+-----------+-------> actual batch size in time
+ // 0 1/2*testDuration testDuration
+ //
+ long worstBatchUs = effectiveDurationUs / 2 + 1;
+ if ((minBatchUs > worstBatchUs) == (maxBatchUs > worstBatchUs)) {
+ // same side
+ double ratio = Math.min(Math.abs(worstBatchUs - minBatchUs),
+ Math.abs(worstBatchUs - maxBatchUs)) / (double)worstBatchUs;
+ expectedMinUs = (long)((ratio + 1) / 2 * testDurationUs) * 4 / 5;
+ } else {
+ // the worst case is possible
+ expectedMinUs = worstBatchUs * 4 / 5;
+ }
+ }
+ long expectedMinNumEvent = expectedMinUs/sampleUs;
+
return new EventBasicVerification(expectedMinNumEvent, environment.getSensor());
}
@@ -103,7 +172,7 @@
stats.addValue(SensorStats.EVENT_COUNT_EXPECTED_KEY, mExpectedMinNumEvent);
stats.addValue(SensorStats.WRONG_SENSOR_KEY, mWrongSensorObserved);
- boolean enoughSample = mNumEvent >= mExpectedMinNumEvent;
+ boolean enoughSample = mNumEvent >= mExpectedMinNumEvent * ( 1 - NUM_EVENT_MERCY_FACTOR );
boolean noWrongSensor = !mWrongSensorObserved;
boolean success = enoughSample && noWrongSensor;
@@ -111,7 +180,8 @@
if (!success) {
Assert.fail(String.format("Failed due to (%s%s)",
- enoughSample?"":"insufficient events, ",
+ enoughSample?"":"insufficient events " + mNumEvent + "/" +
+ mExpectedMinNumEvent + ", ",
noWrongSensor?"":"wrong sensor observed, "));
}
}
diff --git a/tests/tests/hardware/src/android/hardware/fingerprint/cts/FingerprintManagerTest.java b/tests/tests/hardware/src/android/hardware/fingerprint/cts/FingerprintManagerTest.java
index 95704b9..f11b6bc 100644
--- a/tests/tests/hardware/src/android/hardware/fingerprint/cts/FingerprintManagerTest.java
+++ b/tests/tests/hardware/src/android/hardware/fingerprint/cts/FingerprintManagerTest.java
@@ -21,6 +21,7 @@
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintManager.AuthenticationCallback;
import android.os.CancellationSignal;
+import android.platform.test.annotations.Presubmit;
import android.test.AndroidTestCase;
/**
@@ -65,6 +66,7 @@
}
}
+ @Presubmit
public void test_hasFingerprintHardware() {
if (!mHasFingerprintManager) {
return; // skip test if no fingerprint feature
diff --git a/tests/tests/icu/AndroidTest.xml b/tests/tests/icu/AndroidTest.xml
index 299956d..18c95cd 100644
--- a/tests/tests/icu/AndroidTest.xml
+++ b/tests/tests/icu/AndroidTest.xml
@@ -20,5 +20,6 @@
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="runner" value="android.icu.cts.IcuTestRunner" /><!-- override AJUR -->
<option name="package" value="android.icu.cts" />
+ <option name="runtime-hint" value="30m19s" />
</test>
-</configuration>
\ No newline at end of file
+</configuration>
diff --git a/tests/tests/icu/resources/android/icu/cts/expectations/icu-known-failures.txt b/tests/tests/icu/resources/android/icu/cts/expectations/icu-known-failures.txt
index b92e754..9ca52c5 100644
--- a/tests/tests/icu/resources/android/icu/cts/expectations/icu-known-failures.txt
+++ b/tests/tests/icu/resources/android/icu/cts/expectations/icu-known-failures.txt
@@ -49,16 +49,10 @@
name: "android.icu.dev.test.format.PluralRulesTest#testOverUnderflow",
bug: "27566754"
},
-// The following are known to be broken but the reason is not yet known. They are expected to
-// succeed and so will be run and will fail but that is intentional so that they do not get
-// forgotten and are investigated to determine whether it is correct behavior on Android or a bug
-// that needs fixing.
{
- description: "Broken and not yet triaged",
- names: [
- "android.icu.dev.test.format.NumberFormatTest#TestDataDrivenJDK",
- ],
- result: "SUCCESS"
+ description: "Checks differences in DecimalFormat classes from ICU4J and JDK but on Android java.text.DecimalFormat is implemented in terms of ICU4J",
+ name: "android.icu.dev.test.format.NumberFormatTest#TestDataDrivenJDK",
+ bug: "27711713"
},
{
description: "Collation rules data has been removed from ICU4J data on Android",
diff --git a/tests/tests/keystore/Android.mk b/tests/tests/keystore/Android.mk
index 7ba87e3..8e86c0e 100644
--- a/tests/tests/keystore/Android.mk
+++ b/tests/tests/keystore/Android.mk
@@ -23,7 +23,8 @@
# Tag this module as a cts test artifact
LOCAL_COMPATIBILITY_SUITE := cts
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner core-tests-support
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ ctstestrunner core-tests-support platform-test-annotations
LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/tests/tests/keystore/src/android/keystore/cts/CipherTest.java b/tests/tests/keystore/src/android/keystore/cts/CipherTest.java
index 60a48e0..57a7648 100644
--- a/tests/tests/keystore/src/android/keystore/cts/CipherTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/CipherTest.java
@@ -16,6 +16,7 @@
package android.keystore.cts;
+import android.platform.test.annotations.Presubmit;
import android.security.keystore.KeyProperties;
import android.security.keystore.KeyProtection;
import android.test.AndroidTestCase;
@@ -221,6 +222,7 @@
private static final byte[] AES256_KAT_KEY_BYTES =
HexEncoding.decode("cf601cc10aaf434d1f01747136aff222af7fb426d101901712214c3fea18125f");
+ @Presubmit
public void testAlgorithmList() {
// Assert that Android Keystore Provider exposes exactly the expected Cipher
// transformations. We don't care whether the transformations are exposed via aliases, as
diff --git a/tests/tests/location/AndroidTest.xml b/tests/tests/location/AndroidTest.xml
index 178e8d1..4ac850e 100644
--- a/tests/tests/location/AndroidTest.xml
+++ b/tests/tests/location/AndroidTest.xml
@@ -21,7 +21,7 @@
</target_preparer>
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.location.cts" />
- <option name="runtime-hint" value="1m26s" />
+ <option name="runtime-hint" value="18m8s" />
</test>
</configuration>
diff --git a/tests/tests/location/src/android/location/cts/GnssMeasurementTest.java b/tests/tests/location/src/android/location/cts/GnssMeasurementTest.java
index ce81402..3ae7b3c 100644
--- a/tests/tests/location/src/android/location/cts/GnssMeasurementTest.java
+++ b/tests/tests/location/src/android/location/cts/GnssMeasurementTest.java
@@ -51,7 +51,6 @@
measurement.setState(14);
measurement.setSvid(15);
measurement.setTimeOffsetNanos(16.0);
- measurement.setPseudorangeRateCorrected(true);
}
private static void verifyTestValues(GnssMeasurement measurement) {
@@ -74,7 +73,6 @@
assertEquals(14, measurement.getState());
assertEquals(15, measurement.getSvid());
assertEquals(16.0, measurement.getTimeOffsetNanos());
- assertTrue(measurement.isPseudorangeRateCorrected());
}
public void testWriteToParcel() {
@@ -95,11 +93,6 @@
verifyTestValues(newMeasurement);
}
- public void testPseudorangeRateCorrected() {
- GnssMeasurement measurement = new GnssMeasurement();
- measurement.isPseudorangeRateCorrected();
- }
-
public void testSetReset() {
GnssMeasurement measurement = new GnssMeasurement();
setTestValues(measurement);
diff --git a/tests/tests/location/src/android/location/cts/GnssMeasurementsEventCallbackTest.java b/tests/tests/location/src/android/location/cts/GnssMeasurementsEventCallbackTest.java
index 930c344..72addce 100644
--- a/tests/tests/location/src/android/location/cts/GnssMeasurementsEventCallbackTest.java
+++ b/tests/tests/location/src/android/location/cts/GnssMeasurementsEventCallbackTest.java
@@ -16,6 +16,8 @@
package android.location.cts;
+import android.location.GnssClock;
+import android.location.GnssMeasurement;
import android.location.GnssMeasurementsEvent;
import android.test.AndroidTestCase;
@@ -25,7 +27,11 @@
public void testAllMethodsExist() {
GnssMeasurementsEvent.Callback callback = new MockCallback();
- GnssMeasurementsEvent event = new GnssMeasurementsEvent(null, null);
+ GnssClock clock = new GnssClock();
+ GnssMeasurement m1 = new GnssMeasurement();
+ GnssMeasurement m2 = new GnssMeasurement();
+ GnssMeasurementsEvent event = new GnssMeasurementsEvent(
+ clock, new GnssMeasurement[] {m1, m2});
callback.onGnssMeasurementsReceived(event);
callback.onStatusChanged(GnssMeasurementsEvent.STATUS_READY);
}
diff --git a/tests/tests/location/src/android/location/cts/GnssMeasurementsEventTest.java b/tests/tests/location/src/android/location/cts/GnssMeasurementsEventTest.java
index 33cf924..51af03d 100644
--- a/tests/tests/location/src/android/location/cts/GnssMeasurementsEventTest.java
+++ b/tests/tests/location/src/android/location/cts/GnssMeasurementsEventTest.java
@@ -28,7 +28,11 @@
public class GnssMeasurementsEventTest extends AndroidTestCase {
public void testDescribeContents() {
- GnssMeasurementsEvent event = new GnssMeasurementsEvent(null, null);
+ GnssClock clock = new GnssClock();
+ GnssMeasurement m1 = new GnssMeasurement();
+ GnssMeasurement m2 = new GnssMeasurement();
+ GnssMeasurementsEvent event = new GnssMeasurementsEvent(
+ clock, new GnssMeasurement[] {m1, m2});
event.describeContents();
}
diff --git a/tests/tests/location/src/android/location/cts/GnssNavigationMessageEventCallbackTest.java b/tests/tests/location/src/android/location/cts/GnssNavigationMessageEventCallbackTest.java
index a548122..0589c57 100644
--- a/tests/tests/location/src/android/location/cts/GnssNavigationMessageEventCallbackTest.java
+++ b/tests/tests/location/src/android/location/cts/GnssNavigationMessageEventCallbackTest.java
@@ -16,6 +16,7 @@
package android.location.cts;
+import android.location.GnssNavigationMessage;
import android.location.GnssNavigationMessageEvent;
import android.test.AndroidTestCase;
@@ -25,7 +26,8 @@
public void testAllMethodsExist() {
GnssNavigationMessageEvent.Callback callback = new MockCallback();
- GnssNavigationMessageEvent event = new GnssNavigationMessageEvent(null);
+ GnssNavigationMessage message = new GnssNavigationMessage();
+ GnssNavigationMessageEvent event = new GnssNavigationMessageEvent(message);
callback.onGnssNavigationMessageReceived(event);
callback.onStatusChanged(GnssNavigationMessageEvent.STATUS_READY);
}
diff --git a/tests/tests/location/src/android/location/cts/GnssNavigationMessageEventTest.java b/tests/tests/location/src/android/location/cts/GnssNavigationMessageEventTest.java
index 730bd525..0772092 100644
--- a/tests/tests/location/src/android/location/cts/GnssNavigationMessageEventTest.java
+++ b/tests/tests/location/src/android/location/cts/GnssNavigationMessageEventTest.java
@@ -23,7 +23,8 @@
public class GnssNavigationMessageEventTest extends AndroidTestCase {
public void testDescribeContents() {
- GnssNavigationMessageEvent event = new GnssNavigationMessageEvent(null);
+ GnssNavigationMessage message = new GnssNavigationMessage();
+ GnssNavigationMessageEvent event = new GnssNavigationMessageEvent(message);
event.describeContents();
}
diff --git a/tests/tests/location/src/android/location/cts/GnssNavigationMessageTest.java b/tests/tests/location/src/android/location/cts/GnssNavigationMessageTest.java
index 87814c5..a4e18e6 100644
--- a/tests/tests/location/src/android/location/cts/GnssNavigationMessageTest.java
+++ b/tests/tests/location/src/android/location/cts/GnssNavigationMessageTest.java
@@ -93,7 +93,7 @@
private static void setTestValues(GnssNavigationMessage message) {
message.setData(new byte[] {1, 2, 3, 4});
message.setMessageId(5);
- message.setStatus(GnssNavigationMessage.PARCELABLE_WRITE_RETURN_VALUE);
+ message.setStatus(GnssNavigationMessage.STATUS_PARITY_REBUILT);
message.setSubmessageId(6);
message.setSvid(7);
message.setType(GnssNavigationMessage.TYPE_GPS_L2CNAV);
@@ -101,12 +101,13 @@
private static void verifyTestValues(GnssNavigationMessage message) {
byte[] data = message.getData();
+ assertEquals(4, data.length);
assertEquals(1, data[0]);
assertEquals(2, data[1]);
assertEquals(3, data[2]);
assertEquals(4, data[3]);
assertEquals(5, message.getMessageId());
- assertEquals(GnssNavigationMessage.PARCELABLE_WRITE_RETURN_VALUE, message.getStatus());
+ assertEquals(GnssNavigationMessage.STATUS_PARITY_REBUILT, message.getStatus());
assertEquals(6, message.getSubmessageId());
assertEquals(7, message.getSvid());
assertEquals(GnssNavigationMessage.TYPE_GPS_L2CNAV, message.getType());
diff --git a/tests/tests/location/src/android/location/cts/LocationManagerTest.java b/tests/tests/location/src/android/location/cts/LocationManagerTest.java
index 85de83d..36358ab 100644
--- a/tests/tests/location/src/android/location/cts/LocationManagerTest.java
+++ b/tests/tests/location/src/android/location/cts/LocationManagerTest.java
@@ -477,7 +477,7 @@
}
try {
- mManager.removeUpdates( (LocationListener) null );
+ mManager.removeUpdates((LocationListener) null );
fail("Should throw IllegalArgumentException if listener is null!");
} catch (IllegalArgumentException e) {
// expected
@@ -566,7 +566,12 @@
updateLocation(latitude3, longitude3);
assertFalse(listener.hasCalledOnLocationChanged(TEST_TIME_OUT));
- mManager.requestSingleUpdate(LocationManager.GPS_PROVIDER, mPendingIntent);
+ try {
+ mManager.requestSingleUpdate(LocationManager.GPS_PROVIDER, mPendingIntent);
+ fail("Should throw IllegalArgumentException if PendingIntent is null!");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
try {
mManager.requestSingleUpdate(LocationManager.GPS_PROVIDER, (LocationListener) null,
@@ -584,7 +589,7 @@
}
try {
- mManager.removeUpdates( (LocationListener) null );
+ mManager.removeUpdates((LocationListener) null );
fail("Should throw IllegalArgumentException if listener is null!");
} catch (IllegalArgumentException e) {
// expected
diff --git a/tests/tests/media/Android.mk b/tests/tests/media/Android.mk
index 7a92a2c..879c72b 100644
--- a/tests/tests/media/Android.mk
+++ b/tests/tests/media/Android.mk
@@ -44,9 +44,9 @@
# include both the 32 and 64 bit versions
LOCAL_MULTILIB := both
-LOCAL_STATIC_JAVA_LIBRARIES := ctsmediautil ctsdeviceutil compatibility-device-util ctstestserver ctstestrunner
+LOCAL_STATIC_JAVA_LIBRARIES := ctsmediautil ctsdeviceutil compatibility-device-util ctstestserver ctstestrunner ndkaudio
-LOCAL_JNI_SHARED_LIBRARIES := libctsmediacodec_jni libaudio_jni libnativehelper_compat_libc++
+LOCAL_JNI_SHARED_LIBRARIES := libctsmediacodec_jni libaudio_jni libnativehelper_compat_libc++ libndkaudioLib
LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/tests/tests/media/libaudiojni/appendix-b-1-2-recording.cpp b/tests/tests/media/libaudiojni/appendix-b-1-2-recording.cpp
index 5f6f3aa..e628c6f 100644
--- a/tests/tests/media/libaudiojni/appendix-b-1-2-recording.cpp
+++ b/tests/tests/media/libaudiojni/appendix-b-1-2-recording.cpp
@@ -56,8 +56,6 @@
SLDataLocator_IODevice locator_mic;
SLDeviceVolumeItf devicevolumeItf;
SLDataSink audioSink;
- SLDataLocator_URI uri;
- SLDataFormat_MIME mime;
int i;
SLboolean required[MAX_NUMBER_INTERFACES];
diff --git a/tests/tests/media/libaudiojni/audio-record-native.cpp b/tests/tests/media/libaudiojni/audio-record-native.cpp
index 5f72ab3..f771d9b 100644
--- a/tests/tests/media/libaudiojni/audio-record-native.cpp
+++ b/tests/tests/media/libaudiojni/audio-record-native.cpp
@@ -405,7 +405,6 @@
}
static void BufferQueueCallback(SLBufferQueueItf queueItf, void *pContext) {
- SLresult res;
// naked native record
AudioRecordNative *record = (AudioRecordNative *)pContext;
record->bufferQueueCallback(queueItf);
diff --git a/tests/tests/media/libaudiojni/audio-track-native.cpp b/tests/tests/media/libaudiojni/audio-track-native.cpp
index 23e6a0f..ce8bf91 100644
--- a/tests/tests/media/libaudiojni/audio-track-native.cpp
+++ b/tests/tests/media/libaudiojni/audio-track-native.cpp
@@ -345,7 +345,6 @@
}
static void BufferQueueCallback(SLBufferQueueItf queueItf, void *pContext) {
- SLresult res;
// naked native track
AudioTrackNative *track = (AudioTrackNative *)pContext;
track->bufferQueueCallback(queueItf);
diff --git a/tests/tests/media/libmediandkjni/native-media-jni.cpp b/tests/tests/media/libmediandkjni/native-media-jni.cpp
index f15a196..546ef2b 100644
--- a/tests/tests/media/libmediandkjni/native-media-jni.cpp
+++ b/tests/tests/media/libmediandkjni/native-media-jni.cpp
@@ -263,7 +263,7 @@
int t = AMediaExtractor_getSampleTrackIndex(ex);
if (t >=0) {
ssize_t bufidx = AMediaCodec_dequeueInputBuffer(codec[t], 5000);
- ALOGV("track %d, input buffer %d", t, bufidx);
+ ALOGV("track %d, input buffer %zd", t, bufidx);
if (bufidx >= 0) {
size_t bufsize;
uint8_t *buf = AMediaCodec_getInputBuffer(codec[t], bufidx, &bufsize);
@@ -408,7 +408,7 @@
while (!sawOutputEOS) {
ssize_t bufidx = AMediaCodec_dequeueInputBuffer(codec, 5000);
- ALOGV("input buffer %d", bufidx);
+ ALOGV("input buffer %zd", bufidx);
if (bufidx >= 0) {
size_t bufsize;
uint8_t *buf = AMediaCodec_getInputBuffer(codec, bufidx, &bufsize);
@@ -481,7 +481,7 @@
return false;
} else if (!strncmp(mime, "audio/", 6) || !strncmp(mime, "video/", 6)) {
ssize_t tidx = AMediaMuxer_addTrack(muxer, format);
- ALOGI("track %d -> %d format %s", i, tidx, s);
+ ALOGI("track %d -> %zd format %s", i, tidx, s);
AMediaExtractor_selectTrack(ex, i);
} else {
ALOGE("expected audio or video mime type, got %s", mime);
@@ -536,7 +536,7 @@
int64_t duration = 0;
if (!AMediaFormat_getInt64(format, AMEDIAFORMAT_KEY_DURATION, &duration)
|| duration != 123456789123456789ll) {
- ALOGE("AMediaFormat_getInt64 fail: %lld", duration);
+ ALOGE("AMediaFormat_getInt64 fail: %lld", (long long) duration);
return false;
}
diff --git a/tests/tests/media/libndkaudio/Android.mk b/tests/tests/media/libndkaudio/Android.mk
new file mode 100644
index 0000000..f3d7983
--- /dev/null
+++ b/tests/tests/media/libndkaudio/Android.mk
@@ -0,0 +1,57 @@
+# Copyright (C) 2016 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_MODULE := libndkaudioLib
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_C_INCLUDES := \
+ frameworks/wilhelm/include \
+ frameworks/wilhelm/src/android \
+ $(call include-path-for, wilhelm)
+
+LOCAL_SRC_FILES := \
+ OpenSLESUtils.cpp \
+ AudioPlayer.cpp \
+ AudioSource.cpp \
+ PeriodicAudioSource.cpp \
+ SystemParams.cpp \
+ WaveTableGenerator.cpp \
+ WaveTableOscillator.cpp \
+ com_android_ndkaudio_AudioPlayer.cpp \
+ AudioRecorder.cpp \
+ com_android_ndkaudio_AudioRecorder.cpp
+
+LOCAL_CXX_STL := libc++_static
+
+LOCAL_SHARED_LIBRARIES := liblog libOpenSLES
+
+include $(BUILD_SHARED_LIBRARY)
+
+#
+# ndkaudio - java
+#
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := ndkaudio
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_CERTIFICATE := platform
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/tests/tests/media/libndkaudio/AndroidManifest.xml b/tests/tests/media/libndkaudio/AndroidManifest.xml
new file mode 100644
index 0000000..3fbb9ad
--- /dev/null
+++ b/tests/tests/media/libndkaudio/AndroidManifest.xml
@@ -0,0 +1,10 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.ndkaudio"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <uses-sdk
+ android:minSdkVersion="23"
+ android:targetSdkVersion="23" />
+
+</manifest>
diff --git a/tests/tests/media/libndkaudio/AudioPlayer.cpp b/tests/tests/media/libndkaudio/AudioPlayer.cpp
new file mode 100644
index 0000000..9df1658
--- /dev/null
+++ b/tests/tests/media/libndkaudio/AudioPlayer.cpp
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include <assert.h>
+
+#include <android/log.h>
+
+#include <SLES/OpenSLES.h>
+#include <SLES/OpenSLES_Android.h>
+
+#include "AudioPlayer.h"
+
+#include "AudioSource.h"
+#include "SystemParams.h"
+#include "OpenSLESUtils.h"
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+/*
+ * OpenSL ES Stuff
+ */
+static const char* TAG = "AudioPlayer";
+
+// engine interfaces
+static SLObjectItf engineObject = 0;
+static SLEngineItf engineItf;
+
+// output mix interfaces
+static SLObjectItf outputMixObject = 0;
+
+// this callback handler is called every time a buffer finishes playing
+static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf /*bq*/, void *context)
+{
+ // __android_log_print(ANDROID_LOG_INFO, TAG, "bqPlayerCallback()");
+ ((ndkaudio::AudioPlayer*)context)->enqueBuffer();
+}
+
+static void OpenSLEngine() {
+ SLresult result;
+
+ // create engine
+ result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
+ assert(SL_RESULT_SUCCESS == result);
+ // __android_log_print(ANDROID_LOG_INFO, TAG, "OpenSLEngine() - engineObject:%p", engineObject);
+
+ // realize the engine
+ result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
+ // __android_log_print(ANDROID_LOG_INFO, TAG, "Realize() engine result:%s", getSLErrStr(result));
+ assert(SL_RESULT_SUCCESS == result);
+
+ // get the engine interface, which is needed in order to create other objects
+ result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineItf);
+ // __android_log_print(ANDROID_LOG_INFO, TAG, "GetInterface() engine:%p result:%s", engineItf, getSLErrStr(result));
+ assert(SL_RESULT_SUCCESS == result);
+
+ // get the output mixer
+ result = (*engineItf)->CreateOutputMix(engineItf, &outputMixObject, 0, 0, 0);
+ // __android_log_print(ANDROID_LOG_INFO, TAG, "CreateOutputMix() mix:%p result:%s", outputMixObject, getSLErrStr(result));
+ assert(SL_RESULT_SUCCESS == result);
+
+ // realize the output mix
+ result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
+ // __android_log_print(ANDROID_LOG_INFO, TAG, "Realize() result:%s", getSLErrStr(result));
+ assert(SL_RESULT_SUCCESS == result);
+}
+
+static void CloseSLEngine() {
+ __android_log_print(ANDROID_LOG_INFO, TAG, "CloseSLEngine()");
+
+ // destroy output mix object, and invalidate all associated interfaces
+ if (outputMixObject != NULL) {
+ (*outputMixObject)->Destroy(outputMixObject);
+ outputMixObject = NULL;
+ }
+
+ if (engineObject != NULL) {
+ (*engineObject)->Destroy(engineObject);
+ engineObject = NULL;
+ engineItf = NULL;
+ }
+}
+
+/*
+ * AudioPlayer
+ */
+namespace ndkaudio {
+
+AudioPlayer::AudioPlayer() {
+ source_ = NULL;
+
+ sampleRate_ = SystemParams::getSampleRate();
+ numChannels_ = 1;
+
+ numPlayBuffFrames_ = SystemParams::getNumBufferFrames();
+
+ playing_ = false;
+
+ time_ = 0;
+
+ bqPlayerObject_ = NULL;
+ bq_ = NULL;
+ bqPlayerPlay_ = NULL;
+ configItf_ = NULL;
+
+ OpenSLEngine();
+}
+
+AudioPlayer::~AudioPlayer() {
+ CloseSLEngine();
+
+ delete[] playBuff_;
+ playBuff_ = 0;
+}
+
+SLresult AudioPlayer::Open(int numChannels, AudioSource* source) {
+ source_ = source;
+
+ SLresult result;
+
+ numChannels_ = numChannels;
+
+ int internalBuffFactor = 1;
+
+ playBuff_ =
+ new float[numPlayBuffFrames_ * numChannels_ * internalBuffFactor];
+ playBuffSizeInBytes_ = numPlayBuffFrames_ * numChannels_ * sizeof(float)
+ * internalBuffFactor;
+
+ sampleRate_ = SystemParams::getSampleRate();
+
+// __android_log_print(ANDROID_LOG_INFO, TAG,
+// "AudioPlayer::Open(chans:%d, rate:%d)", numChannels,
+// sampleRate_);
+
+ // configure audio source
+ SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {
+ SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, // locatorType
+ 1}; // numBuffers
+
+ // SLuint32 chanMask = SL_SPEAKER_FRONT_LEFT|SL_SPEAKER_FRONT_RIGHT;
+ SLAndroidDataFormat_PCM_EX format_pcm = {SL_ANDROID_DATAFORMAT_PCM_EX, // formatType
+ (SLuint32) numChannels_, // numChannels
+ (SLuint32)(sampleRate_ * 1000), // milliSamplesPerSec
+ 32, // bitsPerSample
+ 32, // containerSize;
+ (SLuint32) chanCountToChanMask(numChannels_), // channelMask
+ SL_BYTEORDER_LITTLEENDIAN, // endianness
+ SL_ANDROID_PCM_REPRESENTATION_FLOAT}; // representation
+ SLDataSource audioSrc = {&loc_bufq, &format_pcm};
+
+ // configure audio sink
+ SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX,
+ outputMixObject};
+ SLDataSink audioSnk = {&loc_outmix, NULL};
+
+ const SLInterfaceID ids[] =
+ {SL_IID_BUFFERQUEUE, SL_IID_ANDROIDCONFIGURATION};
+ const SLboolean req[] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
+
+ // The Player
+ result = (*engineItf)->CreateAudioPlayer(engineItf, &bqPlayerObject_,
+ &audioSrc, &audioSnk,
+ sizeof(ids) / sizeof(ids[0]), ids,
+ req);
+// __android_log_print(ANDROID_LOG_INFO, TAG,
+// "CreateAudioPlayer() result:%s, bqPlayerObject_:%p",
+// getSLErrStr(result), bqPlayerObject_);
+ assert(SL_RESULT_SUCCESS == result);
+
+ return result;
+}
+
+void AudioPlayer::Close() {
+ __android_log_write(ANDROID_LOG_INFO, TAG, "CloseSLPlayer()");
+
+ if (bqPlayerObject_ != NULL) {
+ (*bqPlayerObject_)->Destroy(bqPlayerObject_);
+ bqPlayerObject_ = NULL;
+
+ // invalidate any interfaces
+ bqPlayerPlay_ = NULL;
+ bq_ = NULL;
+ }
+}
+
+SLresult AudioPlayer::RealizePlayer() {
+ SLresult result;
+
+ result = (*bqPlayerObject_)->Realize(bqPlayerObject_, SL_BOOLEAN_FALSE);
+// __android_log_print(ANDROID_LOG_INFO, TAG,
+// "Realize player object result:%s", getSLErrStr(result));
+ assert(SL_RESULT_SUCCESS == result);
+
+ result = (*bqPlayerObject_)->GetInterface(bqPlayerObject_, SL_IID_PLAY,
+ &bqPlayerPlay_);
+// __android_log_print(ANDROID_LOG_INFO, TAG,
+// "get player interface result:%s, bqPlayerPlay_:%p",
+// getSLErrStr(result), bqPlayerPlay_);
+ assert(SL_RESULT_SUCCESS == result);
+
+ // The BufferQueue
+ result = (*bqPlayerObject_)->GetInterface(bqPlayerObject_,
+ SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
+ &bq_);
+// __android_log_print(ANDROID_LOG_INFO, TAG,
+// "get bufferqueue interface:%p result:%s", bq_,
+// getSLErrStr(result));
+ assert(SL_RESULT_SUCCESS == result);
+
+ // The register BufferQueue callback
+ result = (*bq_)->RegisterCallback(bq_, bqPlayerCallback, this);
+// __android_log_print(ANDROID_LOG_INFO, TAG, "register callback result:%s",
+// getSLErrStr(result));
+ assert(SL_RESULT_SUCCESS == result);
+
+ return result;
+}
+
+SLresult AudioPlayer::RealizeRoutingProxy() {
+ SLresult result;
+
+ // The Config interface (for routing)
+ result = (*bqPlayerObject_)->GetInterface(bqPlayerObject_,
+ SL_IID_ANDROIDCONFIGURATION,
+ (void*) &configItf_);
+// __android_log_print(ANDROID_LOG_INFO, TAG, "get Config result:%s",
+// getSLErrStr(result));
+ assert(SL_RESULT_SUCCESS == result);
+
+ return result;
+}
+
+SLresult AudioPlayer::Start() {
+ // __android_log_print(ANDROID_LOG_INFO, TAG, "Start()");
+ playing_ = true;
+
+ // set the player's state to playing
+ SLresult result = (*bqPlayerPlay_)->SetPlayState(bqPlayerPlay_,
+ SL_PLAYSTATE_PLAYING);
+ // __android_log_print(ANDROID_LOG_INFO, TAG, "SetPlayState() result:%s", getSLErrStr(result));
+ assert(SL_RESULT_SUCCESS == result);
+
+ enqueBuffer();
+
+ return result;
+}
+
+void AudioPlayer::Stop() {
+ // __android_log_print(ANDROID_LOG_INFO, TAG, "Stop()");
+ playing_ = false;
+}
+
+SLresult AudioPlayer::enqueBuffer() {
+ // __android_log_print(ANDROID_LOG_INFO, TAG, "AudioPlayer::enqueBuffer()");
+ if (playing_) {
+ long dataSizeInSamples = source_->getData(time_++, playBuff_,
+ numPlayBuffFrames_,
+ source_->getNumChannels());
+ return (*bq_)->Enqueue(bq_, playBuff_, playBuffSizeInBytes_);
+ } else {
+ (*bqPlayerPlay_)->SetPlayState(bqPlayerPlay_, SL_PLAYSTATE_STOPPED);
+ return 0;
+ }
+}
+
+} // namespace ndkaudio
+
diff --git a/tests/tests/media/libndkaudio/AudioPlayer.h b/tests/tests/media/libndkaudio/AudioPlayer.h
new file mode 100644
index 0000000..4d17a18
--- /dev/null
+++ b/tests/tests/media/libndkaudio/AudioPlayer.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#ifndef AUDIOPLAYER_H_
+#define AUDIOPLAYER_H_
+
+#include <SLES/OpenSLES.h>
+#include <SLES/OpenSLES_Android.h>
+
+namespace ndkaudio {
+
+class AudioSource;
+
+class AudioPlayer {
+ public:
+ AudioPlayer();
+ ~AudioPlayer();
+
+ SLresult Open(int numChannels, AudioSource* filler);
+ void Close();
+
+ SLresult RealizePlayer();
+ SLresult RealizeRoutingProxy();
+
+ SLresult Start();
+ void Stop();
+
+ inline bool isPlaying() {
+ return playing_;
+ }
+ inline AudioSource* getSource() {
+ return source_;
+ }
+
+ // This is public because it needs to be called by the OpenSL ES callback, but it should not
+ // be called by anyone else.
+ SLresult enqueBuffer();
+
+ SLPlayItf getPlayerObject() {
+ return bqPlayerPlay_;
+ }
+
+ SLAndroidConfigurationItf getConfigItf() {
+ return configItf_;
+ }
+
+ private:
+ // void fill();
+
+ AudioSource* source_;
+ int sampleRate_;
+ int numChannels_;
+
+ float* playBuff_;
+ long numPlayBuffFrames_;
+ long playBuffSizeInBytes_;
+
+ bool playing_;
+
+ long time_;
+
+ // OpenSLES stuff
+ SLObjectItf bqPlayerObject_;
+ SLPlayItf bqPlayerPlay_;
+ SLAndroidSimpleBufferQueueItf bq_;
+ SLAndroidConfigurationItf configItf_;
+};
+
+} // namespace ndkaudio
+
+#endif /* AUDIOPLAYER_H_ */
diff --git a/tests/tests/media/libndkaudio/AudioRecorder.cpp b/tests/tests/media/libndkaudio/AudioRecorder.cpp
new file mode 100644
index 0000000..9026c60
--- /dev/null
+++ b/tests/tests/media/libndkaudio/AudioRecorder.cpp
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+#include <assert.h>
+
+#include <android/log.h>
+
+#include <SLES/OpenSLES.h>
+#include <SLES/OpenSLES_Android.h>
+
+#include "AudioRecorder.h"
+
+#include "AudioSink.h"
+#include "SystemParams.h"
+#include "OpenSLESUtils.h"
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#define ARRAYSIZE(a) sizeof((a))/sizeof((a)[0])
+
+using namespace ndkaudio;
+
+static const char* TAG = "AudioRecorder";
+
+#define NB_BUFFERS_IN_QUEUE 1
+
+static void RecCallback(SLRecordItf /*recorderItf_*/, void * /*context*/, SLuint32 event)
+{
+ if (SL_RECORDEVENT_HEADATNEWPOS & event) {
+ // __android_log_print(ANDROID_LOG_INFO, TAG, "SL_RECORDEVENT_HEADATNEWPOS");
+ }
+
+ if (SL_RECORDEVENT_HEADATMARKER & event) {
+ // __android_log_print(ANDROID_LOG_INFO, TAG, "SL_RECORDEVENT_HEADATMARKER");
+ }
+
+ if (SL_RECORDEVENT_BUFFER_FULL & event) {
+ // __android_log_print(ANDROID_LOG_INFO, TAG, "SL_RECORDEVENT_BUFFER_FULL");
+ }
+}
+
+#define BUFFER_SIZE_IN_FRAMES 8192
+
+static float* recBuffer = NULL;
+
+static void RecBufferQueueCallback(SLAndroidSimpleBufferQueueItf /*queueItf*/, void * context)
+{
+ AudioRecorder* recorder = (AudioRecorder*)context;
+ // __android_log_print(ANDROID_LOG_INFO, TAG, "RecBufferQueueCallback()");
+ recorder->enqueBuffer();
+}
+
+/*
+ * The OpenSL ES code was derived from:
+ * frameworks/wilhelm/tests/examples/slesTestRecBuffQueue.cpp
+ */
+AudioRecorder::AudioRecorder()
+ : sink_(NULL),
+ recording_(false),
+ sampleRate_(48000),
+ numChannels_(0),
+ numBufferSamples_(0),
+ engineObj_(NULL),
+ engineItf_(NULL),
+ recorderObj_(NULL),
+ recorderItf_(NULL),
+ recBuffQueueItf_(NULL),
+ configItf_(NULL)
+{}
+
+AudioRecorder::~AudioRecorder() {}
+
+void AudioRecorder::Open(int numChannels, AudioSink* sink) {
+ sink_ = sink;
+ numChannels_ = numChannels;
+ // __android_log_print(ANDROID_LOG_INFO, TAG, "AudioRecorder::Open() - numChannels:%d", numChannels);
+
+ SLresult result;
+
+ numBufferSamples_ = BUFFER_SIZE_IN_FRAMES * numChannels_;
+ recBuffer = new float[numBufferSamples_];
+
+ SLEngineOption EngineOption[] = {
+ {(SLuint32) SL_ENGINEOPTION_THREADSAFE, (SLuint32) SL_BOOLEAN_TRUE}
+ };
+
+ /* Create the OpenSL ES Engine object */
+ result = slCreateEngine(&engineObj_, 1, EngineOption, 0, NULL, NULL);
+ assert(SL_RESULT_SUCCESS == result);
+ // __android_log_print(ANDROID_LOG_INFO, TAG, "slCreateEngine() - engineObj_:%p", engineObj_);
+
+ /* Realizing the SL Engine in synchronous mode. */
+ result = (*engineObj_)->Realize(engineObj_, SL_BOOLEAN_FALSE);
+ assert(SL_RESULT_SUCCESS == result);
+ // __android_log_print(ANDROID_LOG_INFO, TAG, "(*engineObj_)->Realize()");
+
+ result = (*engineObj_)->GetInterface(engineObj_, SL_IID_ENGINE, (void*)&engineItf_);
+ assert(SL_RESULT_SUCCESS == result);
+ // __android_log_print(ANDROID_LOG_INFO, TAG, "GetInterface() - engineItf_:%p", engineItf_);
+
+ // Configuration of the recorder
+ SLboolean required[] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
+ SLInterfaceID iidArray[] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE, SL_IID_ANDROIDCONFIGURATION};
+
+ SLDataLocator_IODevice ioDevice;
+ ioDevice.locatorType = SL_DATALOCATOR_IODEVICE;
+ ioDevice.deviceType = SL_IODEVICE_AUDIOINPUT;
+ ioDevice.deviceID = SL_DEFAULTDEVICEID_AUDIOINPUT;
+ ioDevice.device = NULL;
+
+ SLDataSource recSource;
+ recSource.pLocator = (void *) &ioDevice;
+ recSource.pFormat = NULL;
+
+ /* Setup the (OpenSL ES) data sink */
+ SLDataLocator_AndroidSimpleBufferQueue recBuffQueue;
+ recBuffQueue.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
+ recBuffQueue.numBuffers = NB_BUFFERS_IN_QUEUE;
+
+ SLAndroidDataFormat_PCM_EX pcm;
+ pcm.formatType = SL_ANDROID_DATAFORMAT_PCM_EX;
+ pcm.numChannels = numChannels_;
+ pcm.sampleRate = sampleRate_ * 1000; // milliHz
+ pcm.bitsPerSample = 32;
+ pcm.containerSize = 32;
+ pcm.channelMask = chanCountToChanMask(numChannels_);
+ pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
+ pcm.representation = SL_ANDROID_PCM_REPRESENTATION_FLOAT;
+
+ SLDataSink recDest;
+ recDest.pLocator = (void *) &recBuffQueue;
+ recDest.pFormat = (void * ) &pcm;
+
+ /* Create the audio recorder */
+ result = (*engineItf_)->CreateAudioRecorder(engineItf_, &recorderObj_, &recSource, &recDest,
+ ARRAYSIZE(iidArray), iidArray, required);
+ assert(SL_RESULT_SUCCESS == result);
+ // __android_log_print(ANDROID_LOG_INFO, TAG, "CreateAudioRecorder() - recorderObj_:%p", recorderObj_);
+}
+
+void AudioRecorder::Close() {
+ /* Shutdown OpenSL ES */
+ (*engineObj_)->Destroy(engineObj_);
+ engineObj_ = 0;
+}
+
+void AudioRecorder::RealizeRecorder() {
+ SLresult result;
+
+ /* Realize the recorder in synchronous mode. */
+ result = (*recorderObj_)->Realize(recorderObj_, SL_BOOLEAN_FALSE);
+ assert(SL_RESULT_SUCCESS == result);
+ // __android_log_print(ANDROID_LOG_INFO, TAG, "Recorder realized");
+
+ /* Get the record interface which is implicit */
+ result = (*recorderObj_)->GetInterface(recorderObj_, SL_IID_RECORD, (void*)&recorderItf_);
+ assert(SL_RESULT_SUCCESS == result);
+ // __android_log_print(ANDROID_LOG_INFO, TAG, "GetInterface() recorderItf_:%p", recorderItf_);
+
+ /* Set up the recorder callback to get events during the recording */
+ // __android_log_print(ANDROID_LOG_INFO, TAG, "SetMarkerPosition()");
+ result = (*recorderItf_)->SetMarkerPosition(recorderItf_, 2000);
+ assert(SL_RESULT_SUCCESS == result);
+
+ // __android_log_print(ANDROID_LOG_INFO, TAG, "SetPositionUpdatePeriod()");
+ result = (*recorderItf_)->SetPositionUpdatePeriod(recorderItf_, 500);
+ assert(SL_RESULT_SUCCESS == result);
+
+ // __android_log_print(ANDROID_LOG_INFO, TAG, "SetCallbackEventsMask()");
+ result = (*recorderItf_)->SetCallbackEventsMask(recorderItf_, SL_RECORDEVENT_HEADATMARKER | SL_RECORDEVENT_HEADATNEWPOS);
+ assert(SL_RESULT_SUCCESS == result);
+
+ // __android_log_print(ANDROID_LOG_INFO, TAG, "RegisterCallback() - Events");
+ result = (*recorderItf_)->RegisterCallback(recorderItf_, RecCallback, NULL);
+ assert(SL_RESULT_SUCCESS == result);
+
+ /* Get the buffer queue interface which was explicitly requested */
+ result = (*recorderObj_)->GetInterface(recorderObj_, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, (void*)&recBuffQueueItf_);
+ assert(SL_RESULT_SUCCESS == result);
+ // __android_log_print(ANDROID_LOG_INFO, TAG, "GetInterface() recBuffQueueItf_:%p", recBuffQueueItf_);
+
+ result = (*recBuffQueueItf_)->RegisterCallback(recBuffQueueItf_, RecBufferQueueCallback, (void*)this);
+ assert(SL_RESULT_SUCCESS == result);
+ // __android_log_print(ANDROID_LOG_INFO, TAG, "RegisterCallback() - Buffers");
+}
+
+void AudioRecorder::RealizeRoutingProxy() {
+ SLresult result;
+ // The Config interface (for routing)
+ result = (*recorderObj_)->GetInterface(recorderObj_, SL_IID_ANDROIDCONFIGURATION, (void*)&configItf_);
+ // __android_log_print(ANDROID_LOG_INFO, TAG, "get Config result:%s", getSLErrStr(result));
+ assert(SL_RESULT_SUCCESS == result);
+}
+
+void AudioRecorder::Start() {
+ SLresult result;
+
+ /* Enqueue buffers to map the region of memory allocated to store the recorded data */
+ // __android_log_print(ANDROID_LOG_INFO, TAG, "Enqueueing buffer");
+ int bufferSizeInBytes = BUFFER_SIZE_IN_FRAMES * numChannels_ * sizeof(float);
+
+ enqueBuffer();
+
+ /* ------------------------------------------------------ */
+ /* Start recording */
+ // __android_log_print(ANDROID_LOG_INFO, TAG, "Start Recording");
+ recording_ = true;
+ result = (*recorderItf_)->SetRecordState(recorderItf_, SL_RECORDSTATE_RECORDING);
+ assert(SL_RESULT_SUCCESS == result);
+}
+
+void AudioRecorder::Stop() {
+ recording_ = false;
+
+ SLresult result;
+ result = (*recorderItf_)->SetRecordState(recorderItf_, SL_RECORDSTATE_STOPPED);
+}
+
+SLresult AudioRecorder::enqueBuffer() {
+ SLresult result;
+ int bufferSizeInBytes = numBufferSamples_ * sizeof(float);
+ // __android_log_print(ANDROID_LOG_INFO, TAG, "Enque %d bytes", bufferSizeInBytes);
+ result = (*recBuffQueueItf_)->Enqueue(recBuffQueueItf_, recBuffer, bufferSizeInBytes);
+ assert(SL_RESULT_SUCCESS == result);
+
+ return result;
+}
+
+float* AudioRecorder::GetRecordBuffer() {
+ return recBuffer;
+}
diff --git a/tests/tests/media/libndkaudio/AudioRecorder.h b/tests/tests/media/libndkaudio/AudioRecorder.h
new file mode 100644
index 0000000..93a03c3
--- /dev/null
+++ b/tests/tests/media/libndkaudio/AudioRecorder.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#ifndef _AUDIORECORDER_H_
+#define _AUDIORECORDER_H_
+
+#include <SLES/OpenSLES.h>
+#include <SLES/OpenSLES_Android.h>
+
+namespace ndkaudio {
+
+class AudioSink;
+
+class AudioRecorder {
+ public:
+ AudioRecorder();
+ ~AudioRecorder();
+
+ void Open(int numChannels, AudioSink* sink);
+ void Close();
+
+ void RealizeRecorder();
+ void RealizeRoutingProxy();
+
+ void Start();
+ void Stop();
+
+ inline bool isRecording() {
+ return recording_;
+ }
+ inline AudioSink* getSink() {
+ return sink_;
+ }
+
+ SLAndroidConfigurationItf getConfigItf() {
+ return configItf_;
+ }
+
+ // public, but don't call directly (called by the OSLES callback)
+ SLresult enqueBuffer();
+
+ int GetNumBufferSamples() {
+ return numBufferSamples_;
+ }
+ float* GetRecordBuffer();
+
+ private:
+ AudioSink* sink_;
+ bool recording_;
+
+ int sampleRate_;
+ int numChannels_;
+
+ int numBufferSamples_;
+
+ // OpenSL ES stuff
+ // - Engine
+ SLObjectItf engineObj_;
+ SLEngineItf engineItf_;
+
+ // - Recorder
+ SLObjectItf recorderObj_;
+ SLRecordItf recorderItf_;
+ SLAndroidSimpleBufferQueueItf recBuffQueueItf_;
+ SLAndroidConfigurationItf configItf_;
+};
+
+} // namespace ndkaudio
+
+#endif // _AUDIORECORDER_H_
diff --git a/tests/tests/media/libndkaudio/AudioSink.h b/tests/tests/media/libndkaudio/AudioSink.h
new file mode 100644
index 0000000..933abc9
--- /dev/null
+++ b/tests/tests/media/libndkaudio/AudioSink.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#ifndef _AUDIOSINK_H_
+#define _AUDIOSINK_H_
+
+namespace ndkaudio {
+
+class AudioSink {
+ public:
+ AudioSink();
+ virtual ~AudioSink();
+
+ virtual bool put(float * buff, int numFrames, int numChannels) =0;
+};
+
+} // namespace ndkaudio
+
+#endif // _AUDIOSINK_H_
+
diff --git a/tests/tests/media/libndkaudio/AudioSource.cpp b/tests/tests/media/libndkaudio/AudioSource.cpp
new file mode 100644
index 0000000..0363d2c
--- /dev/null
+++ b/tests/tests/media/libndkaudio/AudioSource.cpp
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include "AudioSource.h"
+
+#include "SystemParams.h"
+
+namespace ndkaudio {
+
+static const char* TAG = "AudioSource";
+
+AudioSource::AudioSource(int numChannels)
+ : numChannels_(numChannels),
+ numBuffFrames_(SystemParams::getNumBufferFrames()),
+ lastReadSize_(0)
+{}
+
+AudioSource::~AudioSource()
+{}
+
+} // namespace ndkaudio
diff --git a/tests/tests/media/libndkaudio/AudioSource.h b/tests/tests/media/libndkaudio/AudioSource.h
new file mode 100644
index 0000000..bd1b40a
--- /dev/null
+++ b/tests/tests/media/libndkaudio/AudioSource.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#ifndef AUDIOSOURCE_H_
+#define AUDIOSOURCE_H_
+
+namespace ndkaudio {
+
+class AudioSource {
+ public:
+ AudioSource(int numChannels);
+ virtual ~AudioSource();
+
+ int getLastReadSize() {
+ return lastReadSize_;
+ }
+ int getNumChannels() {
+ return numChannels_;
+ }
+ int getNumBufferFrames() {
+ return numBuffFrames_;
+ }
+
+ virtual int getData(long time, float * buff, int numFrames,
+ int numChannels) =0;
+
+ protected:
+ int numChannels_;
+ int lastReadSize_;
+ int numBuffFrames_;
+};
+
+} //namespace ndkaudio
+
+#endif /* AUDIOSOURCE_H_ */
diff --git a/tests/tests/media/libndkaudio/OpenSLESUtils.cpp b/tests/tests/media/libndkaudio/OpenSLESUtils.cpp
new file mode 100644
index 0000000..7302ef5
--- /dev/null
+++ b/tests/tests/media/libndkaudio/OpenSLESUtils.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include "OpenSLESUtils.h"
+
+#include <SLES/OpenSLES.h>
+#include <SLES/OpenSLES_Android.h>
+
+/*
+ * OSLES Helpers
+ */
+static const char* errStrings[] = {
+ "SL_RESULT_SUCCESS", // 0)
+ "SL_RESULT_PRECONDITIONS_VIOLATE", // 1
+ "SL_RESULT_PARAMETER_INVALID", // 2
+ "SL_RESULT_MEMORY_FAILURE", // 3
+ "SL_RESULT_RESOURCE_ERROR", // 4
+ "SL_RESULT_RESOURCE_LOST", // 5
+ "SL_RESULT_IO_ERROR", // 6
+ "SL_RESULT_BUFFER_INSUFFICIENT", // 7
+ "SL_RESULT_CONTENT_CORRUPTED", // 8
+ "SL_RESULT_CONTENT_UNSUPPORTED", // 9
+ "SL_RESULT_CONTENT_NOT_FOUND", // 10
+ "SL_RESULT_PERMISSION_DENIED", // 11
+ "SL_RESULT_FEATURE_UNSUPPORTED", // 12
+ "SL_RESULT_INTERNAL_ERROR", // 13
+ "SL_RESULT_UNKNOWN_ERROR", // 14
+ "SL_RESULT_OPERATION_ABORTED", // 15
+ "SL_RESULT_CONTROL_LOST" // 16
+};
+
+const char * getSLErrStr(int code) {
+ return errStrings[code];
+}
+
+// These will wind up in <SLES/OpenSLES_Android.h>
+#define SL_ANDROID_SPEAKER_QUAD (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT \
+ | SL_SPEAKER_BACK_LEFT | SL_SPEAKER_BACK_RIGHT)
+
+#define SL_ANDROID_SPEAKER_5DOT1 (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT \
+ | SL_SPEAKER_FRONT_CENTER | SL_SPEAKER_LOW_FREQUENCY| SL_SPEAKER_BACK_LEFT \
+ | SL_SPEAKER_BACK_RIGHT)
+
+#define SL_ANDROID_SPEAKER_7DOT1 (SL_ANDROID_SPEAKER_5DOT1 | SL_SPEAKER_SIDE_LEFT \
+ |SL_SPEAKER_SIDE_RIGHT)
+
+int chanCountToChanMask(int chanCount) {
+ int channelMask = 0;
+
+ switch (chanCount) {
+ case 1:
+ channelMask = SL_SPEAKER_FRONT_CENTER;
+ break;
+
+ case 2:
+ channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
+ break;
+
+ case 4: // Quad
+ channelMask = SL_ANDROID_SPEAKER_QUAD;
+ break;
+
+ case 6: // 5.1
+ channelMask = SL_ANDROID_SPEAKER_5DOT1;
+ break;
+
+ case 8: // 7.1
+ channelMask = SL_ANDROID_SPEAKER_7DOT1;
+ break;
+ }
+ return channelMask;
+}
diff --git a/tests/tests/media/libndkaudio/OpenSLESUtils.h b/tests/tests/media/libndkaudio/OpenSLESUtils.h
new file mode 100644
index 0000000..89dde3d
--- /dev/null
+++ b/tests/tests/media/libndkaudio/OpenSLESUtils.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#ifndef _OPENSLESUTILS_H_
+#define _OPENSLESUTILS_H_
+
+const char * getSLErrStr(int code);
+int chanCountToChanMask(int chanCount);
+
+#endif // _OPENSLESUTILS_H_
diff --git a/tests/tests/media/libndkaudio/PeriodicAudioSource.cpp b/tests/tests/media/libndkaudio/PeriodicAudioSource.cpp
new file mode 100644
index 0000000..06c7e45
--- /dev/null
+++ b/tests/tests/media/libndkaudio/PeriodicAudioSource.cpp
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include "PeriodicAudioSource.h"
+
+namespace ndkaudio {
+
+PeriodicAudioSource::PeriodicAudioSource(int numChannels)
+ : AudioSource(numChannels), targetFreq_(1000.0f) {
+}
+
+} // namespace ndkaudio
diff --git a/tests/tests/media/libndkaudio/PeriodicAudioSource.h b/tests/tests/media/libndkaudio/PeriodicAudioSource.h
new file mode 100644
index 0000000..b1fc03e
--- /dev/null
+++ b/tests/tests/media/libndkaudio/PeriodicAudioSource.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#ifndef PERIODICAUDIOSOURCE_H_
+#define PERIODICAUDIOSOURCE_H_
+
+#include "AudioSource.h"
+
+namespace ndkaudio {
+
+class PeriodicAudioSource : public AudioSource {
+ public:
+ PeriodicAudioSource(int numChannels);
+
+ void setAudioFrequency(float freq) {
+ targetFreq_ = freq;
+ }
+
+ float calcCurrentFreq(long time);
+
+ protected:
+ float targetFreq_;
+};
+
+} // namespace ndkaudio
+
+#endif /* PERIODICAUDIOSOURCE_H_ */
diff --git a/tests/tests/media/libndkaudio/SystemParams.cpp b/tests/tests/media/libndkaudio/SystemParams.cpp
new file mode 100644
index 0000000..a7cde62
--- /dev/null
+++ b/tests/tests/media/libndkaudio/SystemParams.cpp
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include "SystemParams.h"
+
+namespace ndkaudio {
+
+int SystemParams::sysSampleRate_ = 48000;
+int SystemParams::sysBuffFrames_ = 480;
+
+void SystemParams::init(int sysSampleRate, int sysBuffFrames) {
+ sysSampleRate_ = sysSampleRate;
+ sysBuffFrames_ = sysBuffFrames;
+}
+
+} // namespace ndkaudio
diff --git a/tests/tests/media/libndkaudio/SystemParams.h b/tests/tests/media/libndkaudio/SystemParams.h
new file mode 100644
index 0000000..2eb26ea
--- /dev/null
+++ b/tests/tests/media/libndkaudio/SystemParams.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#ifndef SYSTEMPARAMS_H_
+#define SYSTEMPARAMS_H_
+
+namespace ndkaudio {
+
+class SystemParams {
+ public:
+ static void init(int sysSampleRate, int sysBuffFrames);
+
+ static int getSampleRate() {
+ return sysSampleRate_;
+ }
+ static int getNumBufferFrames() {
+ return sysBuffFrames_;
+ }
+
+ private:
+ static int sysSampleRate_;
+ static int sysBuffFrames_;
+};
+
+} // namespace ndkaudio
+
+#endif /* SYSTEMPARAMS_H_ */
diff --git a/tests/tests/media/libndkaudio/WaveTableGenerator.cpp b/tests/tests/media/libndkaudio/WaveTableGenerator.cpp
new file mode 100644
index 0000000..27cfa36
--- /dev/null
+++ b/tests/tests/media/libndkaudio/WaveTableGenerator.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include <math.h>
+
+#include <android/log.h>
+
+#include "WaveTableGenerator.h"
+
+static const float kPI = 3.14159265359; // close enough
+
+static const char* TAG = "WaveTableGenerator";
+
+namespace ndkaudio {
+
+float* WaveTableGenerator::genSinWave(int size, float maxValue) {
+ return genSinWave(size, maxValue, new float[size]);
+}
+
+float* WaveTableGenerator::genSinWave(int size, float maxValue, float* tbl) {
+ float incr = (kPI * 2.0f) / (float) size;
+ float val = 0.0f;
+ for (int index = 0; index < size; index++) {
+ tbl[index] = (float) sin(val) * maxValue;
+ val += incr;
+ }
+
+ return tbl;
+}
+
+} // namespace ndkaudio
diff --git a/tests/tests/media/libndkaudio/WaveTableGenerator.h b/tests/tests/media/libndkaudio/WaveTableGenerator.h
new file mode 100644
index 0000000..cd339b4
--- /dev/null
+++ b/tests/tests/media/libndkaudio/WaveTableGenerator.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#ifndef WAVETABLEGENERATOR_H_
+#define WAVETABLEGENERATOR_H_
+
+namespace ndkaudio {
+
+class WaveTableGenerator {
+ public:
+ // SINE
+ static float* genSinWave(int size, float maxValue);
+ static float* genSinWave(int size, float maxValue, float* tbl);
+};
+
+} // namespace ndkaudio
+
+#endif /* WAVETABLEGENERATOR_H_ */
diff --git a/tests/tests/media/libndkaudio/WaveTableOscillator.cpp b/tests/tests/media/libndkaudio/WaveTableOscillator.cpp
new file mode 100644
index 0000000..05d4a68
--- /dev/null
+++ b/tests/tests/media/libndkaudio/WaveTableOscillator.cpp
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include <android/log.h>
+
+static const char * TAG = "WaveTableOscillator";
+
+#include "WaveTableOscillator.h"
+#include "SystemParams.h"
+
+namespace ndkaudio {
+
+WaveTableOscillator::WaveTableOscillator(int numChannels, float* waveTable,
+ int waveTableSize)
+ : PeriodicAudioSource(numChannels),
+ waveTable_(waveTable),
+ waveTableSize_(waveTableSize),
+ fN_(0.0f),
+ srcPhase_(0.0f),
+ prevFillTime_(0)
+{
+ setWaveTable(waveTable, waveTableSize);
+}
+
+void WaveTableOscillator::setWaveTable(float* waveTable, int waveTableSize) {
+ waveTable_ = waveTable;
+ waveTableSize_ = waveTableSize - 1;
+
+ // The frequency that would be played if we took every sample from the table and
+ // played it at the system sample-rate. The "Nominal" frequency
+ fN_ = SystemParams::getSampleRate() / (float) waveTableSize_;
+}
+
+int WaveTableOscillator::getData(long time, float* outBuff, int numFrames,
+ int /*outChans*/) {
+ prevFillTime_ = time;
+
+ // Frequency - main
+ float currentFreq = targetFreq_;
+
+ float phaseIncr = currentFreq / fN_;
+
+// __android_log_print(ANDROID_LOG_INFO, TAG, "getData() freq:%f, fN_:%f, phs:%f incr:%f", currentFreq, fN_, srcPhase_, phaseIncr);
+
+ if (numChannels_ == 1) {
+ // calculate wave values
+ for (int dstIndex = 0; dstIndex < numFrames; ++dstIndex) {
+ // 'mod' back into the waveTable
+ if (srcPhase_ >= (float) waveTableSize_) {
+ srcPhase_ -= (float) waveTableSize_;
+ }
+
+ // linear-interpolate
+ int srcIndex = (int) srcPhase_;
+ float delta0 = srcPhase_ - srcIndex;
+ float delta1 = 1.0f - delta0;
+ outBuff[dstIndex] = ((waveTable_[srcIndex] * delta1)
+ + (waveTable_[srcIndex + 1] * delta0)) / 2.0f;
+
+ srcPhase_ += phaseIncr;
+ }
+ } else if (numChannels_ == 2) {
+ // calculate wave values
+ int dstIndex = 0;
+ for (int frameIndex = 0; frameIndex < numFrames; frameIndex++) {
+ // 'mod' back into the waveTable
+ if (srcPhase_ >= (float) waveTableSize_) {
+ srcPhase_ -= (float) waveTableSize_;
+ }
+
+ // linear-interpolate
+ int srcIndex = (int) srcPhase_;
+ float delta0 = srcPhase_ - srcIndex;
+ float delta1 = 1.0f - delta0;
+ float out = ((waveTable_[srcIndex] * delta1)
+ + (waveTable_[srcIndex + 1] * delta0)) / 2.0f;
+
+ outBuff[dstIndex++] = out;
+ outBuff[dstIndex++] = out;
+
+ srcPhase_ += phaseIncr;
+ }
+ }
+
+// __android_log_print(ANDROID_LOG_INFO, TAG, " %d samples", numSamples);
+ return numFrames;
+}
+
+} // namespace ndkaudio
diff --git a/tests/tests/media/libndkaudio/WaveTableOscillator.h b/tests/tests/media/libndkaudio/WaveTableOscillator.h
new file mode 100644
index 0000000..28944bc
--- /dev/null
+++ b/tests/tests/media/libndkaudio/WaveTableOscillator.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#ifndef WAVETABLEOSCILLATOR_H_
+#define WAVETABLEOSCILLATOR_H_
+
+#include "PeriodicAudioSource.h"
+
+namespace ndkaudio {
+
+/*
+ * The assumption here is that the provided wave table contains 1 cycle of the wave
+ * and that the first and last samples are the same.
+ */
+class WaveTableOscillator : public PeriodicAudioSource {
+ public:
+ WaveTableOscillator(int numChannels, float* waveTable, int waveTableSize);
+
+ void setWaveTable(float* waveTable, int waveTableSize);
+
+ int getData(long time, float* outBuff, int numFrames, int outChans);
+
+ private:
+ float* waveTable_;
+ int waveTableSize_;
+
+ // 'nominal' frequency (i.e. how many times we step through the
+ // 1-cycle wave table in a second
+ float fN_;
+
+ // current pointer into the wave table
+ float srcPhase_;
+
+ // profiling
+ long prevFillTime_;
+};
+
+} // namespace ndkaudio
+
+#endif /* WAVETABLEOSCILLATOR_H_ */
diff --git a/tests/tests/media/libndkaudio/com_android_ndkaudio_AudioPlayer.cpp b/tests/tests/media/libndkaudio/com_android_ndkaudio_AudioPlayer.cpp
new file mode 100644
index 0000000..a5b480e
--- /dev/null
+++ b/tests/tests/media/libndkaudio/com_android_ndkaudio_AudioPlayer.cpp
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+#include <android/log.h>
+
+#include "com_android_ndkaudio_AudioPlayer.h"
+
+#include "AudioPlayer.h"
+#include "WaveTableGenerator.h"
+#include "WaveTableOscillator.h"
+#include "SystemParams.h"
+
+static const char* TAG = "_com_android_ndkaudio_AudioPlayer_";
+
+using namespace ndkaudio;
+
+static int numChannels = 2;
+static int waveTableSize = 0;
+static float * waveTable = 0;
+
+static WaveTableOscillator* waveTableSource;
+static AudioPlayer* nativePlayer;
+
+static SLresult lastSLResult = 0;
+
+extern "C" {
+
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioPlayer_Create(JNIEnv*, jobject) {
+ __android_log_print(ANDROID_LOG_INFO, TAG, "AudioPlayer_Create() ...");
+
+ if (nativePlayer == 0) {
+ waveTableSize = SystemParams::getNumBufferFrames();
+ waveTable = WaveTableGenerator::genSinWave(waveTableSize, 1.0f);
+ waveTableSource = new WaveTableOscillator(numChannels, waveTable, waveTableSize);
+
+ nativePlayer = new AudioPlayer();
+ nativePlayer->Open(numChannels, waveTableSource);
+ }
+}
+
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioPlayer_Destroy(JNIEnv*, jobject) {
+ __android_log_print(ANDROID_LOG_INFO, TAG, "AudioPlayer_Destroy() ...");
+ nativePlayer->Close();
+}
+
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioPlayer_RealizePlayer(JNIEnv*, jobject) {
+ __android_log_print(ANDROID_LOG_INFO, TAG, "AudioPlayer_RealizePlayer() ...");
+ nativePlayer->RealizePlayer();
+ }
+
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioPlayer_RealizeRoutingProxy(JNIEnv*, jobject) {
+ __android_log_print(ANDROID_LOG_INFO, TAG, "AudioPlayer_RealizeRoutingProxy() ...");
+ nativePlayer->RealizeRoutingProxy();
+ }
+
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioPlayer_Start(JNIEnv*, jobject) {
+ __android_log_print(ANDROID_LOG_INFO, TAG, "AudioPlayer_Start() ...");
+ nativePlayer->Start();
+}
+
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioPlayer_Stop(JNIEnv*, jobject) {
+ __android_log_print(ANDROID_LOG_INFO, TAG, "AudioPlayer_Stop() ...");
+ nativePlayer->Stop();
+}
+
+JNIEXPORT jobject JNICALL Java_com_android_ndkaudio_AudioPlayer_GetRoutingInterface(JNIEnv*, jobject) {
+ __android_log_print(ANDROID_LOG_INFO, TAG, "AudioPlayer_GetRoutingInterface() ...");
+
+ SLAndroidConfigurationItf configItf = nativePlayer->getConfigItf();
+ __android_log_print(ANDROID_LOG_INFO, TAG, " configItf:%p", configItf);
+ jobject routingObj = 0;
+ lastSLResult = (*configItf)->AcquireJavaProxy(configItf, SL_ANDROID_JAVA_PROXY_ROUTING, &routingObj);
+ __android_log_print(ANDROID_LOG_INFO, TAG, " routingObj:%p", routingObj);
+ return routingObj;
+}
+
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioPlayer_ReleaseRoutingInterface(JNIEnv*, jobject, jobject /*proxyObj*/) {
+ __android_log_print(ANDROID_LOG_INFO, TAG, "AudioPlayer_ReleaseRoutingInterface() ...");
+
+ SLAndroidConfigurationItf configItf = nativePlayer->getConfigItf();
+ lastSLResult = (*configItf)->ReleaseJavaProxy(configItf, SL_ANDROID_JAVA_PROXY_ROUTING/*, proxyObj*/);
+}
+
+JNIEXPORT long JNICALL Java_com_android_ndkaudio_AudioPlayer_GetLastSLResult(JNIEnv*, jobject) {
+ return lastSLResult;
+}
+
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioPlayer_ClearLastSLResult(JNIEnv*, jobject) {
+ lastSLResult = 0;
+}
+
+} // extern "C"
diff --git a/tests/tests/media/libndkaudio/com_android_ndkaudio_AudioPlayer.h b/tests/tests/media/libndkaudio/com_android_ndkaudio_AudioPlayer.h
new file mode 100644
index 0000000..e01d3ac
--- /dev/null
+++ b/tests/tests/media/libndkaudio/com_android_ndkaudio_AudioPlayer.h
@@ -0,0 +1,99 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class com_android_ndkaudio_AudioPlayer */
+
+#ifndef _Included_com_android_ndkaudio_AudioPlayer
+#define _Included_com_android_ndkaudio_AudioPlayer
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: com_android_ndkaudio_AudioPlayer
+ * Method: InitN
+ * Signature: ()V
+ */
+
+/*
+ * Class: com_android_ndkaudio_AudioPlayer
+ * Method: Create
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioPlayer_Create
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_android_ndkaudio_AudioPlayer
+ * Method: Destroy
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioPlayer_Destroy
+ (JNIEnv*, jobject);
+
+/*
+ * Class: com_android_ndkaudio_AudioPlayer
+ * Method: RealizePlayer
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioPlayer_RealizePlayer
+ (JNIEnv*, jobject);
+
+/*
+ * Class: com_android_ndkaudio_AudioPlayer
+ * Method: RealizeRoutingProxy
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioPlayer_RealizeRoutingProxy
+ (JNIEnv*, jobject);
+
+/*
+ * Class: com_android_ndkaudio_AudioPlayer
+ * Method: Start
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioPlayer_Start
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_android_ndkaudio_AudioPlayer
+ * Method: Stop
+ * Signature: ()android/
+ */
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioPlayer_Stop
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_android_ndkaudio_AudioPlayer
+ * Method: GetRoutingInterface
+ * Signature: ()Landroid/media/AudioRouting;
+ */
+JNIEXPORT jobject JNICALL Java_com_android_ndkaudio_AudioPlayer_GetRoutingInterface
+ (JNIEnv*, jobject);
+
+/*
+ * Class: com_android_ndkaudio_AudioPlayer
+ * Method: GetRoutingInterface
+ * Signature: (Landroid/media/AudioRouting;)V
+ */
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioPlayer_ReleaseRoutingInterface
+ (JNIEnv*, jobject, jobject);
+
+/*
+ * Class: com_android_ndkaudio_AudioPlayer
+ * Method: GetLastSLResult
+ * Signature: ()J
+ */
+JNIEXPORT long JNICALL Java_com_android_ndkaudio_AudioPlayer_GetLastSLResult
+ (JNIEnv*, jobject);
+
+/*
+ * Class: com_android_ndkaudio_AudioPlayer
+ * Method: ClearLastSLResult
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioPlayer_ClearLastSLResult
+ (JNIEnv*, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/tests/tests/media/libndkaudio/com_android_ndkaudio_AudioRecorder.cpp b/tests/tests/media/libndkaudio/com_android_ndkaudio_AudioRecorder.cpp
new file mode 100644
index 0000000..e7b6abd
--- /dev/null
+++ b/tests/tests/media/libndkaudio/com_android_ndkaudio_AudioRecorder.cpp
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+#include <android/log.h>
+
+#include "com_android_ndkaudio_AudioRecorder.h"
+
+#include "AudioRecorder.h"
+
+using namespace ndkaudio;
+
+static const char* TAG = "_com_android_ndkaudio_AudioRecorder_";
+
+static int numChannels = 2;
+
+static AudioRecorder* nativeRecorder;
+
+static SLresult lastSLResult = 0;
+extern "C" {
+
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioRecorder_Create(JNIEnv*, jobject) {
+ __android_log_print(ANDROID_LOG_INFO, TAG, "AudioRecorder_Create() ...");
+ if (nativeRecorder == 0) {
+ nativeRecorder = new AudioRecorder();
+ }
+ nativeRecorder->Open(numChannels, 0);
+}
+
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioRecorder_Destroy(JNIEnv*, jobject) {
+ __android_log_print(ANDROID_LOG_INFO, TAG, "AudioRecorder_Destroy() ...");
+ nativeRecorder->Close();
+ delete nativeRecorder;
+ nativeRecorder = 0;
+}
+
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioRecorder_RealizeRecorder(JNIEnv*, jobject) {
+ __android_log_print(ANDROID_LOG_INFO, TAG, "AudioRecorder_RealizePlayer() ...");
+ nativeRecorder->RealizeRecorder();
+ }
+
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioRecorder_RealizeRoutingProxy(JNIEnv*, jobject) {
+ __android_log_print(ANDROID_LOG_INFO, TAG, "RealizeRoutingProxy ...");
+ nativeRecorder->RealizeRoutingProxy();
+ }
+
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioRecorder_Start(JNIEnv *, jobject) {
+ __android_log_print(ANDROID_LOG_INFO, TAG, "AudioRecorder_Start() ...");
+ nativeRecorder->Start();
+}
+
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioRecorder_Stop(JNIEnv *, jobject) {
+ __android_log_print(ANDROID_LOG_INFO, TAG, "AudioRecorder_Stop() ...");
+ nativeRecorder->Stop();
+}
+
+JNIEXPORT jobject JNICALL Java_com_android_ndkaudio_AudioRecorder_GetRoutingInterface(JNIEnv*, jobject) {
+ __android_log_print(ANDROID_LOG_INFO, TAG, "AudioPlayer_GetRoutingObj() ...");
+
+ SLAndroidConfigurationItf configItf = nativeRecorder->getConfigItf();
+ jobject routingObj = 0;
+ lastSLResult = (*configItf)->AcquireJavaProxy(configItf, SL_ANDROID_JAVA_PROXY_ROUTING, &routingObj);
+ __android_log_print(ANDROID_LOG_INFO, TAG, " routingObj:%p", routingObj);
+ return routingObj;
+}
+
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioRecorder_ReleaseRoutingInterface(JNIEnv*, jobject, jobject /*proxyObj*/) {
+ __android_log_print(ANDROID_LOG_INFO, TAG, "AudioPlayer_GetRoutingObj() ...");
+
+ SLAndroidConfigurationItf configItf = nativeRecorder->getConfigItf();
+ lastSLResult = (*configItf)->ReleaseJavaProxy(configItf, SL_ANDROID_JAVA_PROXY_ROUTING/*, proxyObj*/);
+}
+
+JNIEXPORT jint JNICALL Java_com_android_ndkaudio_AudioRecorder_GetNumBufferSamples(JNIEnv*, jobject) {
+ return nativeRecorder->GetNumBufferSamples();
+}
+
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioRecorder_GetBufferData(JNIEnv* jEnv, jobject, jfloatArray j_data) {
+ float* dataBuffer = nativeRecorder->GetRecordBuffer();
+ if (dataBuffer != 0) {
+ jEnv->SetFloatArrayRegion(j_data, 0, nativeRecorder->GetNumBufferSamples(), dataBuffer);
+ }
+}
+
+JNIEXPORT long JNICALL Java_com_android_ndkaudio_AudioRecorder_GetLastSLResult(JNIEnv*, jobject) {
+ return lastSLResult;
+}
+
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioRecorder_ClearLastSLResult(JNIEnv*, jobject) {
+ lastSLResult = 0;
+}
+
+} // extern "C"
diff --git a/tests/tests/media/libndkaudio/com_android_ndkaudio_AudioRecorder.h b/tests/tests/media/libndkaudio/com_android_ndkaudio_AudioRecorder.h
new file mode 100644
index 0000000..d35d4b0
--- /dev/null
+++ b/tests/tests/media/libndkaudio/com_android_ndkaudio_AudioRecorder.h
@@ -0,0 +1,109 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class com_android_ndkaudio_AudioRecorder */
+
+#ifndef _Included_com_android_ndkaudio_AudioRecorder
+#define _Included_com_android_ndkaudio_AudioRecorder
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: com_android_ndkaudio_AudioRecorder
+ * Method: Create
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioRecorder_Create
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_android_ndkaudio_AudioRecorder
+ * Method: Destroy
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioRecorder_Destroy
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_android_ndkaudio_AudioRecorder
+ * Method: RealizeRecorder
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioRecorder_RealizeRecorder
+ (JNIEnv*, jobject);
+
+/*
+ * Class: com_android_ndkaudio_AudioRecorder
+ * Method: RealizeRoutingProxy
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioRecorder_RealizeRoutingProxy
+ (JNIEnv*, jobject);
+
+/*
+ * Class: com_android_ndkaudio_AudioRecorder
+ * Method: Start
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioRecorder_Start
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_android_ndkaudio_AudioRecorder
+ * Method: Stop
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioRecorder_Stop
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_android_ndkaudio_AudioRecorder
+ * Method: GetRoutingInterface
+ * Signature: ()Landroid/media/AudioRouting;
+ */
+JNIEXPORT jobject JNICALL Java_com_android_ndkaudio_AudioRecorder_GetRoutingInterface
+ (JNIEnv*, jobject);
+
+/*
+ * Class: com_android_ndkaudio_AudioRecorder
+ * Method: ReleaseRoutingInterface
+ * Signature: (Landroid/media/AudioRouting;)V
+ */
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioRecorder_ReleaseRoutingInterface
+ (JNIEnv*, jobject, jobject);
+
+/*
+ * Class: com_android_ndkaudio_AudioRecorder
+ * Method: GetNumBufferFrames
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_com_android_ndkaudio_AudioRecorder_GetNumBufferFrames
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_android_ndkaudio_AudioRecorder
+ * Method: GetBufferData
+ * Signature: ([F)V
+ */
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioRecorder_GetBufferData
+ (JNIEnv *, jobject, jfloatArray);
+
+/*
+ * Class: com_android_ndkaudio_AudioRecorder
+ * Method: GetLastSLResult
+ * Signature: ()J
+ */
+JNIEXPORT long JNICALL Java_com_android_ndkaudio_AudioRecorder_GetLastSLResult
+ (JNIEnv*, jobject);
+
+/*
+ * Class: com_android_ndkaudio_AudioRecorder
+ * Method: ClearLastSLResult
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_android_ndkaudio_AudioRecorder_ClearLastSLResult
+ (JNIEnv*, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/tests/tests/media/libndkaudio/src/com/android/ndkaudio/AudioPlayer.java b/tests/tests/media/libndkaudio/src/com/android/ndkaudio/AudioPlayer.java
new file mode 100644
index 0000000..f9cd109
--- /dev/null
+++ b/tests/tests/media/libndkaudio/src/com/android/ndkaudio/AudioPlayer.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2016 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.ndkaudio;
+
+import android.media.AudioRouting;
+
+public class AudioPlayer {
+ public AudioPlayer() {
+ Create();
+ }
+
+ public native void Create();
+ public native void Destroy();
+
+ public native void RealizePlayer();
+ public native void RealizeRoutingProxy();
+
+ public native void Start();
+ public native void Stop();
+
+ public native AudioRouting GetRoutingInterface();
+
+ public native void ReleaseRoutingInterface(AudioRouting proxyObj);
+
+ public native long GetLastSLResult();
+ public native void ClearLastSLResult();
+}
diff --git a/tests/tests/media/libndkaudio/src/com/android/ndkaudio/AudioRecorder.java b/tests/tests/media/libndkaudio/src/com/android/ndkaudio/AudioRecorder.java
new file mode 100644
index 0000000..52d20c4
--- /dev/null
+++ b/tests/tests/media/libndkaudio/src/com/android/ndkaudio/AudioRecorder.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2016 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.ndkaudio;
+
+import android.media.AudioRouting;
+
+public class AudioRecorder {
+ public AudioRecorder() {
+ Create();
+ }
+
+ public native void Create();
+ public native void Destroy();
+
+ public native void RealizeRecorder();
+ public native void RealizeRoutingProxy();
+
+ public native void Start();
+ public native void Stop();
+
+ public native AudioRouting GetRoutingInterface();
+ public native void ReleaseRoutingInterface(AudioRouting proxyObj);
+
+ public native int GetNumBufferSamples();
+ public native void GetBufferData(float[] dstBuff);
+
+ public native long GetLastSLResult();
+ public native void ClearLastSLResult();
+}
diff --git a/tests/tests/media/src/android/media/cts/AudioManagerTest.java b/tests/tests/media/src/android/media/cts/AudioManagerTest.java
index 16b1cf3..c78f82a 100644
--- a/tests/tests/media/src/android/media/cts/AudioManagerTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioManagerTest.java
@@ -35,8 +35,6 @@
import static android.media.AudioManager.VIBRATE_TYPE_RINGER;
import static android.provider.Settings.System.SOUND_EFFECTS_ENABLED;
-import android.media.cts.R;
-
import android.content.Context;
import android.content.res.Resources;
import android.media.AudioManager;
@@ -48,8 +46,6 @@
import android.test.InstrumentationTestCase;
import android.view.SoundEffectConstants;
-import java.util.TreeMap;
-
public class AudioManagerTest extends InstrumentationTestCase {
private final static int MP3_TO_PLAY = R.raw.testmp3;
@@ -184,294 +180,417 @@
if (mUseFixedVolume || !mHasVibrator) {
return;
}
- // VIBRATE_SETTING_ON
- mAudioManager.setVibrateSetting(VIBRATE_TYPE_NOTIFICATION, VIBRATE_SETTING_ON);
- assertEquals(mHasVibrator ? VIBRATE_SETTING_ON : VIBRATE_SETTING_OFF,
- mAudioManager.getVibrateSetting(VIBRATE_TYPE_NOTIFICATION));
- mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
- assertEquals(mHasVibrator, mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));
+ try {
+ Utils.toggleNotificationPolicyAccess(
+ mContext.getPackageName(), getInstrumentation(), true);
+ // VIBRATE_SETTING_ON
+ mAudioManager.setVibrateSetting(VIBRATE_TYPE_NOTIFICATION, VIBRATE_SETTING_ON);
+ assertEquals(mHasVibrator ? VIBRATE_SETTING_ON : VIBRATE_SETTING_OFF,
+ mAudioManager.getVibrateSetting(VIBRATE_TYPE_NOTIFICATION));
+ mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
+ assertEquals(mHasVibrator, mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));
- mAudioManager.setRingerMode(RINGER_MODE_SILENT);
- assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));
+ mAudioManager.setRingerMode(RINGER_MODE_SILENT);
+ assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));
- mAudioManager.setRingerMode(RINGER_MODE_VIBRATE);
- assertEquals(mHasVibrator ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT,
- mAudioManager.getRingerMode());
- assertEquals(mHasVibrator, mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));
+ mAudioManager.setRingerMode(RINGER_MODE_VIBRATE);
+ assertEquals(mHasVibrator ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT,
+ mAudioManager.getRingerMode());
+ assertEquals(mHasVibrator, mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));
- // VIBRATE_SETTING_OFF
- mAudioManager.setVibrateSetting(VIBRATE_TYPE_NOTIFICATION, VIBRATE_SETTING_OFF);
- assertEquals(VIBRATE_SETTING_OFF,
- mAudioManager.getVibrateSetting(VIBRATE_TYPE_NOTIFICATION));
- mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
- assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));
+ // VIBRATE_SETTING_OFF
+ mAudioManager.setVibrateSetting(VIBRATE_TYPE_NOTIFICATION, VIBRATE_SETTING_OFF);
+ assertEquals(VIBRATE_SETTING_OFF,
+ mAudioManager.getVibrateSetting(VIBRATE_TYPE_NOTIFICATION));
+ mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
+ assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));
- mAudioManager.setRingerMode(RINGER_MODE_SILENT);
- assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));
+ mAudioManager.setRingerMode(RINGER_MODE_SILENT);
+ assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));
- mAudioManager.setRingerMode(RINGER_MODE_VIBRATE);
- assertEquals(mHasVibrator ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT,
- mAudioManager.getRingerMode());
- assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));
+ mAudioManager.setRingerMode(RINGER_MODE_VIBRATE);
+ assertEquals(mHasVibrator ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT,
+ mAudioManager.getRingerMode());
+ assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));
- // VIBRATE_SETTING_ONLY_SILENT
- mAudioManager.setVibrateSetting(VIBRATE_TYPE_NOTIFICATION, VIBRATE_SETTING_ONLY_SILENT);
- assertEquals(mHasVibrator ? VIBRATE_SETTING_ONLY_SILENT : VIBRATE_SETTING_OFF,
- mAudioManager.getVibrateSetting(VIBRATE_TYPE_NOTIFICATION));
- mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
- assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));
+ // VIBRATE_SETTING_ONLY_SILENT
+ mAudioManager.setVibrateSetting(VIBRATE_TYPE_NOTIFICATION, VIBRATE_SETTING_ONLY_SILENT);
+ assertEquals(mHasVibrator ? VIBRATE_SETTING_ONLY_SILENT : VIBRATE_SETTING_OFF,
+ mAudioManager.getVibrateSetting(VIBRATE_TYPE_NOTIFICATION));
+ mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
+ assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));
- mAudioManager.setRingerMode(RINGER_MODE_SILENT);
- assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));
+ mAudioManager.setRingerMode(RINGER_MODE_SILENT);
+ assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));
- mAudioManager.setRingerMode(RINGER_MODE_VIBRATE);
- assertEquals(mHasVibrator ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT,
- mAudioManager.getRingerMode());
- assertEquals(mHasVibrator, mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));
+ mAudioManager.setRingerMode(RINGER_MODE_VIBRATE);
+ assertEquals(mHasVibrator ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT,
+ mAudioManager.getRingerMode());
+ assertEquals(mHasVibrator, mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));
- // VIBRATE_TYPE_NOTIFICATION
- mAudioManager.setVibrateSetting(VIBRATE_TYPE_NOTIFICATION, VIBRATE_SETTING_ON);
- assertEquals(mHasVibrator ? VIBRATE_SETTING_ON : VIBRATE_SETTING_OFF,
- mAudioManager.getVibrateSetting(VIBRATE_TYPE_NOTIFICATION));
- mAudioManager.setVibrateSetting(VIBRATE_TYPE_NOTIFICATION, VIBRATE_SETTING_OFF);
- assertEquals(VIBRATE_SETTING_OFF, mAudioManager
- .getVibrateSetting(VIBRATE_TYPE_NOTIFICATION));
- mAudioManager.setVibrateSetting(VIBRATE_TYPE_NOTIFICATION, VIBRATE_SETTING_ONLY_SILENT);
- assertEquals(mHasVibrator ? VIBRATE_SETTING_ONLY_SILENT : VIBRATE_SETTING_OFF,
- mAudioManager.getVibrateSetting(VIBRATE_TYPE_NOTIFICATION));
+ // VIBRATE_TYPE_NOTIFICATION
+ mAudioManager.setVibrateSetting(VIBRATE_TYPE_NOTIFICATION, VIBRATE_SETTING_ON);
+ assertEquals(mHasVibrator ? VIBRATE_SETTING_ON : VIBRATE_SETTING_OFF,
+ mAudioManager.getVibrateSetting(VIBRATE_TYPE_NOTIFICATION));
+ mAudioManager.setVibrateSetting(VIBRATE_TYPE_NOTIFICATION, VIBRATE_SETTING_OFF);
+ assertEquals(VIBRATE_SETTING_OFF, mAudioManager
+ .getVibrateSetting(VIBRATE_TYPE_NOTIFICATION));
+ mAudioManager.setVibrateSetting(VIBRATE_TYPE_NOTIFICATION, VIBRATE_SETTING_ONLY_SILENT);
+ assertEquals(mHasVibrator ? VIBRATE_SETTING_ONLY_SILENT : VIBRATE_SETTING_OFF,
+ mAudioManager.getVibrateSetting(VIBRATE_TYPE_NOTIFICATION));
+ } finally {
+ Utils.toggleNotificationPolicyAccess(
+ mContext.getPackageName(), getInstrumentation(), false);
+ }
}
public void testVibrateRinger() throws Exception {
if (mUseFixedVolume || !mHasVibrator) {
return;
}
- // VIBRATE_TYPE_RINGER
- mAudioManager.setVibrateSetting(VIBRATE_TYPE_RINGER, VIBRATE_SETTING_ON);
- assertEquals(mHasVibrator ? VIBRATE_SETTING_ON : VIBRATE_SETTING_OFF,
- mAudioManager.getVibrateSetting(VIBRATE_TYPE_RINGER));
- mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
- assertEquals(mHasVibrator, mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));
+ try {
+ Utils.toggleNotificationPolicyAccess(
+ mContext.getPackageName(), getInstrumentation(), true);
+ // VIBRATE_TYPE_RINGER
+ mAudioManager.setVibrateSetting(VIBRATE_TYPE_RINGER, VIBRATE_SETTING_ON);
+ assertEquals(mHasVibrator ? VIBRATE_SETTING_ON : VIBRATE_SETTING_OFF,
+ mAudioManager.getVibrateSetting(VIBRATE_TYPE_RINGER));
+ mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
+ assertEquals(mHasVibrator, mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));
- mAudioManager.setRingerMode(RINGER_MODE_SILENT);
- assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));
+ mAudioManager.setRingerMode(RINGER_MODE_SILENT);
+ assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));
- mAudioManager.setRingerMode(RINGER_MODE_VIBRATE);
- assertEquals(mHasVibrator ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT,
- mAudioManager.getRingerMode());
- assertEquals(mHasVibrator, mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));
+ mAudioManager.setRingerMode(RINGER_MODE_VIBRATE);
+ assertEquals(mHasVibrator ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT,
+ mAudioManager.getRingerMode());
+ assertEquals(mHasVibrator, mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));
- // VIBRATE_SETTING_OFF
- mAudioManager.setVibrateSetting(VIBRATE_TYPE_RINGER, VIBRATE_SETTING_OFF);
- assertEquals(VIBRATE_SETTING_OFF, mAudioManager.getVibrateSetting(VIBRATE_TYPE_RINGER));
- mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
- assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));
+ // VIBRATE_SETTING_OFF
+ mAudioManager.setVibrateSetting(VIBRATE_TYPE_RINGER, VIBRATE_SETTING_OFF);
+ assertEquals(VIBRATE_SETTING_OFF, mAudioManager.getVibrateSetting(VIBRATE_TYPE_RINGER));
+ mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
+ assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));
- mAudioManager.setRingerMode(RINGER_MODE_SILENT);
- assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));
+ mAudioManager.setRingerMode(RINGER_MODE_SILENT);
+ assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));
- mAudioManager.setRingerMode(RINGER_MODE_VIBRATE);
- assertEquals(mHasVibrator ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT,
- mAudioManager.getRingerMode());
- // Note: as of Froyo, if VIBRATE_TYPE_RINGER is set to OFF, it will
- // not vibrate, even in RINGER_MODE_VIBRATE. This allows users to
- // disable the vibration for incoming calls only.
- assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));
+ mAudioManager.setRingerMode(RINGER_MODE_VIBRATE);
+ assertEquals(mHasVibrator ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT,
+ mAudioManager.getRingerMode());
+ // Note: as of Froyo, if VIBRATE_TYPE_RINGER is set to OFF, it will
+ // not vibrate, even in RINGER_MODE_VIBRATE. This allows users to
+ // disable the vibration for incoming calls only.
+ assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));
- // VIBRATE_SETTING_ONLY_SILENT
- mAudioManager.setVibrateSetting(VIBRATE_TYPE_RINGER, VIBRATE_SETTING_ONLY_SILENT);
- assertEquals(mHasVibrator ? VIBRATE_SETTING_ONLY_SILENT : VIBRATE_SETTING_OFF,
- mAudioManager.getVibrateSetting(VIBRATE_TYPE_RINGER));
- mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
- assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));
+ // VIBRATE_SETTING_ONLY_SILENT
+ mAudioManager.setVibrateSetting(VIBRATE_TYPE_RINGER, VIBRATE_SETTING_ONLY_SILENT);
+ assertEquals(mHasVibrator ? VIBRATE_SETTING_ONLY_SILENT : VIBRATE_SETTING_OFF,
+ mAudioManager.getVibrateSetting(VIBRATE_TYPE_RINGER));
+ mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
+ assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));
- mAudioManager.setRingerMode(RINGER_MODE_SILENT);
- assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));
+ mAudioManager.setRingerMode(RINGER_MODE_SILENT);
+ assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));
- mAudioManager.setRingerMode(RINGER_MODE_VIBRATE);
- assertEquals(mHasVibrator ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT,
- mAudioManager.getRingerMode());
- assertEquals(mHasVibrator, mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));
+ mAudioManager.setRingerMode(RINGER_MODE_VIBRATE);
+ assertEquals(mHasVibrator ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT,
+ mAudioManager.getRingerMode());
+ assertEquals(mHasVibrator, mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));
- // VIBRATE_TYPE_NOTIFICATION
- mAudioManager.setVibrateSetting(VIBRATE_TYPE_RINGER, VIBRATE_SETTING_ON);
- assertEquals(mHasVibrator ? VIBRATE_SETTING_ON : VIBRATE_SETTING_OFF,
- mAudioManager.getVibrateSetting(VIBRATE_TYPE_RINGER));
- mAudioManager.setVibrateSetting(VIBRATE_TYPE_RINGER, VIBRATE_SETTING_OFF);
- assertEquals(VIBRATE_SETTING_OFF, mAudioManager.getVibrateSetting(VIBRATE_TYPE_RINGER));
- mAudioManager.setVibrateSetting(VIBRATE_TYPE_RINGER, VIBRATE_SETTING_ONLY_SILENT);
- assertEquals(mHasVibrator ? VIBRATE_SETTING_ONLY_SILENT : VIBRATE_SETTING_OFF,
- mAudioManager.getVibrateSetting(VIBRATE_TYPE_RINGER));
+ // VIBRATE_TYPE_NOTIFICATION
+ mAudioManager.setVibrateSetting(VIBRATE_TYPE_RINGER, VIBRATE_SETTING_ON);
+ assertEquals(mHasVibrator ? VIBRATE_SETTING_ON : VIBRATE_SETTING_OFF,
+ mAudioManager.getVibrateSetting(VIBRATE_TYPE_RINGER));
+ mAudioManager.setVibrateSetting(VIBRATE_TYPE_RINGER, VIBRATE_SETTING_OFF);
+ assertEquals(VIBRATE_SETTING_OFF, mAudioManager.getVibrateSetting(VIBRATE_TYPE_RINGER));
+ mAudioManager.setVibrateSetting(VIBRATE_TYPE_RINGER, VIBRATE_SETTING_ONLY_SILENT);
+ assertEquals(mHasVibrator ? VIBRATE_SETTING_ONLY_SILENT : VIBRATE_SETTING_OFF,
+ mAudioManager.getVibrateSetting(VIBRATE_TYPE_RINGER));
+ } finally {
+ Utils.toggleNotificationPolicyAccess(
+ mContext.getPackageName(), getInstrumentation(), false);
+ }
}
public void testAccessRingMode() throws Exception {
- mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
- assertEquals(RINGER_MODE_NORMAL, mAudioManager.getRingerMode());
-
- mAudioManager.setRingerMode(RINGER_MODE_SILENT);
- // AudioService#setRingerMode() has:
- // if (isTelevision) return;
- if (mUseFixedVolume || mIsTelevision) {
+ try {
+ Utils.toggleNotificationPolicyAccess(
+ mContext.getPackageName(), getInstrumentation(), true);
+ mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
assertEquals(RINGER_MODE_NORMAL, mAudioManager.getRingerMode());
- } else {
+
+ mAudioManager.setRingerMode(RINGER_MODE_SILENT);
+ // AudioService#setRingerMode() has:
+ // if (isTelevision) return;
+ if (mUseFixedVolume || mIsTelevision) {
+ assertEquals(RINGER_MODE_NORMAL, mAudioManager.getRingerMode());
+ } else {
+ assertEquals(RINGER_MODE_SILENT, mAudioManager.getRingerMode());
+ }
+
+ mAudioManager.setRingerMode(RINGER_MODE_VIBRATE);
+ if (mUseFixedVolume || mIsTelevision) {
+ assertEquals(RINGER_MODE_NORMAL, mAudioManager.getRingerMode());
+ } else {
+ assertEquals(mHasVibrator ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT,
+ mAudioManager.getRingerMode());
+ }
+ } finally {
+ Utils.toggleNotificationPolicyAccess(
+ mContext.getPackageName(), getInstrumentation(), false);
+ }
+ }
+
+ public void testSetRingerModePolicyAccess() throws Exception {
+ try {
+ // Apps without policy access cannot change silent -> normal or silent -> vibrate.
+ Utils.toggleNotificationPolicyAccess(
+ mContext.getPackageName(), getInstrumentation(), true);
+ mAudioManager.setRingerMode(RINGER_MODE_SILENT);
assertEquals(RINGER_MODE_SILENT, mAudioManager.getRingerMode());
- }
+ Utils.toggleNotificationPolicyAccess(
+ mContext.getPackageName(), getInstrumentation(), false);
- mAudioManager.setRingerMode(RINGER_MODE_VIBRATE);
- if (mUseFixedVolume || mIsTelevision) {
+ try {
+ mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
+ fail("Apps without notification policy access cannot change ringer mode");
+ } catch (SecurityException e) {
+ }
+
+ try {
+ mAudioManager.setRingerMode(RINGER_MODE_VIBRATE);
+ fail("Apps without notification policy access cannot change ringer mode");
+ } catch (SecurityException e) {
+ }
+
+ // Apps without policy access cannot change normal -> silent.
+ Utils.toggleNotificationPolicyAccess(
+ mContext.getPackageName(), getInstrumentation(), true);
+ mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
assertEquals(RINGER_MODE_NORMAL, mAudioManager.getRingerMode());
- } else {
- assertEquals(mHasVibrator ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT,
- mAudioManager.getRingerMode());
+ Utils.toggleNotificationPolicyAccess(
+ mContext.getPackageName(), getInstrumentation(), false);
+
+ try {
+ mAudioManager.setRingerMode(RINGER_MODE_SILENT);
+ fail("Apps without notification policy access cannot change ringer mode");
+ } catch (SecurityException e) {
+ }
+ assertEquals(RINGER_MODE_NORMAL, mAudioManager.getRingerMode());
+
+ // Apps without policy access cannot change vibrate -> silent.
+ Utils.toggleNotificationPolicyAccess(
+ mContext.getPackageName(), getInstrumentation(), true);
+ mAudioManager.setRingerMode(RINGER_MODE_VIBRATE);
+ assertEquals(RINGER_MODE_VIBRATE, mAudioManager.getRingerMode());
+ Utils.toggleNotificationPolicyAccess(
+ mContext.getPackageName(), getInstrumentation(), false);
+
+ try {
+ mAudioManager.setRingerMode(RINGER_MODE_SILENT);
+ fail("Apps without notification policy access cannot change ringer mode");
+ } catch (SecurityException e) {
+ }
+
+ // Apps without policy access can change vibrate -> normal and vice versa.
+ assertEquals(RINGER_MODE_VIBRATE, mAudioManager.getRingerMode());
+ mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
+ assertEquals(RINGER_MODE_NORMAL, mAudioManager.getRingerMode());
+ mAudioManager.setRingerMode(RINGER_MODE_VIBRATE);
+ assertEquals(RINGER_MODE_VIBRATE, mAudioManager.getRingerMode());
+ } finally {
+ Utils.toggleNotificationPolicyAccess(
+ mContext.getPackageName(), getInstrumentation(), false);
}
}
+ public void testVolumeDndAffectedStream() throws Exception {
+ if (mUseFixedVolume || mHasVibrator) {
+ return;
+ }
+ Utils.toggleNotificationPolicyAccess(
+ mContext.getPackageName(), getInstrumentation(), true);
+ mAudioManager.setStreamVolume(
+ AudioManager.STREAM_SYSTEM, 7, AudioManager.FLAG_ALLOW_RINGER_MODES);
+ mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
+ Utils.toggleNotificationPolicyAccess(
+ mContext.getPackageName(), getInstrumentation(), false);
+ // 7 to 0, fail.
+ try {
+ mAudioManager.setStreamVolume(
+ AudioManager.STREAM_SYSTEM, 0, AudioManager.FLAG_ALLOW_RINGER_MODES);
+ fail("Apps without notification policy access cannot change ringer mode");
+ } catch (SecurityException e) {}
+
+ // 7 to 1: success
+ mAudioManager.setStreamVolume(
+ AudioManager.STREAM_SYSTEM, 1, AudioManager.FLAG_ALLOW_RINGER_MODES);
+ assertEquals("setStreamVolume did not change volume",
+ 1, mAudioManager.getStreamVolume(AudioManager.STREAM_SYSTEM));
+
+ // 0 to non-zero: fail.
+ Utils.toggleNotificationPolicyAccess(
+ mContext.getPackageName(), getInstrumentation(), true);
+ mAudioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
+ mAudioManager.setStreamVolume(
+ AudioManager.STREAM_SYSTEM, 0, AudioManager.FLAG_ALLOW_RINGER_MODES);
+ Utils.toggleNotificationPolicyAccess(
+ mContext.getPackageName(), getInstrumentation(), false);
+
+ try {
+ mAudioManager.setStreamVolume(
+ AudioManager.STREAM_SYSTEM, 6, AudioManager.FLAG_ALLOW_RINGER_MODES);
+ fail("Apps without notification policy access cannot change ringer mode");
+ } catch (SecurityException e) {}
+ }
+
public void testVolume() throws Exception {
- int volume, volumeDelta;
- int[] streams = { AudioManager.STREAM_ALARM,
- AudioManager.STREAM_MUSIC,
- AudioManager.STREAM_VOICE_CALL,
- AudioManager.STREAM_RING };
+ try {
+ Utils.toggleNotificationPolicyAccess(
+ mContext.getPackageName(), getInstrumentation(), true);
+ int volume, volumeDelta;
+ int[] streams = {AudioManager.STREAM_ALARM,
+ AudioManager.STREAM_MUSIC,
+ AudioManager.STREAM_VOICE_CALL,
+ AudioManager.STREAM_RING};
- mAudioManager.adjustVolume(ADJUST_RAISE, 0);
- mAudioManager.adjustSuggestedStreamVolume(
- ADJUST_LOWER, USE_DEFAULT_STREAM_TYPE, 0);
- int maxMusicVolume = mAudioManager.getStreamMaxVolume(STREAM_MUSIC);
+ mAudioManager.adjustVolume(ADJUST_RAISE, 0);
+ mAudioManager.adjustSuggestedStreamVolume(
+ ADJUST_LOWER, USE_DEFAULT_STREAM_TYPE, 0);
+ int maxMusicVolume = mAudioManager.getStreamMaxVolume(STREAM_MUSIC);
- for (int i = 0; i < streams.length; i++) {
- // set ringer mode to back normal to not interfere with volume tests
- mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
+ for (int i = 0; i < streams.length; i++) {
+ // set ringer mode to back normal to not interfere with volume tests
+ mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
- int maxVolume = mAudioManager.getStreamMaxVolume(streams[i]);
- int minVolume = mAudioManager.getStreamMinVolume(streams[i]);
+ int maxVolume = mAudioManager.getStreamMaxVolume(streams[i]);
+ int minVolume = mAudioManager.getStreamMinVolume(streams[i]);
- // validate min
- assertTrue(String.format("minVolume(%d) must be >= 0", minVolume), minVolume >= 0);
- assertTrue(String.format("minVolume(%d) must be < maxVolume(%d)", minVolume, maxVolume),
- minVolume < maxVolume);
+ // validate min
+ assertTrue(String.format("minVolume(%d) must be >= 0", minVolume), minVolume >= 0);
+ assertTrue(String.format("minVolume(%d) must be < maxVolume(%d)", minVolume,
+ maxVolume),
+ minVolume < maxVolume);
- mAudioManager.setStreamVolume(streams[i], 1, 0);
- if (mUseFixedVolume) {
- assertEquals(maxVolume, mAudioManager.getStreamVolume(streams[i]));
- continue;
- }
- assertEquals(1, mAudioManager.getStreamVolume(streams[i]));
+ mAudioManager.setStreamVolume(streams[i], 1, 0);
+ if (mUseFixedVolume) {
+ assertEquals(maxVolume, mAudioManager.getStreamVolume(streams[i]));
+ continue;
+ }
+ assertEquals(1, mAudioManager.getStreamVolume(streams[i]));
- if (streams[i] == AudioManager.STREAM_MUSIC && mAudioManager.isWiredHeadsetOn()) {
- // due to new regulations, music sent over a wired headset may be volume limited
- // until the user explicitly increases the limit, so we can't rely on being able
- // to set the volume to getStreamMaxVolume(). Instead, determine the current limit
- // by increasing the volume until it won't go any higher, then use that volume as
- // the maximum for the purposes of this test
- int curvol = 0;
- int prevvol = 0;
- do {
- prevvol = curvol;
- mAudioManager.adjustStreamVolume(streams[i], ADJUST_RAISE, 0);
- curvol = mAudioManager.getStreamVolume(streams[i]);
- } while (curvol != prevvol);
- maxVolume = maxMusicVolume = curvol;
- }
- mAudioManager.setStreamVolume(streams[i], maxVolume, 0);
- mAudioManager.adjustStreamVolume(streams[i], ADJUST_RAISE, 0);
- assertEquals(maxVolume, mAudioManager.getStreamVolume(streams[i]));
-
- volumeDelta = getVolumeDelta(mAudioManager.getStreamVolume(streams[i]));
- mAudioManager.adjustSuggestedStreamVolume(ADJUST_LOWER, streams[i], 0);
- assertEquals(maxVolume - volumeDelta, mAudioManager.getStreamVolume(streams[i]));
-
- // volume lower
- mAudioManager.setStreamVolume(streams[i], maxVolume, 0);
- volume = mAudioManager.getStreamVolume(streams[i]);
- while (volume > minVolume) {
- volumeDelta = getVolumeDelta(mAudioManager.getStreamVolume(streams[i]));
- mAudioManager.adjustStreamVolume(streams[i], ADJUST_LOWER, 0);
- assertEquals(Math.max(0, volume - volumeDelta),
- mAudioManager.getStreamVolume(streams[i]));
- volume = mAudioManager.getStreamVolume(streams[i]);
- }
-
- mAudioManager.adjustStreamVolume(streams[i], ADJUST_SAME, 0);
-
- // volume raise
- mAudioManager.setStreamVolume(streams[i], 1, 0);
- volume = mAudioManager.getStreamVolume(streams[i]);
- while (volume < maxVolume) {
- volumeDelta = getVolumeDelta(mAudioManager.getStreamVolume(streams[i]));
+ if (streams[i] == AudioManager.STREAM_MUSIC && mAudioManager.isWiredHeadsetOn()) {
+ // due to new regulations, music sent over a wired headset may be volume limited
+ // until the user explicitly increases the limit, so we can't rely on being able
+ // to set the volume to getStreamMaxVolume(). Instead, determine the current limit
+ // by increasing the volume until it won't go any higher, then use that volume as
+ // the maximum for the purposes of this test
+ int curvol = 0;
+ int prevvol = 0;
+ do {
+ prevvol = curvol;
+ mAudioManager.adjustStreamVolume(streams[i], ADJUST_RAISE, 0);
+ curvol = mAudioManager.getStreamVolume(streams[i]);
+ } while (curvol != prevvol);
+ maxVolume = maxMusicVolume = curvol;
+ }
+ mAudioManager.setStreamVolume(streams[i], maxVolume, 0);
mAudioManager.adjustStreamVolume(streams[i], ADJUST_RAISE, 0);
- assertEquals(Math.min(volume + volumeDelta, maxVolume),
- mAudioManager.getStreamVolume(streams[i]));
- volume = mAudioManager.getStreamVolume(streams[i]);
- }
-
- // volume same
- mAudioManager.setStreamVolume(streams[i], maxVolume, 0);
- for (int k = 0; k < maxVolume; k++) {
- mAudioManager.adjustStreamVolume(streams[i], ADJUST_SAME, 0);
assertEquals(maxVolume, mAudioManager.getStreamVolume(streams[i]));
+
+ volumeDelta = getVolumeDelta(mAudioManager.getStreamVolume(streams[i]));
+ mAudioManager.adjustSuggestedStreamVolume(ADJUST_LOWER, streams[i], 0);
+ assertEquals(maxVolume - volumeDelta, mAudioManager.getStreamVolume(streams[i]));
+
+ // volume lower
+ mAudioManager.setStreamVolume(streams[i], maxVolume, 0);
+ volume = mAudioManager.getStreamVolume(streams[i]);
+ while (volume > minVolume) {
+ volumeDelta = getVolumeDelta(mAudioManager.getStreamVolume(streams[i]));
+ mAudioManager.adjustStreamVolume(streams[i], ADJUST_LOWER, 0);
+ assertEquals(Math.max(0, volume - volumeDelta),
+ mAudioManager.getStreamVolume(streams[i]));
+ volume = mAudioManager.getStreamVolume(streams[i]);
+ }
+
+ mAudioManager.adjustStreamVolume(streams[i], ADJUST_SAME, 0);
+
+ // volume raise
+ mAudioManager.setStreamVolume(streams[i], 1, 0);
+ volume = mAudioManager.getStreamVolume(streams[i]);
+ while (volume < maxVolume) {
+ volumeDelta = getVolumeDelta(mAudioManager.getStreamVolume(streams[i]));
+ mAudioManager.adjustStreamVolume(streams[i], ADJUST_RAISE, 0);
+ assertEquals(Math.min(volume + volumeDelta, maxVolume),
+ mAudioManager.getStreamVolume(streams[i]));
+ volume = mAudioManager.getStreamVolume(streams[i]);
+ }
+
+ // volume same
+ mAudioManager.setStreamVolume(streams[i], maxVolume, 0);
+ for (int k = 0; k < maxVolume; k++) {
+ mAudioManager.adjustStreamVolume(streams[i], ADJUST_SAME, 0);
+ assertEquals(maxVolume, mAudioManager.getStreamVolume(streams[i]));
+ }
+
+ mAudioManager.setStreamVolume(streams[i], maxVolume, 0);
}
- mAudioManager.setStreamVolume(streams[i], maxVolume, 0);
+ if (mUseFixedVolume) {
+ return;
+ }
+
+ // adjust volume
+ mAudioManager.adjustVolume(ADJUST_RAISE, 0);
+
+ MediaPlayer mp = MediaPlayer.create(mContext, MP3_TO_PLAY);
+ assertNotNull(mp);
+ mp.setAudioStreamType(STREAM_MUSIC);
+ mp.setLooping(true);
+ mp.start();
+ Thread.sleep(TIME_TO_PLAY);
+ assertTrue(mAudioManager.isMusicActive());
+
+ // adjust volume as ADJUST_SAME
+ for (int k = 0; k < maxMusicVolume; k++) {
+ mAudioManager.adjustVolume(ADJUST_SAME, 0);
+ assertEquals(maxMusicVolume, mAudioManager.getStreamVolume(STREAM_MUSIC));
+ }
+
+ // adjust volume as ADJUST_RAISE
+ mAudioManager.setStreamVolume(STREAM_MUSIC, 0, 0);
+ volumeDelta = getVolumeDelta(mAudioManager.getStreamVolume(STREAM_MUSIC));
+ mAudioManager.adjustVolume(ADJUST_RAISE, 0);
+ assertEquals(Math.min(volumeDelta, maxMusicVolume),
+ mAudioManager.getStreamVolume(STREAM_MUSIC));
+
+ // adjust volume as ADJUST_LOWER
+ mAudioManager.setStreamVolume(STREAM_MUSIC, maxMusicVolume, 0);
+ maxMusicVolume = mAudioManager.getStreamVolume(STREAM_MUSIC);
+ volumeDelta = getVolumeDelta(mAudioManager.getStreamVolume(STREAM_MUSIC));
+ mAudioManager.adjustVolume(ADJUST_LOWER, 0);
+ assertEquals(Math.max(0, maxMusicVolume - volumeDelta),
+ mAudioManager.getStreamVolume(STREAM_MUSIC));
+
+ mp.stop();
+ mp.release();
+ Thread.sleep(TIME_TO_PLAY);
+ assertFalse(mAudioManager.isMusicActive());
+ } finally {
+ Utils.toggleNotificationPolicyAccess(
+ mContext.getPackageName(), getInstrumentation(), false);
}
-
- if (mUseFixedVolume) {
- return;
- }
-
- // adjust volume
- mAudioManager.adjustVolume(ADJUST_RAISE, 0);
-
- MediaPlayer mp = MediaPlayer.create(mContext, MP3_TO_PLAY);
- assertNotNull(mp);
- mp.setAudioStreamType(STREAM_MUSIC);
- mp.setLooping(true);
- mp.start();
- Thread.sleep(TIME_TO_PLAY);
- assertTrue(mAudioManager.isMusicActive());
-
- // adjust volume as ADJUST_SAME
- for (int k = 0; k < maxMusicVolume; k++) {
- mAudioManager.adjustVolume(ADJUST_SAME, 0);
- assertEquals(maxMusicVolume, mAudioManager.getStreamVolume(STREAM_MUSIC));
- }
-
- // adjust volume as ADJUST_RAISE
- mAudioManager.setStreamVolume(STREAM_MUSIC, 0, 0);
- volumeDelta = getVolumeDelta(mAudioManager.getStreamVolume(STREAM_MUSIC));
- mAudioManager.adjustVolume(ADJUST_RAISE, 0);
- assertEquals(Math.min(volumeDelta, maxMusicVolume),
- mAudioManager.getStreamVolume(STREAM_MUSIC));
-
- // adjust volume as ADJUST_LOWER
- mAudioManager.setStreamVolume(STREAM_MUSIC, maxMusicVolume, 0);
- maxMusicVolume = mAudioManager.getStreamVolume(STREAM_MUSIC);
- volumeDelta = getVolumeDelta(mAudioManager.getStreamVolume(STREAM_MUSIC));
- mAudioManager.adjustVolume(ADJUST_LOWER, 0);
- assertEquals(Math.max(0, maxMusicVolume - volumeDelta),
- mAudioManager.getStreamVolume(STREAM_MUSIC));
-
- mp.stop();
- mp.release();
- Thread.sleep(TIME_TO_PLAY);
- assertFalse(mAudioManager.isMusicActive());
}
- public void testMute() {
+ public void testMuteFixedVolume() throws Exception {
int[] streams = {
AudioManager.STREAM_VOICE_CALL,
AudioManager.STREAM_MUSIC,
AudioManager.STREAM_RING,
AudioManager.STREAM_ALARM,
AudioManager.STREAM_NOTIFICATION,
- AudioManager.STREAM_SYSTEM };
-
- int muteAffectedStreams = System.getInt(mContext.getContentResolver(),
- System.MUTE_STREAMS_AFFECTED,
- // Same defaults as in AudioService. Should be kept in
- // sync.
- ((1 << AudioManager.STREAM_MUSIC) |
- (1 << AudioManager.STREAM_RING) |
- (1 << AudioManager.STREAM_NOTIFICATION) |
- (1 << AudioManager.STREAM_SYSTEM)));
+ AudioManager.STREAM_SYSTEM};
if (mUseFixedVolume) {
for (int i = 0; i < streams.length; i++) {
mAudioManager.adjustStreamVolume(streams[i], AudioManager.ADJUST_MUTE, 0);
@@ -486,54 +605,87 @@
assertFalse("Muting should not affect a fixed volume device.",
mAudioManager.isStreamMute(streams[i]));
}
+ }
+ }
+
+ public void testMute() throws Exception {
+ if (mUseFixedVolume) {
return;
}
- // This ensures we're out of vibrate or silent modes.
- mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
- for (int i = 0; i < streams.length; i++) {
- // ensure each stream is on and turned up.
- mAudioManager.setStreamVolume(streams[i], mAudioManager.getStreamMaxVolume(streams[i]),
- 0);
- if (((1 << streams[i]) & muteAffectedStreams) == 0) {
+
+ int[] streams = {
+ AudioManager.STREAM_VOICE_CALL,
+ AudioManager.STREAM_MUSIC,
+ AudioManager.STREAM_RING,
+ AudioManager.STREAM_ALARM,
+ AudioManager.STREAM_NOTIFICATION,
+ AudioManager.STREAM_SYSTEM };
+
+ try {
+ int muteAffectedStreams = System.getInt(mContext.getContentResolver(),
+ System.MUTE_STREAMS_AFFECTED,
+ // Same defaults as in AudioService. Should be kept in
+ // sync.
+ ((1 << AudioManager.STREAM_MUSIC) |
+ (1 << AudioManager.STREAM_RING) |
+ (1 << AudioManager.STREAM_NOTIFICATION) |
+ (1 << AudioManager.STREAM_SYSTEM)));
+ Utils.toggleNotificationPolicyAccess(
+ mContext.getPackageName(), getInstrumentation(), true);
+ // This ensures we're out of vibrate or silent modes.
+ mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
+ Utils.toggleNotificationPolicyAccess(
+ mContext.getPackageName(), getInstrumentation(), false);
+ for (int i = 0; i < streams.length; i++) {
+ // ensure each stream is on and turned up.
+ mAudioManager.setStreamVolume(streams[i],
+ mAudioManager.getStreamMaxVolume(streams[i]),
+ 0);
+ if (((1 << streams[i]) & muteAffectedStreams) == 0) {
+ mAudioManager.adjustStreamVolume(streams[i], AudioManager.ADJUST_MUTE, 0);
+ assertFalse("Stream " + streams[i] + " should not be affected by mute.",
+ mAudioManager.isStreamMute(streams[i]));
+ mAudioManager.setStreamMute(streams[i], true);
+ assertFalse("Stream " + streams[i] + " should not be affected by mute.",
+ mAudioManager.isStreamMute(streams[i]));
+ mAudioManager.adjustStreamVolume(streams[i], AudioManager.ADJUST_TOGGLE_MUTE,
+ 0);
+ assertFalse("Stream " + streams[i] + " should not be affected by mute.",
+ mAudioManager.isStreamMute(streams[i]));
+ continue;
+ }
mAudioManager.adjustStreamVolume(streams[i], AudioManager.ADJUST_MUTE, 0);
- assertFalse("Stream " + streams[i] + " should not be affected by mute.",
+ assertTrue("Muting stream " + streams[i] + " failed.",
mAudioManager.isStreamMute(streams[i]));
- mAudioManager.setStreamMute(streams[i], true);
- assertFalse("Stream " + streams[i] + " should not be affected by mute.",
+
+ mAudioManager.adjustStreamVolume(streams[i], AudioManager.ADJUST_UNMUTE, 0);
+ assertFalse("Unmuting stream " + streams[i] + " failed.",
mAudioManager.isStreamMute(streams[i]));
+
mAudioManager.adjustStreamVolume(streams[i], AudioManager.ADJUST_TOGGLE_MUTE, 0);
- assertFalse("Stream " + streams[i] + " should not be affected by mute.",
+ assertTrue("Toggling mute on stream " + streams[i] + " failed.",
mAudioManager.isStreamMute(streams[i]));
- continue;
+
+ mAudioManager.adjustStreamVolume(streams[i], AudioManager.ADJUST_TOGGLE_MUTE, 0);
+ assertFalse("Toggling mute on stream " + streams[i] + " failed.",
+ mAudioManager.isStreamMute(streams[i]));
+
+ mAudioManager.setStreamMute(streams[i], true);
+ assertTrue("Muting stream " + streams[i] + " using setStreamMute failed",
+ mAudioManager.isStreamMute(streams[i]));
+
+ // mute it three more times to verify the ref counting is gone.
+ mAudioManager.setStreamMute(streams[i], true);
+ mAudioManager.setStreamMute(streams[i], true);
+ mAudioManager.setStreamMute(streams[i], true);
+
+ mAudioManager.setStreamMute(streams[i], false);
+ assertFalse("Unmuting stream " + streams[i] + " using setStreamMute failed.",
+ mAudioManager.isStreamMute(streams[i]));
}
- mAudioManager.adjustStreamVolume(streams[i], AudioManager.ADJUST_MUTE, 0);
- assertTrue("Muting stream " + streams[i] + " failed.",
- mAudioManager.isStreamMute(streams[i]));
-
- mAudioManager.adjustStreamVolume(streams[i], AudioManager.ADJUST_UNMUTE, 0);
- assertFalse("Unmuting stream " + streams[i] + " failed.",
- mAudioManager.isStreamMute(streams[i]));
-
- mAudioManager.adjustStreamVolume(streams[i], AudioManager.ADJUST_TOGGLE_MUTE, 0);
- assertTrue("Toggling mute on stream " + streams[i] + " failed.",
- mAudioManager.isStreamMute(streams[i]));
-
- mAudioManager.adjustStreamVolume(streams[i], AudioManager.ADJUST_TOGGLE_MUTE, 0);
- assertFalse("Toggling mute on stream " + streams[i] + " failed.",
- mAudioManager.isStreamMute(streams[i]));
-
- mAudioManager.setStreamMute(streams[i], true);
- assertTrue("Muting stream " + streams[i] + " using setStreamMute failed",
- mAudioManager.isStreamMute(streams[i]));
-
- // mute it three more times to verify the ref counting is gone.
- mAudioManager.setStreamMute(streams[i], true);
- mAudioManager.setStreamMute(streams[i], true);
- mAudioManager.setStreamMute(streams[i], true);
-
- mAudioManager.setStreamMute(streams[i], false);
- assertFalse("Unmuting stream " + streams[i] + " using setStreamMute failed.",
- mAudioManager.isStreamMute(streams[i]));
+ } finally {
+ Utils.toggleNotificationPolicyAccess(
+ mContext.getPackageName(), getInstrumentation(), false);
}
}
@@ -549,4 +701,5 @@
private int getVolumeDelta(int volume) {
return 1;
}
+
}
diff --git a/tests/tests/media/src/android/media/cts/AudioPlayRoutingNative.java b/tests/tests/media/src/android/media/cts/AudioPlayRoutingNative.java
new file mode 100644
index 0000000..6156095
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/AudioPlayRoutingNative.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2016 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 android.media.cts;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.content.Context;
+import android.cts.util.CtsAndroidTestCase;
+import android.media.AudioDeviceInfo;
+import android.media.AudioManager;
+import android.media.AudioRouting;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+import com.android.ndkaudio.AudioPlayer;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+public class AudioPlayRoutingNative extends AndroidTestCase {
+ private static final String TAG = "AudioPlayRoutingNative";
+
+ private AudioManager mAudioManager;
+
+ static {
+ System.loadLibrary("ndkaudioLib");
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ // get the AudioManager
+ mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+ assertNotNull(mAudioManager);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ //
+ // Tests
+ //
+
+ // Test a basic Aquire/Release cycle on the default player.
+ public void testAquireDefaultProxy() throws Exception {
+ AudioPlayer player = new AudioPlayer();
+ player.ClearLastSLResult();
+ player.RealizePlayer();
+ player.RealizeRoutingProxy();
+
+ AudioRouting routingObj = player.GetRoutingInterface();
+ assertNotNull(routingObj);
+
+ // Not allowed to acquire twice
+ routingObj = player.GetRoutingInterface();
+ assertNull(routingObj);
+ assertTrue(player.GetLastSLResult() != 0);
+
+ player.ReleaseRoutingInterface(routingObj);
+ assertTrue(player.GetLastSLResult() == 0);
+ }
+
+ // Test an Aquire before the OpenSL ES player is Realized.
+ public void testAquirePreRealizeDefaultProxy() throws Exception {
+ AudioPlayer player = new AudioPlayer();
+ player.ClearLastSLResult();
+ player.RealizeRoutingProxy();
+ assertTrue(player.GetLastSLResult() == 0);
+
+ AudioRouting routingObj = player.GetRoutingInterface();
+ assertTrue(player.GetLastSLResult() == 0);
+ assertNotNull(routingObj);
+
+ player.RealizePlayer();
+ assertTrue(player.GetLastSLResult() == 0);
+
+ player.ReleaseRoutingInterface(routingObj);
+ assertTrue(player.GetLastSLResult() == 0);
+ }
+
+ // Test actually setting the routing through the enumerated devices.
+ public void testRouting() {
+ AudioPlayer player = new AudioPlayer();
+ player.ClearLastSLResult();
+ player.RealizePlayer();
+ player.RealizeRoutingProxy();
+
+ AudioRouting routingObj = player.GetRoutingInterface();
+ assertNotNull(routingObj);
+
+ AudioDeviceInfo[] deviceList;
+ deviceList = mAudioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS);
+ assertTrue(deviceList != null);
+ for (AudioDeviceInfo devInfo : deviceList) {
+ assertTrue(routingObj.setPreferredDevice(devInfo));
+ }
+
+ player.ReleaseRoutingInterface(routingObj);
+ assertTrue(player.GetLastSLResult() == 0);
+ }
+}
diff --git a/tests/tests/media/src/android/media/cts/AudioRecordRoutingNative.java b/tests/tests/media/src/android/media/cts/AudioRecordRoutingNative.java
new file mode 100644
index 0000000..c965e14
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/AudioRecordRoutingNative.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2016 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 android.media.cts;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.content.Context;
+import android.media.AudioDeviceInfo;
+import android.media.AudioManager;
+import android.media.AudioRouting;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+import com.android.ndkaudio.AudioRecorder;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+public class AudioRecordRoutingNative extends AndroidTestCase {
+ private static final String TAG = "AudioRecordRoutingNative";
+
+ private AudioManager mAudioManager;
+
+ static {
+ System.loadLibrary("ndkaudioLib");
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ // get the AudioManager
+ mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+ assertNotNull(mAudioManager);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ //
+ // Tests
+ //
+
+ // Test a basic Aquire/Release cycle on the default recorder.
+ public void testAquireDefaultProxy() throws Exception {
+ AudioRecorder recorder = new AudioRecorder();
+ recorder.ClearLastSLResult();
+ recorder.RealizeRecorder();
+ recorder.RealizeRoutingProxy();
+
+ AudioRouting routingObj = recorder.GetRoutingInterface();
+ assertNotNull(routingObj);
+
+ // Not allowed to acquire twice
+ routingObj = recorder.GetRoutingInterface();
+ assertNull(routingObj);
+ assertTrue(recorder.GetLastSLResult() != 0);
+
+ recorder.ReleaseRoutingInterface(routingObj);
+ assertTrue(recorder.GetLastSLResult() == 0);
+ }
+
+ // Test an Aquire before the OpenSL ES recorder is Realized.
+ public void testAquirePreRealizeDefaultProxy() throws Exception {
+ AudioRecorder recorder = new AudioRecorder();
+ recorder.ClearLastSLResult();
+ recorder.RealizeRecorder();
+ recorder.RealizeRoutingProxy();
+ assertTrue(recorder.GetLastSLResult() == 0);
+
+ AudioRouting routingObj = recorder.GetRoutingInterface();
+ assertTrue(recorder.GetLastSLResult() == 0);
+ assertNotNull(routingObj);
+
+ recorder.RealizeRecorder();
+ assertTrue(recorder.GetLastSLResult() == 0);
+
+ recorder.ReleaseRoutingInterface(routingObj);
+ assertTrue(recorder.GetLastSLResult() == 0);
+ }
+
+ // Test actually setting the routing through the enumerated devices.
+ public void testRouting() {
+ AudioRecorder recorder = new AudioRecorder();
+ recorder.ClearLastSLResult();
+ recorder.RealizeRecorder();
+ recorder.RealizeRoutingProxy();
+
+ AudioRouting routingObj = recorder.GetRoutingInterface();
+ assertNotNull(routingObj);
+
+ AudioDeviceInfo[] deviceList;
+ deviceList = mAudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS);
+ assertTrue(deviceList != null);
+ for (AudioDeviceInfo devInfo : deviceList) {
+ assertTrue(routingObj.setPreferredDevice(devInfo));
+ }
+
+ recorder.ReleaseRoutingInterface(routingObj);
+ assertTrue(recorder.GetLastSLResult() == 0);
+ }
+}
diff --git a/tests/tests/media/src/android/media/cts/AudioTrackLatencyTest.java b/tests/tests/media/src/android/media/cts/AudioTrackLatencyTest.java
index 505c4dc..0851a0a 100644
--- a/tests/tests/media/src/android/media/cts/AudioTrackLatencyTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioTrackLatencyTest.java
@@ -54,7 +54,8 @@
public class AudioTrackLatencyTest extends CtsAndroidTestCase {
private String TAG = "AudioTrackLatencyTest";
private final static long NANOS_PER_MILLISECOND = 1000000L;
- private final static long NANOS_PER_SECOND = NANOS_PER_MILLISECOND * 1000L;
+ private final static int MILLIS_PER_SECOND = 1000;
+ private final static long NANOS_PER_SECOND = NANOS_PER_MILLISECOND * MILLIS_PER_SECOND;
private void log(String testName, String message) {
Log.i(TAG, "[" + testName + "] " + message);
@@ -97,8 +98,9 @@
initialBufferSize, track.getBufferSizeInFrames());
int resultZero = track.setBufferSizeInFrames(0);
- assertTrue(TEST_NAME + ": zero size OK", resultZero > 0);
- assertTrue(TEST_NAME + ": zero size < original", resultZero < initialBufferSize);
+ assertTrue(TEST_NAME + ": should be >0, but got " + resultZero, resultZero > 0);
+ assertTrue(TEST_NAME + ": zero size < original, but got " + resultZero,
+ resultZero < initialBufferSize);
assertEquals(TEST_NAME + ": should match resultZero",
resultZero, track.getBufferSizeInFrames());
@@ -118,6 +120,148 @@
track.release();
}
+ // Helper class for tests
+ private static class TestSetup {
+ public int sampleRate = 48000;
+ public int samplesPerFrame = 2;
+ public int bytesPerSample = 2;
+ public int config = AudioFormat.CHANNEL_OUT_STEREO;
+ public int format = AudioFormat.ENCODING_PCM_16BIT;
+ public int mode = AudioTrack.MODE_STREAM;
+ public int streamType = AudioManager.STREAM_MUSIC;
+ public int framesPerBuffer = 256;
+ public double amplitude = 0.5;
+
+ private AudioTrack mTrack;
+ private short[] mData;
+ private int mActualSizeInFrames;
+
+ AudioTrack createTrack() {
+ mData = AudioHelper.createSineWavesShort(framesPerBuffer,
+ samplesPerFrame, 1, amplitude);
+ int minBufferSize = AudioTrack.getMinBufferSize(sampleRate, config, format);
+ // Create a buffer that is 3/2 times bigger than the minimum.
+ // This gives me room to cut it in half and play without glitching.
+ // This is an arbitrary scaling factor.
+ int bufferSize = (minBufferSize * 3) / 2;
+ mTrack = new AudioTrack(streamType, sampleRate, config, format,
+ bufferSize, mode);
+
+ // Calculate and use a smaller buffer size
+ int smallBufferSize = bufferSize / 2; // arbitrary, smaller might underflow
+ int smallBuffSizeInFrames = smallBufferSize / (samplesPerFrame * bytesPerSample);
+ mActualSizeInFrames = mTrack.setBufferSizeInFrames(smallBuffSizeInFrames);
+ return mTrack;
+
+ }
+
+ int primeAudioTrack(String testName) {
+ // Prime the buffer.
+ int samplesWrittenTotal = 0;
+ int samplesWritten;
+ do{
+ samplesWritten = mTrack.write(mData, 0, mData.length);
+ if (samplesWritten > 0) {
+ samplesWrittenTotal += samplesWritten;
+ }
+ } while (samplesWritten == mData.length);
+ int framesWrittenTotal = samplesWrittenTotal / samplesPerFrame;
+ assertTrue(testName + ": framesWrittenTotal = " + framesWrittenTotal
+ + ", size = " + mActualSizeInFrames,
+ framesWrittenTotal >= mActualSizeInFrames);
+ return framesWrittenTotal;
+ }
+
+ /**
+ * @param seconds
+ */
+ public void writeSeconds(double seconds) throws InterruptedException {
+ long msecEnd = System.currentTimeMillis() + (long)(seconds * 1000);
+ while (System.currentTimeMillis() < msecEnd) {
+ // Use non-blocking mode in case the track is hung.
+ int samplesWritten = mTrack.write(mData, 0, mData.length, AudioTrack.WRITE_NON_BLOCKING);
+ if (samplesWritten < mData.length) {
+ int samplesRemaining = mData.length - samplesWritten;
+ int framesRemaining = samplesRemaining / samplesPerFrame;
+ int millis = (framesRemaining * 1000) / sampleRate;
+ Thread.sleep(millis);
+ }
+ }
+ }
+ }
+
+ // Try to play an AudioTrack when the initial size is less than capacity.
+ // We want to make sure the track starts properly and is not stuck.
+ public void testPlaySmallBuffer() throws Exception {
+ final String TEST_NAME = "testPlaySmallBuffer";
+ TestSetup setup = new TestSetup();
+ AudioTrack track = setup.createTrack();
+
+ // Prime the buffer.
+ int framesWrittenTotal = setup.primeAudioTrack(TEST_NAME);
+
+ // Start playing and let it drain.
+ int position1 = track.getPlaybackHeadPosition();
+ assertEquals(TEST_NAME + ": initial position", 0, position1);
+ track.play();
+
+ // Make sure it starts within a reasonably short time.
+ final long MAX_TIME_TO_START_MSEC = 500; // arbitrary
+ long giveUpAt = System.currentTimeMillis() + MAX_TIME_TO_START_MSEC;
+ int position2 = track.getPlaybackHeadPosition();
+ while ((position1 == position2)
+ && (System.currentTimeMillis() < giveUpAt)) {
+ Thread.sleep(20); // arbitrary interval
+ position2 = track.getPlaybackHeadPosition();
+ }
+ assertTrue(TEST_NAME + ": did it start?, position after start = " + position2,
+ position2 > position1);
+
+ // Make sure it finishes playing the data.
+ // Wait several times longer than it should take to play the data.
+ final int several = 3; // arbitrary
+ Thread.sleep(several * framesWrittenTotal * MILLIS_PER_SECOND / setup.sampleRate);
+ position2 = track.getPlaybackHeadPosition();
+ assertEquals(TEST_NAME + ": did it play all the data?",
+ framesWrittenTotal, position2);
+
+ track.release();
+ }
+
+ // Try to play and pause an AudioTrack when the initial size is less than capacity.
+ // We want to make sure the track starts properly and is not stuck.
+ public void testPlayPauseSmallBuffer() throws Exception {
+ final String TEST_NAME = "testPlayPauseSmallBuffer";
+ TestSetup setup = new TestSetup();
+ AudioTrack track = setup.createTrack();
+
+ // Prime the buffer.
+ setup.primeAudioTrack(TEST_NAME);
+
+ // Start playing then pause and play in a loop.
+ int position1 = track.getPlaybackHeadPosition();
+ assertEquals(TEST_NAME + ": initial position", 0, position1);
+ track.play();
+ // try pausing several times to see it if it fails
+ final int several = 4; // arbitrary
+ for (int i = 0; i < several; i++) {
+ // write data in non-blocking mode for a few seconds
+ setup.writeSeconds(2.0); // arbitrary, long enough for audio to get to the device
+ // Did position advance as we were playing? Or was the track stuck?
+ int position2 = track.getPlaybackHeadPosition();
+ int delta = position2 - position1; // safe from wrapping
+ assertTrue(TEST_NAME + ": [" + i + "] did it advance? p1 = " + position1
+ + ", p2 = " + position2, delta > 0);
+ position1 = position2;
+ // pause for a second
+ track.pause();
+ Thread.sleep(MILLIS_PER_SECOND);
+ track.play();
+ }
+
+ track.release();
+ }
+
// Create a track with or without FLAG_LOW_LATENCY
private AudioTrack createCustomAudioTrack(boolean lowLatency) {
final String TEST_NAME = "createCustomAudioTrack";
@@ -303,7 +447,7 @@
// Play with ridiculously small size. We want to get underruns so we know that an app
// can get to the edge of underrunning.
int resultZero = track.setBufferSizeInFrames(0);
- assertTrue(TEST_NAME + ": zero size OK", resultZero > 0);
+ assertTrue(TEST_NAME + ": should return > 0, got " + resultZero, resultZero > 0);
assertTrue(TEST_NAME + ": zero size < original", resultZero < initialBufferSize);
numSeconds = TEST_NUM_SECONDS / 2; // cuz test takes longer when underflowing
numBuffers = numSeconds * TEST_SR / TEST_FRAMES_PER_BUFFER;
diff --git a/tests/tests/media/src/android/media/cts/Utils.java b/tests/tests/media/src/android/media/cts/Utils.java
index bb9cf78..914a0518 100644
--- a/tests/tests/media/src/android/media/cts/Utils.java
+++ b/tests/tests/media/src/android/media/cts/Utils.java
@@ -18,9 +18,13 @@
import android.app.Instrumentation;
import android.app.UiAutomation;
+import android.content.ContentResolver;
+import android.content.Context;
import android.os.ParcelFileDescriptor;
+import android.provider.Settings;
import java.io.FileInputStream;
+import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;
@@ -67,4 +71,39 @@
result = convertStreamToString(inputStream);
}
}
+
+ protected static void toggleNotificationPolicyAccess(String packageName,
+ Instrumentation instrumentation, boolean on) throws IOException {
+ Context context = instrumentation.getContext();
+
+ // Get permission to enable accessibility
+ UiAutomation uiAutomation = instrumentation.getUiAutomation();
+
+ ContentResolver cr = context.getContentResolver();
+ String alreadyEnabledServices = Settings.Secure.getString(
+ cr, Settings.Secure.ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES);
+ ParcelFileDescriptor fd = null;
+ if (on) {
+ // Change the settings to enable the media cts package
+ fd = uiAutomation.executeShellCommand(
+ "settings --user cur put secure "
+ + Settings.Secure.ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES + " "
+ + alreadyEnabledServices + ":"
+ + packageName);
+ } else {
+ int index = alreadyEnabledServices.indexOf(":" + packageName);
+ if (index >= 0) {
+ fd = uiAutomation.executeShellCommand(
+ "settings --user cur put secure "
+ + Settings.Secure.ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES + " "
+ + alreadyEnabledServices.substring(0, index));
+ }
+ }
+ if (fd != null) {
+ InputStream in = new FileInputStream(fd.getFileDescriptor());
+ byte[] buffer = new byte[4096];
+ while (in.read(buffer) > 0) ;
+ }
+ uiAutomation.destroy();
+ }
}
diff --git a/tests/tests/mediastress/preconditions/src/android/mediastress/cts/preconditions/MediaPreparer.java b/tests/tests/mediastress/preconditions/src/android/mediastress/cts/preconditions/MediaPreparer.java
index 35d4bbd..7254045 100644
--- a/tests/tests/mediastress/preconditions/src/android/mediastress/cts/preconditions/MediaPreparer.java
+++ b/tests/tests/mediastress/preconditions/src/android/mediastress/cts/preconditions/MediaPreparer.java
@@ -18,14 +18,11 @@
import com.android.compatibility.common.tradefed.targetprep.PreconditionPreparer;
import com.android.compatibility.common.util.DynamicConfigHostSide;
import com.android.ddmlib.IDevice;
-import com.android.ddmlib.Log;
import com.android.tradefed.build.IBuildInfo;
import com.android.tradefed.config.Option;
import com.android.tradefed.config.OptionClass;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil;
-import com.android.tradefed.log.LogUtil.CLog;
import com.android.tradefed.targetprep.BuildError;
import com.android.tradefed.targetprep.TargetSetupError;
import com.android.tradefed.util.FileUtil;
@@ -150,7 +147,7 @@
if(!matcher.find()) {
// could not find resolution in dumpsysOutput, return largest max playback resolution
// so that preparer copies all media files
- CLog.e(MAX_PLAYBACK_RES_FAILURE_MSG);
+ logError(MAX_PLAYBACK_RES_FAILURE_MSG);
return resolutions[RES_1920_1080];
}
@@ -160,7 +157,7 @@
first = Integer.parseInt(matcher.group(1));
second = Integer.parseInt(matcher.group(2));
} catch (NumberFormatException e) {
- CLog.e(MAX_PLAYBACK_RES_FAILURE_MSG);
+ logError(MAX_PLAYBACK_RES_FAILURE_MSG);
return resolutions[RES_1920_1080];
}
// dimensions in dumpsys output seem consistently reversed
@@ -195,11 +192,6 @@
return true;
}
- /* A simple helper to print messages to the tradefed console */
- private static void printInfo(String info) {
- LogUtil.printLog(Log.LogLevel.INFO, LOG_TAG, info);
- }
-
/*
* After downloading and unzipping the media files, mLocalMediaPath must be the path to the
* directory containing 'bbb_short' and 'bbb_full' directories, as it is defined in its
@@ -249,7 +241,7 @@
new BufferedOutputStream(new FileOutputStream(mediaFolderZip));
byte[] buffer = new byte[1024];
int count;
- printInfo("Downloading media files to host");
+ logInfo("Downloading media files to host");
while ((count = in.read(buffer)) >= 0) {
out.write(buffer, 0, count);
}
@@ -257,7 +249,7 @@
out.close();
in.close();
- printInfo("Unzipping media files");
+ logInfo("Unzipping media files");
ZipUtil.extractZip(new ZipFile(mediaFolderZip), mediaFolder);
} catch (IOException e) {
@@ -283,16 +275,15 @@
Dimension copiedResolution = resolutions[resIndex];
String resString = resolutionString(copiedResolution);
if (copiedResolution.width > mvpr.width || copiedResolution.height > mvpr.height) {
- printInfo(String.format(
- "Device cannot support resolutions %s and larger, media copying complete",
- resString));
+ logInfo("Device cannot support resolutions %s and larger, media copying complete",
+ resString);
return;
}
String deviceShortFilePath = baseDeviceShortDir + resString;
String deviceFullFilePath = baseDeviceFullDir + resString;
if (!device.doesFileExist(deviceShortFilePath) ||
!device.doesFileExist(deviceFullFilePath)) {
- printInfo(String.format("Copying files of resolution %s to device", resString));
+ logInfo("Copying files of resolution %s to device", resString);
String localShortDirName = "bbb_short/" + resString;
String localFullDirName = "bbb_full/" + resString;
File localShortDir = new File(mLocalMediaPath, localShortDirName);
@@ -330,7 +321,7 @@
Dimension mvpr = getMaxVideoPlaybackResolution(device);
if (mediaFilesExistOnDevice(device, mvpr)) {
// if files already on device, do nothing
- printInfo("Media files found on the device");
+ logInfo("Media files found on the device");
return;
}
@@ -356,7 +347,7 @@
updateLocalMediaPath(mediaFolder);
}
- printInfo(String.format("Media files located on host at: %s", mLocalMediaPath));
+ logInfo("Media files located on host at: %s", mLocalMediaPath);
copyMediaFiles(device, mvpr);
}
diff --git a/tests/tests/mediastress/src/android/mediastress/cts/MediaPlayerStressTest.java b/tests/tests/mediastress/src/android/mediastress/cts/MediaPlayerStressTest.java
index 6f4ebdd..b33451b 100644
--- a/tests/tests/mediastress/src/android/mediastress/cts/MediaPlayerStressTest.java
+++ b/tests/tests/mediastress/src/android/mediastress/cts/MediaPlayerStressTest.java
@@ -19,7 +19,6 @@
import android.app.Activity;
import android.app.Instrumentation;
import android.content.Intent;
-import android.media.CamcorderProfile;
import android.cts.util.MediaUtils;
import android.media.MediaRecorder.AudioEncoder;
import android.media.MediaRecorder.VideoEncoder;
diff --git a/tests/tests/mediastress/src/android/mediastress/cts/NativeMediaActivity.java b/tests/tests/mediastress/src/android/mediastress/cts/NativeMediaActivity.java
index a37d4c2..ca935c4 100644
--- a/tests/tests/mediastress/src/android/mediastress/cts/NativeMediaActivity.java
+++ b/tests/tests/mediastress/src/android/mediastress/cts/NativeMediaActivity.java
@@ -20,7 +20,6 @@
import android.app.Activity;
import android.content.res.Configuration;
import android.graphics.SurfaceTexture;
-import android.media.CamcorderProfile;
import android.os.Bundle;
import android.util.Log;
import android.view.Surface;
@@ -34,7 +33,7 @@
import junit.framework.Assert;
public class NativeMediaActivity extends Activity implements OnSurfaceChangedListener {
- public static final String EXTRA_VIDEO_QUALITY = "videoQuality";
+ public static final String EXTRA_VIDEO_HEIGHT = "videoHeight";
// should be long enough. time-out can be treated as error
public static final long NATIVE_MEDIA_LIFECYCLE_TIMEOUT_MS = 10000;
static final String TAG = "NativeMedia";
@@ -51,8 +50,7 @@
private SurfaceTextureGLSurfaceView mGLView;
private volatile boolean mNativeCreated = false;
- /** 0 for default (480x360), other value can be CamcorderProfile.QUALITY_480P / 720P / 1080P */
- private int mVideoQuality = 0;
+ private int mVideoHeight = 360;
// native media status queued whenever there is a change in life.
private final BlockingQueue<Boolean> mNativeWaitQ = new LinkedBlockingQueue<Boolean>();
@@ -61,7 +59,7 @@
super.onCreate(icicle);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON |
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
- mVideoQuality = getIntent().getIntExtra(EXTRA_VIDEO_QUALITY, mVideoQuality);
+ mVideoHeight = getIntent().getIntExtra(EXTRA_VIDEO_HEIGHT, mVideoHeight);
mGLView = new SurfaceTextureGLSurfaceView(this, this);
setContentView(mGLView);
}
@@ -159,14 +157,14 @@
private String getMediaString() {
int mediaIndex = 0; // default: 480x360
- switch(mVideoQuality) {
- case CamcorderProfile.QUALITY_1080P:
+ switch(mVideoHeight) {
+ case 1080:
mediaIndex = 3;
break;
- case CamcorderProfile.QUALITY_720P:
+ case 720:
mediaIndex = 2;
break;
- case CamcorderProfile.QUALITY_480P:
+ case 480:
mediaIndex = 1;
break;
}
diff --git a/tests/tests/mediastress/src/android/mediastress/cts/NativeMediaTest.java b/tests/tests/mediastress/src/android/mediastress/cts/NativeMediaTest.java
index 05145f5..40284a6 100644
--- a/tests/tests/mediastress/src/android/mediastress/cts/NativeMediaTest.java
+++ b/tests/tests/mediastress/src/android/mediastress/cts/NativeMediaTest.java
@@ -18,7 +18,6 @@
import android.app.Instrumentation;
import android.content.Intent;
import android.cts.util.MediaUtils;
-import android.media.CamcorderProfile;
import android.media.MediaFormat;
import android.media.MediaRecorder.AudioEncoder;
import android.media.MediaRecorder.VideoEncoder;
@@ -40,37 +39,30 @@
}
public void test1080pPlay() throws InterruptedException {
- runPlayTest(CamcorderProfile.QUALITY_1080P);
+ runPlayTest(1920, 1080);
}
public void test720pPlay() throws InterruptedException {
- runPlayTest(CamcorderProfile.QUALITY_720P);
+ runPlayTest(1280, 720);
}
public void test480pPlay() throws InterruptedException {
- runPlayTest(CamcorderProfile.QUALITY_480P);
+ runPlayTest(720, 480);
}
public void testDefaultPlay() throws InterruptedException {
- runPlayTest(0);
+ runPlayTest(480, 360);
}
- private void runPlayTest(int quality) throws InterruptedException {
+ private void runPlayTest(int width, int height) throws InterruptedException {
+ MediaFormat format = MediaFormat.createVideoFormat(MIME_TYPE, width, height);
// Don't run the test if the codec isn't supported.
- if (!MediaUtils.checkDecoder(MIME_TYPE)) {
+ if (!MediaUtils.canDecode(format)) {
return; // skip
}
- // Don't run the test if the quality level isn't supported.
- if (quality != 0) {
- if (!isResolutionSupported(quality)) {
- Log.w(TAG, "Quality level " + quality + " not supported.");
- return;
- }
- }
Intent intent = new Intent();
- intent.putExtra(NativeMediaActivity.EXTRA_VIDEO_QUALITY,
- quality);
+ intent.putExtra(NativeMediaActivity.EXTRA_VIDEO_HEIGHT, height);
setActivityIntent(intent);
final NativeMediaActivity activity = getActivity();
final Instrumentation instrumentation = getInstrumentation();
@@ -98,17 +90,4 @@
Assert.assertNotNull(status); // null means time-out
Assert.assertEquals(expectAlive, status.booleanValue());
}
-
- private boolean isResolutionSupported(int quality) {
- Assert.assertEquals(Environment.getExternalStorageState(), Environment.MEDIA_MOUNTED);
- if (!CamcorderProfile.hasProfile(quality)) {
- return false;
- }
- CamcorderProfile profile = CamcorderProfile.get(quality);
- if ((profile != null) && (profile.videoCodec == VIDEO_CODEC) &&
- (profile.audioCodec == AudioEncoder.AAC)) {
- return true;
- }
- return false;
- }
}
diff --git a/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
index 55fd1f5..5497454 100644
--- a/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
+++ b/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
@@ -484,6 +484,9 @@
}
assertTrue(mWifiManager.isWifiEnabled());
+ // This will generate a distinct stack trace if the initial connection fails.
+ connectWifi();
+
int i = 0;
for (; i < 15; i++) {
// Wait for a WiFi connection
diff --git a/tests/tests/os/Android.mk b/tests/tests/os/Android.mk
index c837ce3..bbee284 100644
--- a/tests/tests/os/Android.mk
+++ b/tests/tests/os/Android.mk
@@ -24,15 +24,17 @@
# Include both the 32 and 64 bit versions
LOCAL_MULTILIB := both
-LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner guava
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ ctsdeviceutil ctstestrunner guava platform-test-annotations
LOCAL_JNI_SHARED_LIBRARIES := libcts_jni libctsos_jni libnativehelper_compat_libc++
-LOCAL_SRC_FILES := $(call all-java-files-under, src) \
- src/android/os/cts/IParcelFileDescriptorPeer.aidl \
- src/android/os/cts/IEmptyService.aidl \
- src/android/os/cts/ISeccompIsolatedService.aidl \
- src/android/os/cts/ISecondary.aidl
+LOCAL_SRC_FILES := \
+ $(call all-java-files-under, src) \
+ src/android/os/cts/IParcelFileDescriptorPeer.aidl \
+ src/android/os/cts/IEmptyService.aidl \
+ src/android/os/cts/ISeccompIsolatedService.aidl \
+ src/android/os/cts/ISecondary.aidl
LOCAL_PACKAGE_NAME := CtsOsTestCases
diff --git a/tests/tests/os/src/android/os/cts/CustomClassLoaderTest.java b/tests/tests/os/src/android/os/cts/CustomClassLoaderTest.java
index bd88073..4c4804e 100644
--- a/tests/tests/os/src/android/os/cts/CustomClassLoaderTest.java
+++ b/tests/tests/os/src/android/os/cts/CustomClassLoaderTest.java
@@ -19,6 +19,7 @@
import java.io.*;
import java.lang.reflect.*;
+import android.platform.test.annotations.Presubmit;
import android.test.AndroidTestCase;
public class CustomClassLoaderTest extends AndroidTestCase {
@@ -76,6 +77,7 @@
/* Test a custom class loader based on the PathClassLoader.
*/
+ @Presubmit
public void testCustomPathClassLoader() throws Exception {
// Try to load the TestClass class by the CustomPathClassLoader.
try {
diff --git a/tests/tests/os/src/android/os/cts/HardwarePropertiesManagerTest.java b/tests/tests/os/src/android/os/cts/HardwarePropertiesManagerTest.java
deleted file mode 100644
index 4239fa2..0000000
--- a/tests/tests/os/src/android/os/cts/HardwarePropertiesManagerTest.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (C) 2015 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 android.os.cts;
-
-import android.content.Context;
-import android.os.CpuUsageInfo;
-import android.os.HardwarePropertiesManager;
-import android.os.SystemClock;
-import android.test.AndroidTestCase;
-
-import java.lang.Math;
-
-public class HardwarePropertiesManagerTest extends AndroidTestCase {
- public static final int MAX_FAN_SPEED = 20000;
- public static final int MAX_DEVICE_TEMP = 200;
- public static final int MONITORING_ITERATION_NUMBER = 10;
-
- // Time between checks in milliseconds.
- public static final long SLEEP_TIME = 10;
-
- private void checkFanSpeed(float speed) {
- assertTrue(speed >= 0 && speed < MAX_FAN_SPEED);
- }
-
- private void checkDeviceTemp(float temp) {
- assertTrue(Math.abs(temp) < MAX_DEVICE_TEMP);
- }
-
- private void checkCpuUsageInfo(CpuUsageInfo info) {
- assertTrue(info.getActive() >= 0 && info.getTotal() >= 0 && info.getTotal() >= info.getActive());
- }
-
- private void checkFanSpeeds(float[] fanSpeeds) {
- for (float speed : fanSpeeds) {
- checkFanSpeed(speed);
- }
- }
-
- private void checkTemps(float[] temps) {
- for (float temp : temps) {
- checkDeviceTemp(temp);
- }
- }
-
- private void checkCpuUsages(CpuUsageInfo[] cpuUsages) {
- for (CpuUsageInfo info : cpuUsages) {
- checkCpuUsageInfo(info);
- }
- }
-
- // Check validity of new array of fan speeds:
- // the number of fans should be the same.
- private void checkFanSpeeds(float[] speeds, float[] oldSpeeds) {
- assertEquals(speeds.length, oldSpeeds.length);
- }
-
- // Check validity of new array of device temperatures:
- // the number of entries should be the same.
- private void checkDeviceTemps(float[] temps, float[] oldTemps) {
- assertEquals(temps.length, oldTemps.length);
- }
-
- // Check validity of new array of cpu usages:
- // The number of CPUs should be the same and total/active time should not decrease.
- private void checkCpuUsages(CpuUsageInfo[] infos,
- CpuUsageInfo[] oldInfos) {
- assertEquals(infos.length, oldInfos.length);
- for (int i = 0; i < infos.length; ++i) {
- assertTrue(oldInfos[i].getActive() <= infos[i].getActive() &&
- oldInfos[i].getTotal() <= infos[i].getTotal());
- }
- }
-
- /**
- * test points:
- * 1. Get fan speeds, device temperatures and CPU usage information.
- * 2. Check for validity.
- * 3. Sleep.
- * 4. Do it 10 times and compare with old ones.
- */
- public void testHardwarePropertiesManager() throws InterruptedException {
- HardwarePropertiesManager hm = (HardwarePropertiesManager) getContext().getSystemService(
- Context.HARDWARE_PROPERTIES_SERVICE);
-
- float[] oldFanSpeeds = hm.getFanSpeeds();
- float[] oldCpuTemps = hm.getDeviceTemperatures(
- HardwarePropertiesManager.DEVICE_TEMPERATURE_CPU);
- float[] oldGpuTemps = hm.getDeviceTemperatures(
- HardwarePropertiesManager.DEVICE_TEMPERATURE_GPU);
- float[] oldBatteryTemps = hm.getDeviceTemperatures(
- HardwarePropertiesManager.DEVICE_TEMPERATURE_BATTERY);
- CpuUsageInfo[] oldCpuUsages = hm.getCpuUsages();
-
- checkFanSpeeds(oldFanSpeeds);
- checkTemps(oldCpuTemps);
- checkTemps(oldGpuTemps);
- checkTemps(oldBatteryTemps);
- checkCpuUsages(oldCpuUsages);
-
- for (int i = 0; i < MONITORING_ITERATION_NUMBER; i++) {
- Thread.sleep(SLEEP_TIME);
-
- float[] fanSpeeds = hm.getFanSpeeds();
- float[] cpuTemps = hm.getDeviceTemperatures(
- HardwarePropertiesManager.DEVICE_TEMPERATURE_CPU);
- float[] gpuTemps = hm.getDeviceTemperatures(
- HardwarePropertiesManager.DEVICE_TEMPERATURE_GPU);
- float[] batteryTemps = hm.getDeviceTemperatures(
- HardwarePropertiesManager.DEVICE_TEMPERATURE_BATTERY);
- CpuUsageInfo[] cpuUsages = hm.getCpuUsages();
-
- checkFanSpeeds(fanSpeeds);
- checkTemps(cpuTemps);
- checkTemps(gpuTemps);
- checkTemps(batteryTemps);
- checkCpuUsages(cpuUsages);
-
- checkFanSpeeds(fanSpeeds, oldFanSpeeds);
- checkDeviceTemps(cpuTemps, oldCpuTemps);
- checkDeviceTemps(gpuTemps, oldGpuTemps);
- checkDeviceTemps(batteryTemps, oldBatteryTemps);
- checkCpuUsages(cpuUsages, oldCpuUsages);
-
- oldFanSpeeds = fanSpeeds;
- oldCpuTemps = cpuTemps;
- oldGpuTemps = gpuTemps;
- oldBatteryTemps = batteryTemps;
- oldCpuUsages = cpuUsages;
- }
- }
-}
diff --git a/tests/tests/permission/Android.mk b/tests/tests/permission/Android.mk
index 2de9d9c..c37ddfc 100644
--- a/tests/tests/permission/Android.mk
+++ b/tests/tests/permission/Android.mk
@@ -29,7 +29,8 @@
LOCAL_JAVA_LIBRARIES := telephony-common
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner guava android-ex-camera2
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ ctstestrunner guava android-ex-camera2 platform-test-annotations
LOCAL_JNI_SHARED_LIBRARIES := libctspermission_jni libnativehelper_compat_libc++
diff --git a/tests/tests/permission/src/android/permission/cts/Camera2PermissionTest.java b/tests/tests/permission/src/android/permission/cts/Camera2PermissionTest.java
index 021a501..e40d7cb 100644
--- a/tests/tests/permission/src/android/permission/cts/Camera2PermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/Camera2PermissionTest.java
@@ -23,6 +23,7 @@
import android.hardware.camera2.CameraManager;
import android.os.Handler;
import android.os.HandlerThread;
+import android.platform.test.annotations.Presubmit;
import android.test.AndroidTestCase;
import android.util.Log;
@@ -96,6 +97,7 @@
/**
* Add and remove availability listeners should work without permission.
*/
+ @Presubmit
public void testAvailabilityCallback() throws Exception {
DummyCameraListener availabilityListener = new DummyCameraListener();
// Remove a not-registered listener is a no-op.
diff --git a/tests/tests/print/AndroidTest.xml b/tests/tests/print/AndroidTest.xml
index 21d8f03..68aa157 100644
--- a/tests/tests/print/AndroidTest.xml
+++ b/tests/tests/print/AndroidTest.xml
@@ -20,5 +20,6 @@
</target_preparer>
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.print.cts" />
+ <option name="runtime-hint" value="12m35s" />
</test>
-</configuration>
\ No newline at end of file
+</configuration>
diff --git a/tests/tests/provider/Android.mk b/tests/tests/provider/Android.mk
index b92a924..59fb9f6 100644
--- a/tests/tests/provider/Android.mk
+++ b/tests/tests/provider/Android.mk
@@ -32,7 +32,8 @@
LOCAL_JAVA_LIBRARIES := android.test.runner telephony-common
-LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ ctsdeviceutil ctstestrunner platform-test-annotations
LOCAL_JNI_SHARED_LIBRARIES := libcts_jni libnativehelper_compat_libc++
diff --git a/tests/tests/provider/src/android/provider/cts/BlockedNumberBackupRestoreTest.java b/tests/tests/provider/src/android/provider/cts/BlockedNumberBackupRestoreTest.java
new file mode 100644
index 0000000..fc0333c
--- /dev/null
+++ b/tests/tests/provider/src/android/provider/cts/BlockedNumberBackupRestoreTest.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2016 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 android.provider.cts;
+
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.provider.BlockedNumberContract;
+import android.telecom.Log;
+
+import java.util.Objects;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * CTS tests for backup and restore of blocked numbers using local transport.
+ */
+// To run the tests in this file w/o running all the cts tests:
+// make cts
+// cts-tradefed
+// run cts -m CtsProviderTestCases --test android.provider.cts.BlockedNumberBackupRestoreTest
+public class BlockedNumberBackupRestoreTest extends TestCaseThatRunsIfTelephonyIsEnabled {
+ private static final String TAG = "BlockedNumberBackupRestoreTest";
+ private static final String LOCAL_BACKUP_COMPONENT =
+ "android/com.android.internal.backup.LocalTransport";
+ private static final String BLOCKED_NUMBERS_PROVIDER_PACKAGE =
+ "com.android.providers.blockednumber";
+ private static final int BACKUP_TIMEOUT_MILLIS = 4000;
+ private static final Pattern BMGR_ENABLED_PATTERN = Pattern.compile(
+ "^Backup Manager currently (enabled|disabled)$");
+
+ private ContentResolver mContentResolver;
+ private Context mContext;
+ private String mOldTransport;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mContext = getInstrumentation().getContext();
+ mContentResolver = mContext.getContentResolver();
+
+ BlockedNumberTestUtils.setDefaultSmsApp(
+ true, mContext.getPackageName(), getInstrumentation().getUiAutomation());
+
+ mOldTransport = setBackupTransport(LOCAL_BACKUP_COMPONENT);
+ clearBlockedNumbers();
+ wipeBackup();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ wipeBackup();
+ clearBlockedNumbers();
+ setBackupTransport(mOldTransport);
+
+ BlockedNumberTestUtils.setDefaultSmsApp(
+ false, mContext.getPackageName(), getInstrumentation().getUiAutomation());
+
+ super.tearDown();
+ }
+
+ public void testBackupAndRestoreForSingleNumber() throws Exception {
+ if (!hasBackupTransport(LOCAL_BACKUP_COMPONENT)) {
+ Log.i(TAG, "skipping BlockedNumberBackupRestoreTest");
+ }
+
+ Log.i(TAG, "Adding blocked numbers.");
+ insertBlockedNumber("123456789");
+
+ Log.i(TAG, "Running backup.");
+ runBackup();
+ Thread.sleep(BACKUP_TIMEOUT_MILLIS);
+
+ Log.i(TAG, "Clearing blocked numbers.");
+ clearBlockedNumbers();
+ verifyBlockedNumbers();
+
+ Log.i(TAG, "Restoring blocked numbers.");
+ runRestore();
+ Thread.sleep(BACKUP_TIMEOUT_MILLIS);
+ verifyBlockedNumbers("123456789");
+ }
+
+ public void testBackupAndRestoreWithDeletion() throws Exception {
+ if (!hasBackupTransport(LOCAL_BACKUP_COMPONENT)) {
+ Log.i(TAG, "skipping BlockedNumberBackupRestoreTest");
+ }
+
+ Log.i(TAG, "Adding blocked numbers.");
+ insertBlockedNumber("123456789");
+ insertBlockedNumber("223456789");
+ insertBlockedNumber("323456789");
+
+ Log.i(TAG, "Running backup.");
+ runBackup();
+ Thread.sleep(BACKUP_TIMEOUT_MILLIS);
+
+ Log.i(TAG, "Deleting blocked number.");
+ deleteNumber("123456789");
+ verifyBlockedNumbers("223456789", "323456789");
+
+ Log.i(TAG, "Running backup.");
+ runBackup();
+ Thread.sleep(BACKUP_TIMEOUT_MILLIS);
+
+ Log.i(TAG, "Clearing blocked numbers.");
+ clearBlockedNumbers();
+ verifyBlockedNumbers();
+
+ Log.i(TAG, "Restoring blocked numbers.");
+ runRestore();
+ Thread.sleep(BACKUP_TIMEOUT_MILLIS);
+ verifyBlockedNumbers("223456789", "323456789");
+ }
+
+ private void insertBlockedNumber(String number) {
+ ContentValues cv = new ContentValues();
+ cv.put(BlockedNumberContract.BlockedNumbers.COLUMN_ORIGINAL_NUMBER, number);
+ mContentResolver.insert(BlockedNumberContract.BlockedNumbers.CONTENT_URI, cv);
+ }
+
+ private void deleteNumber(String number) {
+ assertEquals(1,
+ mContentResolver.delete(
+ BlockedNumberContract.BlockedNumbers.CONTENT_URI,
+ BlockedNumberContract.BlockedNumbers.COLUMN_ORIGINAL_NUMBER + "= ?",
+ new String[] {number}));
+ }
+
+ private void verifyBlockedNumbers(String ... blockedNumbers) {
+ assertEquals(blockedNumbers.length,
+ mContentResolver.query(
+ BlockedNumberContract.BlockedNumbers.CONTENT_URI, null, null, null, null)
+ .getCount());
+ for (String blockedNumber : blockedNumbers) {
+ assertTrue(BlockedNumberContract.isBlocked(mContext, blockedNumber));
+ }
+ }
+
+ private void clearBlockedNumbers() {
+ mContentResolver.delete(BlockedNumberContract.BlockedNumbers.CONTENT_URI, null, null);
+ }
+
+ private boolean hasBackupTransport(String transport) throws Exception {
+ String output = BlockedNumberTestUtils.executeShellCommand(
+ getInstrumentation().getUiAutomation(), "bmgr list transports");
+ for (String t : output.split(" ")) {
+ if ("*".equals(t)) {
+ // skip the current selection marker.
+ continue;
+ } else if (Objects.equals(transport, t)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private String setBackupTransport(String transport) throws Exception {
+ String output = exec("bmgr transport " + transport);
+ Pattern pattern = Pattern.compile("\\(formerly (.*)\\)$");
+ Matcher matcher = pattern.matcher(output);
+ if (matcher.find()) {
+ return matcher.group(1);
+ } else {
+ throw new Exception("non-parsable output setting bmgr transport: " + output);
+ }
+ }
+
+ private void runBackup() throws Exception {
+ exec("bmgr backupnow " + BLOCKED_NUMBERS_PROVIDER_PACKAGE);
+ }
+
+ private void runRestore() throws Exception {
+ exec("bmgr restore " + BLOCKED_NUMBERS_PROVIDER_PACKAGE);
+ }
+
+ private void wipeBackup() throws Exception {
+ exec("bmgr wipe " + LOCAL_BACKUP_COMPONENT + " " + BLOCKED_NUMBERS_PROVIDER_PACKAGE);
+ }
+
+ private String exec(String command) throws Exception {
+ return BlockedNumberTestUtils.executeShellCommand(
+ getInstrumentation().getUiAutomation(), command);
+ }
+}
diff --git a/tests/tests/provider/src/android/provider/cts/BlockedNumberContractTest.java b/tests/tests/provider/src/android/provider/cts/BlockedNumberContractTest.java
index 7ea63f3..9509d00 100644
--- a/tests/tests/provider/src/android/provider/cts/BlockedNumberContractTest.java
+++ b/tests/tests/provider/src/android/provider/cts/BlockedNumberContractTest.java
@@ -43,7 +43,7 @@
// To run the tests in this file w/o running all the cts tests:
// make cts
// cts-tradefed
-// run cts -c android.provider.cts.BlockedNumberContractTest
+// run cts -m CtsProviderTestCases --test android.provider.cts.BlockedNumberContractTest
public class BlockedNumberContractTest extends TestCaseThatRunsIfTelephonyIsEnabled {
private ContentResolver mContentResolver;
private Context mContext;
@@ -105,11 +105,7 @@
} catch (SecurityException expected) {
}
- try {
- BlockedNumberContract.canCurrentUserBlockNumbers(mContext);
- fail("Should throw SecurityException");
- } catch (SecurityException expected) {
- }
+ assertTrue(BlockedNumberContract.canCurrentUserBlockNumbers(mContext));
}
public void testGetType() throws Exception {
@@ -344,17 +340,7 @@
}
private void setDefaultSmsApp(boolean setToSmsApp) throws Exception {
- StringBuilder command = new StringBuilder();
- command.append("appops set ");
- command.append(mContext.getPackageName());
- command.append(" WRITE_SMS ");
- command.append(setToSmsApp ? "allow" : "default");
-
- ParcelFileDescriptor pfd = getInstrumentation().getUiAutomation()
- .executeShellCommand(command.toString());
-
- InputStream is = new FileInputStream(pfd.getFileDescriptor());
- final byte[] buffer = new byte[8192];
- while ((is.read(buffer)) != -1);
+ BlockedNumberTestUtils.setDefaultSmsApp(
+ setToSmsApp, mContext.getPackageName(), getInstrumentation().getUiAutomation());
}
}
diff --git a/tests/tests/provider/src/android/provider/cts/BlockedNumberTestUtils.java b/tests/tests/provider/src/android/provider/cts/BlockedNumberTestUtils.java
new file mode 100644
index 0000000..b520542
--- /dev/null
+++ b/tests/tests/provider/src/android/provider/cts/BlockedNumberTestUtils.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2016 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 android.provider.cts;
+
+import android.app.UiAutomation;
+import android.os.ParcelFileDescriptor;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * Utility methods for blocked number cts tests.
+ */
+public class BlockedNumberTestUtils {
+ static void setDefaultSmsApp(boolean setToSmsApp, String packageName, UiAutomation uiAutomation)
+ throws Exception {
+ String command = String.format(
+ "appops set %s WRITE_SMS %s", packageName, setToSmsApp ? "allow" : "default");
+ executeShellCommand(uiAutomation, command);
+ }
+
+ static String executeShellCommand(UiAutomation uiAutomation, String command)
+ throws IOException {
+ ParcelFileDescriptor pfd = uiAutomation.executeShellCommand(command.toString());
+ BufferedReader br = null;
+ try (InputStream in = new FileInputStream(pfd.getFileDescriptor());) {
+ br = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8));
+ String str = null;
+ StringBuilder out = new StringBuilder();
+ while ((str = br.readLine()) != null) {
+ out.append(str);
+ }
+ return out.toString();
+ } finally {
+ if (br != null) {
+ br.close();
+ }
+ }
+ }
+}
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Images_MediaTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Images_MediaTest.java
index 589b5cd..8bf2516 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Images_MediaTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Images_MediaTest.java
@@ -28,6 +28,7 @@
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Environment;
+import android.platform.test.annotations.Presubmit;
import android.provider.MediaStore.Images.Media;
import android.provider.MediaStore.Images.Thumbnails;
import android.test.InstrumentationTestCase;
@@ -178,6 +179,7 @@
assertEquals(src.getHeight(), result.getHeight());
}
+ @Presubmit
public void testGetContentUri() {
Cursor c = null;
assertNotNull(c = mContentResolver.query(Media.getContentUri("internal"), null, null, null,
diff --git a/tests/tests/rsblas/AndroidTest.xml b/tests/tests/rsblas/AndroidTest.xml
index 19e6acc..340ca29 100644
--- a/tests/tests/rsblas/AndroidTest.xml
+++ b/tests/tests/rsblas/AndroidTest.xml
@@ -20,5 +20,6 @@
</target_preparer>
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="com.android.cts.rsblas" />
+ <option name="runtime-hint" value="12m57s" />
</test>
-</configuration>
\ No newline at end of file
+</configuration>
diff --git a/tests/tests/security/jni/android_security_cts_AudioEffectBinderTest.cpp b/tests/tests/security/jni/android_security_cts_AudioEffectBinderTest.cpp
index 4c27416..6e94fce 100644
--- a/tests/tests/security/jni/android_security_cts_AudioEffectBinderTest.cpp
+++ b/tests/tests/security/jni/android_security_cts_AudioEffectBinderTest.cpp
@@ -119,7 +119,7 @@
descriptor.type = EFFECT_UIID_EQUALIZER;
descriptor.uuid = *EFFECT_UUID_NULL;
const int32_t priority = 0;
- const int sessionId = AUDIO_SESSION_OUTPUT_MIX;
+ const audio_session_t sessionId = AUDIO_SESSION_OUTPUT_MIX;
const audio_io_handle_t io = AUDIO_IO_HANDLE_NONE;
const String16 opPackageName("Exploitable");
status_t status;
diff --git a/tests/tests/security/src/android/security/cts/MediaServerCrashTest.java b/tests/tests/security/src/android/security/cts/MediaServerCrashTest.java
index 5298196..147a5cd 100644
--- a/tests/tests/security/src/android/security/cts/MediaServerCrashTest.java
+++ b/tests/tests/security/src/android/security/cts/MediaServerCrashTest.java
@@ -121,7 +121,9 @@
private void checkIfMediaServerDiedForDrm(int res) throws Exception {
if (!convertDmToFl(res, mFlFilePath)) {
- fail("Can not convert dm to fl");
+ Log.w(TAG, "Can not convert dm to fl, skip checkIfMediaServerDiedForDrm");
+ mMediaPlayer.release();
+ return;
}
Log.d(TAG, "intermediate fl file is " + mFlFilePath);
diff --git a/tests/tests/systemui/AndroidTest.xml b/tests/tests/systemui/AndroidTest.xml
index d98dae6..61bdae3 100644
--- a/tests/tests/systemui/AndroidTest.xml
+++ b/tests/tests/systemui/AndroidTest.xml
@@ -20,5 +20,6 @@
</target_preparer>
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.systemui.cts" />
+ <option name="runtime-hint" value="10m19s" />
</test>
-</configuration>
\ No newline at end of file
+</configuration>
diff --git a/tests/tests/telecom/AndroidTest.xml b/tests/tests/telecom/AndroidTest.xml
index 03f64b3..7f34c0c 100644
--- a/tests/tests/telecom/AndroidTest.xml
+++ b/tests/tests/telecom/AndroidTest.xml
@@ -23,5 +23,6 @@
</target_preparer>
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.telecom.cts" />
+ <option name="runtime-hint" value="10m20s" />
</test>
</configuration>
diff --git a/tests/tests/telephony/AndroidManifest.xml b/tests/tests/telephony/AndroidManifest.xml
index 6e9545a..e1905d1 100644
--- a/tests/tests/telephony/AndroidManifest.xml
+++ b/tests/tests/telephony/AndroidManifest.xml
@@ -34,6 +34,56 @@
<provider android:name="android.telephony.cts.MmsPduProvider"
android:authorities="telephonyctstest"
android:grantUriPermissions="true" />
+
+ <!-- SmsReceiver, MmsReceiver, ComposeSmsActivity, HeadlessSmsSendService together make
+ this a valid SmsApplication (that can be set as the default SMS app). Although some of these
+ classes don't do anything, they are needed to make this a valid candidate for default SMS
+ app. -->
+ <!-- BroadcastReceiver that listens for incoming SMS messages -->
+ <receiver android:name=".SmsReceiver"
+ android:permission="android.permission.BROADCAST_SMS">
+ <intent-filter>
+ <action android:name="android.provider.Telephony.SMS_DELIVER" />
+ </intent-filter>
+ </receiver>
+
+ <!-- BroadcastReceiver that listens for incoming MMS messages -->
+ <receiver android:name=".MmsReceiver"
+ android:permission="android.permission.BROADCAST_WAP_PUSH">
+ <intent-filter>
+ <action android:name="android.provider.Telephony.WAP_PUSH_DELIVER" />
+ <data android:mimeType="application/vnd.wap.mms-message" />
+ </intent-filter>
+ </receiver>
+
+ <!-- Activity that allows the user to send new SMS/MMS messages -->
+ <activity android:name=".ComposeSmsActivity" >
+ <intent-filter>
+ <action android:name="android.intent.action.SEND" />
+ <action android:name="android.intent.action.SENDTO" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.BROWSABLE" />
+ <data android:scheme="sms" />
+ <data android:scheme="smsto" />
+ <data android:scheme="mms" />
+ <data android:scheme="mmsto" />
+ </intent-filter>
+ </activity>
+
+ <!-- Service that delivers messages from the phone "quick response" -->
+ <service android:name=".HeadlessSmsSendService"
+ android:permission="android.permission.SEND_RESPOND_VIA_MESSAGE"
+ android:exported="true" >
+ <intent-filter>
+ <action android:name="android.intent.action.RESPOND_VIA_MESSAGE" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <data android:scheme="sms" />
+ <data android:scheme="smsto" />
+ <data android:scheme="mms" />
+ <data android:scheme="mmsto" />
+ </intent-filter>
+ </service>
+
<uses-library android:name="android.test.runner" />
</application>
diff --git a/tests/tests/telephony/src/android/telephony/cts/ComposeSmsActivity.java b/tests/tests/telephony/src/android/telephony/cts/ComposeSmsActivity.java
new file mode 100644
index 0000000..df1f0a9
--- /dev/null
+++ b/tests/tests/telephony/src/android/telephony/cts/ComposeSmsActivity.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2016 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 android.telephony.cts;
+
+import android.app.Activity;
+
+/**
+ * SmsReceiver, MmsReceiver, ComposeSmsActivity, HeadlessSmsSendService together make
+ * this a valid SmsApplication (that can be set as the default SMS app). Although some of these
+ * classes don't do anything, they are needed to make this a valid candidate for default SMS
+ * app. -->
+ */
+public class ComposeSmsActivity extends Activity {
+}
diff --git a/tests/tests/telephony/src/android/telephony/cts/HeadlessSmsSendService.java b/tests/tests/telephony/src/android/telephony/cts/HeadlessSmsSendService.java
new file mode 100644
index 0000000..f3fadb31
--- /dev/null
+++ b/tests/tests/telephony/src/android/telephony/cts/HeadlessSmsSendService.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2016 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 android.telephony.cts;
+
+import android.annotation.Nullable;
+import android.app.IntentService;
+import android.content.Intent;
+
+/**
+ * SmsReceiver, MmsReceiver, ComposeSmsActivity, HeadlessSmsSendService together make
+ * this a valid SmsApplication (that can be set as the default SMS app). Although some of these
+ * classes don't do anything, they are needed to make this a valid candidate for default SMS
+ * app. -->
+ */
+public class HeadlessSmsSendService extends IntentService {
+ /**
+ * Creates an IntentService. Invoked by your subclass's constructor.
+ *
+ * @param name Used to name the worker thread, important only for debugging.
+ */
+ public HeadlessSmsSendService(String name) {
+ super(name);
+ }
+
+ @Override
+ protected void onHandleIntent(@Nullable Intent intent) {
+
+ }
+}
diff --git a/tests/tests/telephony/src/android/telephony/cts/MmsReceiver.java b/tests/tests/telephony/src/android/telephony/cts/MmsReceiver.java
new file mode 100644
index 0000000..d7d4b86
--- /dev/null
+++ b/tests/tests/telephony/src/android/telephony/cts/MmsReceiver.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2016 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 android.telephony.cts;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+/**
+ * SmsReceiver, MmsReceiver, ComposeSmsActivity, HeadlessSmsSendService together make
+ * this a valid SmsApplication (that can be set as the default SMS app). Although some of these
+ * classes don't do anything, they are needed to make this a valid candidate for default SMS
+ * app. -->
+ */
+public class MmsReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ }
+}
diff --git a/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java b/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java
index 6b72b82a..db7a974 100755
--- a/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java
@@ -25,7 +25,7 @@
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.SystemClock;
-import android.telephony.SmsManager;
+import android.provider.Telephony;
import android.telephony.SmsMessage;
import android.telephony.TelephonyManager;
import android.test.AndroidTestCase;
@@ -57,6 +57,7 @@
private static final String SMS_SEND_ACTION = "CTS_SMS_SEND_ACTION";
private static final String SMS_DELIVERY_ACTION = "CTS_SMS_DELIVERY_ACTION";
private static final String DATA_SMS_RECEIVED_ACTION = "android.intent.action.DATA_SMS_RECEIVED";
+ public static final String SMS_DELIVER_DEFAULT_APP_ACTION = "CTS_SMS_DELIVERY_ACTION_DEFAULT_APP";
// List of network operators that don't support SMS delivery report
private static final List<String> NO_DELIVERY_REPORTS =
@@ -190,6 +191,8 @@
private SmsBroadcastReceiver mSendReceiver;
private SmsBroadcastReceiver mDeliveryReceiver;
private SmsBroadcastReceiver mDataSmsReceiver;
+ private SmsBroadcastReceiver mSmsDeliverReceiver;
+ private SmsBroadcastReceiver mSmsReceivedReceiver;
private PendingIntent mSentIntent;
private PendingIntent mDeliveredIntent;
private Intent mSendIntent;
@@ -254,7 +257,7 @@
return longText.equals(actualMessage);
}
- public void testSendMessages() throws InterruptedException {
+ public void testSendAndReceiveMessages() throws InterruptedException {
if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
return;
}
@@ -267,16 +270,23 @@
IntentFilter sendIntentFilter = new IntentFilter(SMS_SEND_ACTION);
IntentFilter deliveryIntentFilter = new IntentFilter(SMS_DELIVERY_ACTION);
IntentFilter dataSmsReceivedIntentFilter = new IntentFilter(DATA_SMS_RECEIVED_ACTION);
+ IntentFilter smsDeliverIntentFilter = new IntentFilter(SMS_DELIVER_DEFAULT_APP_ACTION);
+ IntentFilter smsReceivedIntentFilter =
+ new IntentFilter(Telephony.Sms.Intents.SMS_RECEIVED_ACTION);
dataSmsReceivedIntentFilter.addDataScheme("sms");
dataSmsReceivedIntentFilter.addDataAuthority("localhost", "19989");
mSendReceiver = new SmsBroadcastReceiver(SMS_SEND_ACTION);
mDeliveryReceiver = new SmsBroadcastReceiver(SMS_DELIVERY_ACTION);
mDataSmsReceiver = new SmsBroadcastReceiver(DATA_SMS_RECEIVED_ACTION);
+ mSmsDeliverReceiver = new SmsBroadcastReceiver(SMS_DELIVER_DEFAULT_APP_ACTION);
+ mSmsReceivedReceiver = new SmsBroadcastReceiver(Telephony.Sms.Intents.SMS_RECEIVED_ACTION);
getContext().registerReceiver(mSendReceiver, sendIntentFilter);
getContext().registerReceiver(mDeliveryReceiver, deliveryIntentFilter);
getContext().registerReceiver(mDataSmsReceiver, dataSmsReceivedIntentFilter);
+ getContext().registerReceiver(mSmsDeliverReceiver, smsDeliverIntentFilter);
+ getContext().registerReceiver(mSmsReceivedReceiver, smsReceivedIntentFilter);
// send single text sms
init();
@@ -285,6 +295,12 @@
if (mDeliveryReportSupported) {
assertTrue(mDeliveryReceiver.waitForCalls(1, TIME_OUT));
}
+ // non-default app should receive only SMS_RECEIVED_ACTION
+ assertTrue(mSmsReceivedReceiver.waitForCalls(1, TIME_OUT));
+ assertTrue(mSmsDeliverReceiver.waitForCalls(0, 0));
+
+ // due to permission restrictions, currently there is no way to make this test app the
+ // default SMS app
if (mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) {
// TODO: temp workaround, OCTET encoding for EMS not properly supported
@@ -326,6 +342,9 @@
if (mDeliveryReportSupported) {
assertTrue(mDeliveryReceiver.waitForCalls(numParts, TIME_OUT));
}
+ // non-default app should receive only SMS_RECEIVED_ACTION
+ assertTrue(mSmsReceivedReceiver.waitForCalls(1, TIME_OUT));
+ assertTrue(mSmsDeliverReceiver.waitForCalls(0, 0));
} else {
// This GSM network doesn't support Multipart SMS message.
// Skip the test.
@@ -336,6 +355,8 @@
mSendReceiver.reset();
mDeliveryReceiver.reset();
mDataSmsReceiver.reset();
+ mSmsDeliverReceiver.reset();
+ mSmsReceivedReceiver.reset();
mReceivedDataSms = false;
mSentIntent = PendingIntent.getBroadcast(getContext(), 0, mSendIntent,
PendingIntent.FLAG_ONE_SHOT);
diff --git a/tests/tests/telephony/src/android/telephony/cts/SmsReceiver.java b/tests/tests/telephony/src/android/telephony/cts/SmsReceiver.java
new file mode 100644
index 0000000..4fdadbb
--- /dev/null
+++ b/tests/tests/telephony/src/android/telephony/cts/SmsReceiver.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2016 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 android.telephony.cts;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.provider.Telephony;
+
+public class SmsReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent != null && intent.getAction().equals(Telephony.Sms.Intents.SMS_DELIVER_ACTION)) {
+ context.sendBroadcast(new Intent(SmsManagerTest.SMS_DELIVER_DEFAULT_APP_ACTION));
+ }
+ }
+}
diff --git a/tests/tests/text/src/android/text/method/cts/BackspaceTest.java b/tests/tests/text/src/android/text/method/cts/BackspaceTest.java
index 8900f9a..fa2e262 100644
--- a/tests/tests/text/src/android/text/method/cts/BackspaceTest.java
+++ b/tests/tests/text/src/android/text/method/cts/BackspaceTest.java
@@ -132,10 +132,6 @@
state.setByString("'1' U+FE0E U+20E3 |");
backspace(state, 0);
state.assertEquals("|");
-
- state.setByString("'1' U+E0101 U+20E3 |");
- backspace(state, 0);
- state.assertEquals("|");
}
@SmallTest
@@ -154,24 +150,6 @@
}
@SmallTest
- public void testEmojiZWJSequence() {
- EditorState state = new EditorState();
-
- // U+200D is ZERO WIDTH JOINER.
- state.setByString("U+1F441 U+200D U+1F5E8 |");
- backspace(state, 0);
- state.assertEquals("|");
-
- state.setByString("U+1F441 U+200D U+1F5E8 U+FE0E |");
- backspace(state, 0);
- state.assertEquals("|");
-
- state.setByString("U+1F468 U+200D U+2764 U+FE0F U+200D U+1F48B U+200D U+1F468 |");
- backspace(state, 0);
- state.assertEquals("|");
- }
-
- @SmallTest
public void testFlags() {
EditorState state = new EditorState();
@@ -203,14 +181,4 @@
backspace(state, 0);
state.assertEquals("|");
}
-
- @SmallTest
- public void testEmojiModifier() {
- EditorState state = new EditorState();
-
- // U+1F3FB is EMOJI MODIFIER FITZPATRICK TYPE-1-2.
- state.setByString("U+1F466 U+1F3FB |");
- backspace(state, 0);
- state.assertEquals("|");
- }
}
diff --git a/tests/tests/text/src/android/text/method/cts/ForwardDeleteTest.java b/tests/tests/text/src/android/text/method/cts/ForwardDeleteTest.java
index 7ba6285..47c2795 100644
--- a/tests/tests/text/src/android/text/method/cts/ForwardDeleteTest.java
+++ b/tests/tests/text/src/android/text/method/cts/ForwardDeleteTest.java
@@ -124,6 +124,10 @@
state.setByString("| '1' U+20E3");
forwardDelete(state, 0);
state.assertEquals("|");
+
+ state.setByString("| '1' U+FE0F U+20E3");
+ forwardDelete(state, 0);
+ state.assertEquals("|");
}
@SmallTest
@@ -142,20 +146,6 @@
}
@SmallTest
- public void testEmojiZeroWidthJoinerSequence() {
- EditorState state = new EditorState();
-
- // U+200D is ZERO WIDTH JOINER.
- state.setByString("| U+1F441 U+200D U+1F5E8");
- forwardDelete(state, 0);
- state.assertEquals("|");
-
- state.setByString("| U+1F468 U+200D U+2764 U+FE0F U+200D U+1F48B U+200D U+1F468");
- forwardDelete(state, 0);
- state.assertEquals("|");
- }
-
- @SmallTest
public void testFlags() {
EditorState state = new EditorState();
@@ -171,14 +161,4 @@
forwardDelete(state, 0);
state.assertEquals("|");
}
-
- @SmallTest
- public void testEmojiModifier() {
- EditorState state = new EditorState();
-
- // U+1F3FB is EMOJI MODIFIER FITZPATRICK TYPE-1-2.
- state.setByString("| U+1F466 U+1F3FB");
- forwardDelete(state, 0);
- state.assertEquals("|");
- }
}
diff --git a/tests/tests/text/src/android/text/style/cts/AbsoluteSizeSpanTest.java b/tests/tests/text/src/android/text/style/cts/AbsoluteSizeSpanTest.java
index bdd3d17..e825bd1 100644
--- a/tests/tests/text/src/android/text/style/cts/AbsoluteSizeSpanTest.java
+++ b/tests/tests/text/src/android/text/style/cts/AbsoluteSizeSpanTest.java
@@ -47,6 +47,14 @@
assertEquals(-5, absoluteSizeSpan.getSize());
}
+ public void testGetDip() {
+ AbsoluteSizeSpan absoluteSizeSpan = new AbsoluteSizeSpan(5);
+ assertEquals(false, absoluteSizeSpan.getDip());
+
+ absoluteSizeSpan = new AbsoluteSizeSpan(5, true);
+ assertEquals(true, absoluteSizeSpan.getDip());
+ }
+
public void testUpdateMeasureState() {
AbsoluteSizeSpan absoluteSizeSpan = new AbsoluteSizeSpan(1);
diff --git a/tests/tests/text/src/android/text/style/cts/EasyEditSpanTest.java b/tests/tests/text/src/android/text/style/cts/EasyEditSpanTest.java
new file mode 100644
index 0000000..7405107
--- /dev/null
+++ b/tests/tests/text/src/android/text/style/cts/EasyEditSpanTest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2016 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 android.text.style.cts;
+
+import android.app.PendingIntent;
+import android.content.Intent;
+import android.os.Parcel;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.text.style.EasyEditSpan;
+
+public class EasyEditSpanTest extends AndroidTestCase {
+ @SmallTest
+ public void testConstructor() {
+ new EasyEditSpan();
+ new EasyEditSpan(PendingIntent.getActivity(getContext(), 0, new Intent(), 0));
+ Parcel p = Parcel.obtain();
+ try {
+ new EasyEditSpan(p);
+ } finally {
+ p.recycle();
+ }
+ }
+
+ @SmallTest
+ public void testDescribeContents_doesNotThrowException() {
+ EasyEditSpan easyEditSpan = new EasyEditSpan();
+ easyEditSpan.describeContents();
+ }
+
+ @SmallTest
+ public void testGetSpanTypeId_doesNotThrowException() {
+ EasyEditSpan easyEditSpan = new EasyEditSpan();
+ easyEditSpan.getSpanTypeId();
+ }
+
+ @SmallTest
+ public void testWriteToParcel() {
+ Parcel p = Parcel.obtain();
+ try {
+ EasyEditSpan easyEditSpan = new EasyEditSpan();
+ easyEditSpan.writeToParcel(p, 0);
+ p.setDataPosition(0);
+ new EasyEditSpan(p);
+ } finally {
+ p.recycle();
+ }
+ }
+}
diff --git a/tests/tests/text/src/android/text/style/cts/LocaleSpanTest.java b/tests/tests/text/src/android/text/style/cts/LocaleSpanTest.java
index bc93e41..f44cca5 100644
--- a/tests/tests/text/src/android/text/style/cts/LocaleSpanTest.java
+++ b/tests/tests/text/src/android/text/style/cts/LocaleSpanTest.java
@@ -17,9 +17,10 @@
package android.text.style.cts;
import junit.framework.TestCase;
-
import android.annotation.NonNull;
import android.os.Parcel;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.text.TextPaint;
import android.text.style.LocaleSpan;
import android.util.LocaleList;
@@ -35,6 +36,7 @@
assertEquals(locales, cloned.getLocales());
}
+ @SmallTest
public void testGetLocales() {
checkGetLocales(LocaleList.getEmptyLocaleList());
checkGetLocales(LocaleList.forLanguageTags("en"));
@@ -42,6 +44,7 @@
checkGetLocales(LocaleList.forLanguageTags("de-DE-u-co-phonebk,en-GB,en"));
}
+ @SmallTest
public void testConstructorWithLocaleList() {
try {
new LocaleSpan((LocaleList) null);
@@ -66,4 +69,48 @@
}
}
}
+
+ @SmallTest
+ public void testDescribeContents_doesNotThrowException() {
+ LocaleSpan localeSpan = new LocaleSpan(LocaleList.getEmptyLocaleList());
+ localeSpan.describeContents();
+ }
+
+ @SmallTest
+ public void testGetSpanTypeId_doesNotThrowException() {
+ LocaleSpan localeSpan = new LocaleSpan(LocaleList.getEmptyLocaleList());
+ localeSpan.getSpanTypeId();
+ }
+
+ @SmallTest
+ public void testUpdateDrawState() {
+ LocaleList localeListForSpan = LocaleList.forLanguageTags("en");
+ LocaleSpan localeSpan = new LocaleSpan(localeListForSpan);
+
+ TextPaint tp = new TextPaint();
+ LocaleList localeList = LocaleList.forLanguageTags("fr,de");
+ tp.setTextLocales(localeList);
+ assertEquals(localeList, tp.getTextLocales());
+ assertEquals(localeList.get(0), tp.getTextLocale());
+
+ localeSpan.updateDrawState(tp);
+ assertEquals(localeListForSpan, tp.getTextLocales());
+ assertEquals(localeListForSpan.get(0), tp.getTextLocale());
+ }
+
+ @SmallTest
+ public void testUpdateMeasureState() {
+ LocaleList localeListForSpan = LocaleList.forLanguageTags("en");
+ LocaleSpan localeSpan = new LocaleSpan(localeListForSpan);
+
+ TextPaint tp = new TextPaint();
+ LocaleList localeList = LocaleList.forLanguageTags("fr,de");
+ tp.setTextLocales(localeList);
+ assertEquals(localeList, tp.getTextLocales());
+ assertEquals(localeList.get(0), tp.getTextLocale());
+
+ localeSpan.updateMeasureState(tp);
+ assertEquals(localeListForSpan, tp.getTextLocales());
+ assertEquals(localeListForSpan.get(0), tp.getTextLocale());
+ }
}
diff --git a/tests/tests/text/src/android/text/style/cts/TtsSpanTest.java b/tests/tests/text/src/android/text/style/cts/TtsSpanTest.java
index 3c320f1..c718a37 100644
--- a/tests/tests/text/src/android/text/style/cts/TtsSpanTest.java
+++ b/tests/tests/text/src/android/text/style/cts/TtsSpanTest.java
@@ -18,6 +18,7 @@
import android.os.Parcel;
import android.os.PersistableBundle;
+import android.test.suitebuilder.annotation.SmallTest;
import android.text.style.TtsSpan;
import junit.framework.TestCase;
@@ -25,6 +26,7 @@
PersistableBundle bundle;
+ @Override
protected void setUp() {
bundle = new PersistableBundle();
bundle.putString("argument.one", "value.one");
@@ -33,6 +35,7 @@
bundle.putLong("argument.four", 4);
}
+ @SmallTest
public void testGetArgs() {
TtsSpan t = new TtsSpan("test.type.one", bundle);
PersistableBundle args = t.getArgs();
@@ -43,21 +46,25 @@
assertEquals(4, args.getLong("argument.four"));
}
+ @SmallTest
public void testGetType() {
TtsSpan t = new TtsSpan("test.type.two", bundle);
assertEquals("test.type.two", t.getType());
}
+ @SmallTest
public void testDescribeContents() {
TtsSpan span = new TtsSpan("test.type.three", bundle);
span.describeContents();
}
+ @SmallTest
public void testGetSpanTypeId() {
TtsSpan span = new TtsSpan("test.type.four", bundle);
span.getSpanTypeId();
}
+ @SmallTest
public void testWriteAndReadParcel() {
Parcel p = Parcel.obtain();
try {
@@ -78,4 +85,423 @@
p.recycle();
}
}
+
+ @SmallTest
+ public void testBuilder() {
+ final TtsSpan t = (new TtsSpan.Builder<>("test.type.builder"))
+ .setStringArgument("argument.string", "value")
+ .setIntArgument("argument.int", Integer.MAX_VALUE)
+ .setLongArgument("argument.long", Long.MAX_VALUE)
+ .build();
+ assertEquals("test.type.builder", t.getType());
+ PersistableBundle args = t.getArgs();
+ assertEquals(3, args.size());
+ assertEquals("value", args.getString("argument.string"));
+ assertEquals(Integer.MAX_VALUE, args.getInt("argument.int"));
+ assertEquals(Long.MAX_VALUE, args.getLong("argument.long"));
+ }
+
+ @SmallTest
+ public void testSemioticClassBuilder() {
+ final TtsSpan t = (new TtsSpan.SemioticClassBuilder<>("test.type.semioticClassBuilder"))
+ .setGender(TtsSpan.GENDER_FEMALE)
+ .setAnimacy(TtsSpan.ANIMACY_ANIMATE)
+ .setMultiplicity(TtsSpan.MULTIPLICITY_SINGLE)
+ .setCase(TtsSpan.CASE_NOMINATIVE)
+ .build();
+ assertEquals("test.type.semioticClassBuilder", t.getType());
+ PersistableBundle args = t.getArgs();
+ assertEquals(4, args.size());
+ assertEquals(TtsSpan.GENDER_FEMALE, args.getString(TtsSpan.ARG_GENDER));
+ assertEquals(TtsSpan.ANIMACY_ANIMATE, args.getString(TtsSpan.ARG_ANIMACY));
+ assertEquals(TtsSpan.MULTIPLICITY_SINGLE, args.getString(TtsSpan.ARG_MULTIPLICITY));
+ assertEquals(TtsSpan.CASE_NOMINATIVE, args.getString(TtsSpan.ARG_CASE));
+ }
+
+ @SmallTest
+ public void testTextBuilder() {
+ {
+ final TtsSpan t = (new TtsSpan.TextBuilder())
+ .setText("text")
+ .build();
+ assertEquals(TtsSpan.TYPE_TEXT, t.getType());
+ PersistableBundle args = t.getArgs();
+ assertEquals(1, args.size());
+ assertEquals("text", args.getString(TtsSpan.ARG_TEXT));
+ }
+ {
+ final TtsSpan t = (new TtsSpan.TextBuilder("text")).build();
+ assertEquals(TtsSpan.TYPE_TEXT, t.getType());
+ PersistableBundle args = t.getArgs();
+ assertEquals(1, args.size());
+ assertEquals("text", args.getString(TtsSpan.ARG_TEXT));
+ }
+ }
+
+ @SmallTest
+ public void testCardinalBuilder() {
+ {
+ final TtsSpan t = (new TtsSpan.CardinalBuilder())
+ .setNumber(Long.MAX_VALUE)
+ .build();
+ assertEquals(TtsSpan.TYPE_CARDINAL, t.getType());
+ PersistableBundle args = t.getArgs();
+ assertEquals(1, args.size());
+ assertEquals(String.valueOf(Long.MAX_VALUE), args.getString(TtsSpan.ARG_NUMBER));
+ }
+ {
+ final TtsSpan t = (new TtsSpan.CardinalBuilder())
+ .setNumber("10")
+ .build();
+ assertEquals(TtsSpan.TYPE_CARDINAL, t.getType());
+ PersistableBundle args = t.getArgs();
+ assertEquals(1, args.size());
+ assertEquals("10", args.getString(TtsSpan.ARG_NUMBER));
+ }
+ {
+ final TtsSpan t = (new TtsSpan.CardinalBuilder(Long.MAX_VALUE)).build();
+ assertEquals(TtsSpan.TYPE_CARDINAL, t.getType());
+ PersistableBundle args = t.getArgs();
+ assertEquals(1, args.size());
+ assertEquals(String.valueOf(Long.MAX_VALUE), args.getString(TtsSpan.ARG_NUMBER));
+ }
+ {
+ final TtsSpan t = (new TtsSpan.CardinalBuilder("10")).build();
+ assertEquals(TtsSpan.TYPE_CARDINAL, t.getType());
+ PersistableBundle args = t.getArgs();
+ assertEquals(1, args.size());
+ assertEquals("10", args.getString(TtsSpan.ARG_NUMBER));
+ }
+ }
+
+ @SmallTest
+ public void testOrdinalBuilder() {
+ {
+ final TtsSpan t = (new TtsSpan.OrdinalBuilder())
+ .setNumber(Long.MAX_VALUE)
+ .build();
+ assertEquals(TtsSpan.TYPE_ORDINAL, t.getType());
+ PersistableBundle args = t.getArgs();
+ assertEquals(1, args.size());
+ assertEquals(String.valueOf(Long.MAX_VALUE), args.getString(TtsSpan.ARG_NUMBER));
+ }
+ {
+ final TtsSpan t = (new TtsSpan.OrdinalBuilder())
+ .setNumber("10")
+ .build();
+ assertEquals(TtsSpan.TYPE_ORDINAL, t.getType());
+ PersistableBundle args = t.getArgs();
+ assertEquals(1, args.size());
+ assertEquals("10", args.getString(TtsSpan.ARG_NUMBER));
+ }
+ {
+ final TtsSpan t = (new TtsSpan.OrdinalBuilder(Long.MAX_VALUE)).build();
+ assertEquals(TtsSpan.TYPE_ORDINAL, t.getType());
+ PersistableBundle args = t.getArgs();
+ assertEquals(1, args.size());
+ assertEquals(String.valueOf(Long.MAX_VALUE), args.getString(TtsSpan.ARG_NUMBER));
+ }
+ {
+ final TtsSpan t = (new TtsSpan.OrdinalBuilder("10")).build();
+ assertEquals(TtsSpan.TYPE_ORDINAL, t.getType());
+ PersistableBundle args = t.getArgs();
+ assertEquals(1, args.size());
+ assertEquals("10", args.getString(TtsSpan.ARG_NUMBER));
+ }
+ }
+
+ @SmallTest
+ public void testDecimalBuilder() {
+ {
+ final TtsSpan t = (new TtsSpan.DecimalBuilder())
+ .setArgumentsFromDouble(10.25, 1, 2)
+ .build();
+ assertEquals(TtsSpan.TYPE_DECIMAL, t.getType());
+ PersistableBundle args = t.getArgs();
+ assertEquals(2, args.size());
+ assertEquals("10", args.getString(TtsSpan.ARG_INTEGER_PART));
+ assertEquals("25", args.getString(TtsSpan.ARG_FRACTIONAL_PART));
+ }
+ {
+ final TtsSpan t = (new TtsSpan.DecimalBuilder(10.25, 1, 2)).build();
+ assertEquals(TtsSpan.TYPE_DECIMAL, t.getType());
+ PersistableBundle args = t.getArgs();
+ assertEquals(2, args.size());
+ assertEquals("10", args.getString(TtsSpan.ARG_INTEGER_PART));
+ assertEquals("25", args.getString(TtsSpan.ARG_FRACTIONAL_PART));
+ }
+ {
+ final TtsSpan t = (new TtsSpan.DecimalBuilder())
+ .setArgumentsFromDouble(10, 0, 0)
+ .build();
+ assertEquals(TtsSpan.TYPE_DECIMAL, t.getType());
+ PersistableBundle args = t.getArgs();
+ assertEquals(1, args.size());
+ assertEquals("10", args.getString(TtsSpan.ARG_INTEGER_PART));
+ }
+ {
+ final TtsSpan t = (new TtsSpan.DecimalBuilder(10, 0, 0)).build();
+ assertEquals(TtsSpan.TYPE_DECIMAL, t.getType());
+ PersistableBundle args = t.getArgs();
+ assertEquals(1, args.size());
+ assertEquals("10", args.getString(TtsSpan.ARG_INTEGER_PART));
+ }
+ {
+ final TtsSpan t = (new TtsSpan.DecimalBuilder())
+ .setArgumentsFromDouble(10.25, 10, 10)
+ .build();
+ assertEquals(TtsSpan.TYPE_DECIMAL, t.getType());
+ PersistableBundle args = t.getArgs();
+ assertEquals(2, args.size());
+ assertEquals("10", args.getString(TtsSpan.ARG_INTEGER_PART));
+ assertEquals("2500000000", args.getString(TtsSpan.ARG_FRACTIONAL_PART));
+ }
+ }
+
+ @SmallTest
+ public void testFractionBuilder() {
+ {
+ final TtsSpan t = (new TtsSpan.FractionBuilder())
+ .setIntegerPart(10)
+ .setNumerator(3)
+ .setDenominator(100)
+ .build();
+ assertEquals(TtsSpan.TYPE_FRACTION, t.getType());
+ PersistableBundle args = t.getArgs();
+ assertEquals(3, args.size());
+ assertEquals("10", args.getString(TtsSpan.ARG_INTEGER_PART));
+ assertEquals("3", args.getString(TtsSpan.ARG_NUMERATOR));
+ assertEquals("100", args.getString(TtsSpan.ARG_DENOMINATOR));
+ }
+ {
+ final TtsSpan t = (new TtsSpan.FractionBuilder(10, 3, 100)).build();
+ assertEquals(TtsSpan.TYPE_FRACTION, t.getType());
+ PersistableBundle args = t.getArgs();
+ assertEquals(3, args.size());
+ assertEquals("10", args.getString(TtsSpan.ARG_INTEGER_PART));
+ assertEquals("3", args.getString(TtsSpan.ARG_NUMERATOR));
+ assertEquals("100", args.getString(TtsSpan.ARG_DENOMINATOR));
+ }
+ }
+
+ @SmallTest
+ public void testMeasureBuilder() {
+ {
+ final TtsSpan t = (new TtsSpan.MeasureBuilder())
+ .setNumber(10)
+ .setUnit("unit")
+ .build();
+ assertEquals(TtsSpan.TYPE_MEASURE, t.getType());
+ PersistableBundle args = t.getArgs();
+ assertEquals(2, args.size());
+ assertEquals("10", args.getString(TtsSpan.ARG_NUMBER));
+ assertEquals("unit", args.getString(TtsSpan.ARG_UNIT));
+ }
+ {
+ final TtsSpan t = (new TtsSpan.MeasureBuilder())
+ .setIntegerPart(10)
+ .setFractionalPart("25")
+ .setUnit("unit")
+ .build();
+ assertEquals(TtsSpan.TYPE_MEASURE, t.getType());
+ PersistableBundle args = t.getArgs();
+ assertEquals(3, args.size());
+ assertEquals("10", args.getString(TtsSpan.ARG_INTEGER_PART));
+ assertEquals("25", args.getString(TtsSpan.ARG_FRACTIONAL_PART));
+ assertEquals("unit", args.getString(TtsSpan.ARG_UNIT));
+ }
+ {
+ final TtsSpan t = (new TtsSpan.MeasureBuilder())
+ .setIntegerPart(10)
+ .setNumerator(3)
+ .setDenominator(100)
+ .setUnit("unit")
+ .build();
+ assertEquals(TtsSpan.TYPE_MEASURE, t.getType());
+ PersistableBundle args = t.getArgs();
+ assertEquals(4, args.size());
+ assertEquals("10", args.getString(TtsSpan.ARG_INTEGER_PART));
+ assertEquals("3", args.getString(TtsSpan.ARG_NUMERATOR));
+ assertEquals("100", args.getString(TtsSpan.ARG_DENOMINATOR));
+ assertEquals("unit", args.getString(TtsSpan.ARG_UNIT));
+ }
+ }
+
+ @SmallTest
+ public void testTimeBuilder() {
+ {
+ final TtsSpan t = (new TtsSpan.TimeBuilder())
+ .setHours(20)
+ .setMinutes(50)
+ .build();
+ assertEquals(TtsSpan.TYPE_TIME, t.getType());
+ PersistableBundle args = t.getArgs();
+ assertEquals(2, args.size());
+ assertEquals(20, args.getInt(TtsSpan.ARG_HOURS));
+ assertEquals(50, args.getInt(TtsSpan.ARG_MINUTES));
+ }
+ {
+ final TtsSpan t = (new TtsSpan.TimeBuilder(20, 50)).build();
+ assertEquals(TtsSpan.TYPE_TIME, t.getType());
+ PersistableBundle args = t.getArgs();
+ assertEquals(2, args.size());
+ assertEquals(20, args.getInt(TtsSpan.ARG_HOURS));
+ assertEquals(50, args.getInt(TtsSpan.ARG_MINUTES));
+ }
+ }
+
+ @SmallTest
+ public void testDateBuilder() {
+ {
+ final TtsSpan t = (new TtsSpan.DateBuilder())
+ .setWeekday(3)
+ .setDay(16)
+ .setMonth(3)
+ .setYear(2016)
+ .build();
+ assertEquals(TtsSpan.TYPE_DATE, t.getType());
+ PersistableBundle args = t.getArgs();
+ assertEquals(4, args.size());
+ assertEquals(3, args.getInt(TtsSpan.ARG_WEEKDAY));
+ assertEquals(16, args.getInt(TtsSpan.ARG_DAY));
+ assertEquals(3, args.getInt(TtsSpan.ARG_MONTH));
+ assertEquals(2016, args.getInt(TtsSpan.ARG_YEAR));
+ }
+ {
+ final TtsSpan t = (new TtsSpan.DateBuilder(3, 16, 3, 2016)).build();
+ assertEquals(TtsSpan.TYPE_DATE, t.getType());
+ PersistableBundle args = t.getArgs();
+ assertEquals(4, args.size());
+ assertEquals(3, args.getInt(TtsSpan.ARG_WEEKDAY));
+ assertEquals(16, args.getInt(TtsSpan.ARG_DAY));
+ assertEquals(3, args.getInt(TtsSpan.ARG_MONTH));
+ assertEquals(2016, args.getInt(TtsSpan.ARG_YEAR));
+ }
+ {
+ final TtsSpan t = (new TtsSpan.DateBuilder(3, 16, null, null)).build();
+ assertEquals(TtsSpan.TYPE_DATE, t.getType());
+ PersistableBundle args = t.getArgs();
+ assertEquals(2, args.size());
+ assertEquals(3, args.getInt(TtsSpan.ARG_WEEKDAY));
+ assertEquals(16, args.getInt(TtsSpan.ARG_DAY));
+ }
+ }
+
+ @SmallTest
+ public void testMoneyBuilder() {
+ final TtsSpan t = (new TtsSpan.MoneyBuilder())
+ .setIntegerPart(10)
+ .setFractionalPart("25")
+ .setCurrency("USD")
+ .setQuantity("1000")
+ .build();
+ assertEquals(TtsSpan.TYPE_MONEY, t.getType());
+ PersistableBundle args = t.getArgs();
+ assertEquals(4, args.size());
+ assertEquals("10", args.getString(TtsSpan.ARG_INTEGER_PART));
+ assertEquals("25", args.getString(TtsSpan.ARG_FRACTIONAL_PART));
+ assertEquals("USD", args.getString(TtsSpan.ARG_CURRENCY));
+ assertEquals("1000", args.getString(TtsSpan.ARG_QUANTITY));
+ }
+
+ @SmallTest
+ public void testTelephoneBuilder() {
+ {
+ final TtsSpan t = (new TtsSpan.TelephoneBuilder())
+ .setCountryCode("+01")
+ .setNumberParts("000-000-0000")
+ .setExtension("0000")
+ .build();
+ assertEquals(TtsSpan.TYPE_TELEPHONE, t.getType());
+ PersistableBundle args = t.getArgs();
+ assertEquals(3, args.size());
+ assertEquals("+01", args.getString(TtsSpan.ARG_COUNTRY_CODE));
+ assertEquals("000-000-0000", args.getString(TtsSpan.ARG_NUMBER_PARTS));
+ assertEquals("0000", args.getString(TtsSpan.ARG_EXTENSION));
+ }
+ {
+ final TtsSpan t = (new TtsSpan.TelephoneBuilder("000-000-0000")).build();
+ assertEquals(TtsSpan.TYPE_TELEPHONE, t.getType());
+ PersistableBundle args = t.getArgs();
+ assertEquals(1, args.size());
+ assertEquals("000-000-0000", args.getString(TtsSpan.ARG_NUMBER_PARTS));
+ }
+ }
+
+ @SmallTest
+ public void testElectronicBuilder() {
+ {
+ final TtsSpan t = (new TtsSpan.ElectronicBuilder())
+ .setEmailArguments("example", "example.com")
+ .build();
+ assertEquals(TtsSpan.TYPE_ELECTRONIC, t.getType());
+ PersistableBundle args = t.getArgs();
+ assertEquals(2, args.size());
+ assertEquals("example", args.getString(TtsSpan.ARG_USERNAME));
+ assertEquals("example.com", args.getString(TtsSpan.ARG_DOMAIN));
+ }
+ {
+ final TtsSpan t = (new TtsSpan.ElectronicBuilder())
+ .setProtocol("http")
+ .setDomain("example.com")
+ .setPort(80)
+ .setPath("example/index.html")
+ .setQueryString("arg1=value1&arg2=value2")
+ .setFragmentId("fragment")
+ .setUsername("username")
+ .setPassword("password")
+ .build();
+ assertEquals(TtsSpan.TYPE_ELECTRONIC, t.getType());
+ PersistableBundle args = t.getArgs();
+ assertEquals(8, args.size());
+ assertEquals("http", args.getString(TtsSpan.ARG_PROTOCOL));
+ assertEquals("example.com", args.getString(TtsSpan.ARG_DOMAIN));
+ assertEquals(80, args.getInt(TtsSpan.ARG_PORT));
+ assertEquals("example/index.html", args.getString(TtsSpan.ARG_PATH));
+ assertEquals("arg1=value1&arg2=value2", args.getString(TtsSpan.ARG_QUERY_STRING));
+ assertEquals("fragment", args.getString(TtsSpan.ARG_FRAGMENT_ID));
+ assertEquals("username", args.getString(TtsSpan.ARG_USERNAME));
+ assertEquals("password", args.getString(TtsSpan.ARG_PASSWORD));
+ }
+ }
+
+ @SmallTest
+ public void testDigitsBuilder() {
+ {
+ final TtsSpan t = (new TtsSpan.DigitsBuilder())
+ .setDigits("12345")
+ .build();
+ assertEquals(TtsSpan.TYPE_DIGITS, t.getType());
+ PersistableBundle args = t.getArgs();
+ assertEquals(1, args.size());
+ assertEquals("12345", args.getString(TtsSpan.ARG_DIGITS));
+ }
+ {
+ final TtsSpan t = (new TtsSpan.DigitsBuilder("12345")).build();
+ assertEquals(TtsSpan.TYPE_DIGITS, t.getType());
+ PersistableBundle args = t.getArgs();
+ assertEquals(1, args.size());
+ assertEquals("12345", args.getString(TtsSpan.ARG_DIGITS));
+ }
+ }
+
+ @SmallTest
+ public void testVerbatimBuilder() {
+ {
+ final TtsSpan t = (new TtsSpan.VerbatimBuilder())
+ .setVerbatim("abcdefg")
+ .build();
+ assertEquals(TtsSpan.TYPE_VERBATIM, t.getType());
+ PersistableBundle args = t.getArgs();
+ assertEquals(1, args.size());
+ assertEquals("abcdefg", args.getString(TtsSpan.ARG_VERBATIM));
+ }
+ {
+ final TtsSpan t = (new TtsSpan.VerbatimBuilder("abcdefg")).build();
+ assertEquals(TtsSpan.TYPE_VERBATIM, t.getType());
+ PersistableBundle args = t.getArgs();
+ assertEquals(1, args.size());
+ assertEquals("abcdefg", args.getString(TtsSpan.ARG_VERBATIM));
+ }
+ }
}
diff --git a/tests/tests/theme/Android.mk b/tests/tests/theme/Android.mk
index 0f370d0..8b69a09 100644
--- a/tests/tests/theme/Android.mk
+++ b/tests/tests/theme/Android.mk
@@ -24,7 +24,8 @@
# When built, explicitly put it in the data partition.
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ ctstestrunner platform-test-annotations
LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/tests/tests/theme/src/android/theme/cts/DeviceDefaultTest.java b/tests/tests/theme/src/android/theme/cts/DeviceDefaultTest.java
index 77de0b4..fdac2d1 100644
--- a/tests/tests/theme/src/android/theme/cts/DeviceDefaultTest.java
+++ b/tests/tests/theme/src/android/theme/cts/DeviceDefaultTest.java
@@ -21,6 +21,7 @@
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
+import android.platform.test.annotations.Presubmit;
import android.test.ActivityInstrumentationTestCase2;
public class DeviceDefaultTest extends ActivityInstrumentationTestCase2<DeviceDefaultActivity> {
@@ -57,6 +58,7 @@
assertNoActionBar(android.R.style.Theme_DeviceDefault_DialogWhenLarge_NoActionBar);
}
+ @Presubmit
public void testGetActionBar_DeviceDefault_InputMethod() {
assertNoActionBar(android.R.style.Theme_DeviceDefault_InputMethod);
}
diff --git a/tests/tests/uiautomation/AndroidTest.xml b/tests/tests/uiautomation/AndroidTest.xml
index cf15c6b..c4f1665 100644
--- a/tests/tests/uiautomation/AndroidTest.xml
+++ b/tests/tests/uiautomation/AndroidTest.xml
@@ -20,5 +20,6 @@
</target_preparer>
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.app.uiautomation.cts" />
+ <option name="runtime-hint" value="6m42s" />
</test>
</configuration>
diff --git a/tests/tests/uirendering/AndroidTest.xml b/tests/tests/uirendering/AndroidTest.xml
index 30c99db..c89300b 100644
--- a/tests/tests/uirendering/AndroidTest.xml
+++ b/tests/tests/uirendering/AndroidTest.xml
@@ -20,6 +20,6 @@
</target_preparer>
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.uirendering.cts" />
- <option name="runtime-hint" value="3m" />
+ <option name="runtime-hint" value="11m55s" />
</test>
</configuration>
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/BitmapFilterTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/BitmapFilterTests.java
index b324b06..d0820e2 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/BitmapFilterTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/BitmapFilterTests.java
@@ -20,13 +20,15 @@
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.MediumTest;
import android.uirendering.cts.bitmapverifiers.BitmapVerifier;
import android.uirendering.cts.bitmapverifiers.ColorVerifier;
import android.uirendering.cts.bitmapverifiers.PerPixelBitmapVerifier;
import android.uirendering.cts.testinfrastructure.ActivityTestBase;
import android.uirendering.cts.testinfrastructure.CanvasClient;
+import org.junit.Test;
+@MediumTest
public class BitmapFilterTests extends ActivityTestBase {
private static final int WHITE_WEIGHT = 255 * 3;
private enum FilterEnum {
@@ -75,32 +77,32 @@
private static final int BIG_GRID_SIZE = TEST_WIDTH * 2;
private Bitmap mBigGridBitmap = createGridBitmap(BIG_GRID_SIZE, BIG_GRID_SIZE);
- @SmallTest
+ @Test
public void testPaintFilterScaleUp() {
runScaleTest(FilterEnum.PAINT_FILTER, true);
}
- @SmallTest
+ @Test
public void testPaintFilterScaleDown() {
runScaleTest(FilterEnum.PAINT_FILTER, false);
}
- @SmallTest
+ @Test
public void testDrawFilterRemoveFilterScaleUp() {
runScaleTest(FilterEnum.REMOVE_FILTER, true);
}
- @SmallTest
+ @Test
public void testDrawFilterRemoveFilterScaleDown() {
runScaleTest(FilterEnum.REMOVE_FILTER, false);
}
- @SmallTest
+ @Test
public void testDrawFilterScaleUp() {
runScaleTest(FilterEnum.ADD_FILTER, true);
}
- @SmallTest
+ @Test
public void testDrawFilterScaleDown() {
runScaleTest(FilterEnum.ADD_FILTER, false);
}
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/CanvasStateTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/CanvasStateTests.java
index 0e5fb0f..38d884d 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/CanvasStateTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/CanvasStateTests.java
@@ -20,9 +20,10 @@
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.Region;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.MediumTest;
import android.uirendering.cts.testinfrastructure.ActivityTestBase;
import android.uirendering.cts.testinfrastructure.CanvasClient;
+import org.junit.Test;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -33,9 +34,9 @@
* Although these tests don't verify drawing content, they still make use of ActivityTestBase's
* capability to test the hardware accelerated Canvas in the way that it is used by Views.
*/
+@MediumTest
public class CanvasStateTests extends ActivityTestBase {
-
- @SmallTest
+ @Test
public void testClipRectReturnValues() {
createTest()
.addCanvasClient(new CanvasClient() {
@@ -53,7 +54,7 @@
.runWithoutVerification();
}
- @SmallTest
+ @Test
public void testClipRegionReturnValues() {
createTest()
.addCanvasClient(new CanvasClient() {
@@ -86,7 +87,7 @@
.runWithoutVerification();
}
- @SmallTest
+ @Test
public void testClipPathReturnValues() {
createTest()
.addCanvasClient(new CanvasClient() {
@@ -107,7 +108,7 @@
})
.runWithoutVerification();
}
- @SmallTest
+ @Test
public void testQuickReject() {
createTest()
.addCanvasClient(new CanvasClient() {
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ColorFilterAlphaTest.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ColorFilterAlphaTest.java
index 56ca467..483ad87 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ColorFilterAlphaTest.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ColorFilterAlphaTest.java
@@ -32,6 +32,7 @@
import java.util.List;
+@MediumTest
@RunWith(Parameterized.class)
public class ColorFilterAlphaTest extends ActivityTestBase {
// We care about one point in each of the four rectangles of different alpha values, as well as
@@ -130,7 +131,6 @@
};
@Test
- @MediumTest
public void test() {
createTest()
.addCanvasClient(mCanvasClient, mConfig.hardwareAccelerated)
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ExactCanvasTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ExactCanvasTests.java
index d3fdb7b..bf68f3e 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ExactCanvasTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ExactCanvasTests.java
@@ -22,7 +22,7 @@
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.drawable.NinePatchDrawable;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.MediumTest;
import android.uirendering.cts.bitmapcomparers.BitmapComparer;
import android.uirendering.cts.bitmapcomparers.ExactComparer;
import android.uirendering.cts.bitmapverifiers.BitmapVerifier;
@@ -30,11 +30,13 @@
import android.uirendering.cts.testinfrastructure.ActivityTestBase;
import android.uirendering.cts.testinfrastructure.CanvasClient;
import android.uirendering.cts.R;
+import org.junit.Test;
+@MediumTest
public class ExactCanvasTests extends ActivityTestBase {
private final BitmapComparer mExactComparer = new ExactComparer();
- @SmallTest
+ @Test
public void testBlueRect() {
final Rect rect = new Rect(10, 10, 80, 80);
createTest()
@@ -50,7 +52,7 @@
.runWithVerifier(new RectVerifier(Color.WHITE, Color.BLUE, rect));
}
- @SmallTest
+ @Test
public void testPoints() {
createTest()
.addCanvasClient(new CanvasClient() {
@@ -68,7 +70,7 @@
.runWithComparer(mExactComparer);
}
- @SmallTest
+ @Test
public void testBlackRectWithStroke() {
createTest()
.addCanvasClient(new CanvasClient() {
@@ -86,7 +88,7 @@
.runWithComparer(mExactComparer);
}
- @SmallTest
+ @Test
public void testBlackLineOnGreenBack() {
createTest()
.addCanvasClient(new CanvasClient() {
@@ -102,7 +104,7 @@
.runWithComparer(mExactComparer);
}
- @SmallTest
+ @Test
public void testDrawRedRectOnBlueBack() {
createTest()
.addCanvasClient(new CanvasClient() {
@@ -117,7 +119,7 @@
.runWithComparer(mExactComparer);
}
- @SmallTest
+ @Test
public void testDrawLine() {
createTest()
.addCanvasClient(new CanvasClient() {
@@ -135,7 +137,7 @@
.runWithComparer(mExactComparer);
}
- @SmallTest
+ @Test
public void testDrawWhiteScreen() {
createTest()
.addCanvasClient(new CanvasClient() {
@@ -147,7 +149,7 @@
.runWithComparer(mExactComparer);
}
- @SmallTest
+ @Test
public void testBasicText() {
final String testString = "THIS IS A TEST";
createTest()
@@ -164,7 +166,7 @@
.runWithComparer(mExactComparer);
}
- @SmallTest
+ @Test
public void testBasicColorXfermode() {
createTest()
.addCanvasClient(new CanvasClient() {
@@ -177,7 +179,7 @@
.runWithComparer(mExactComparer);
}
- @SmallTest
+ @Test
public void testBluePaddedSquare() {
final NinePatchDrawable ninePatchDrawable = (NinePatchDrawable)
getActivity().getResources().getDrawable(R.drawable.blue_padded_square);
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/FontRenderingTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/FontRenderingTests.java
index bac3629..738dcfb 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/FontRenderingTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/FontRenderingTests.java
@@ -22,7 +22,7 @@
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.MediumTest;
import android.uirendering.cts.bitmapcomparers.BitmapComparer;
import android.uirendering.cts.bitmapcomparers.MSSIMComparer;
import android.uirendering.cts.bitmapverifiers.GoldenImageVerifier;
@@ -30,7 +30,9 @@
import android.uirendering.cts.testinfrastructure.CanvasClient;
import android.uirendering.cts.R;
+import org.junit.Test;
+@MediumTest
public class FontRenderingTests extends ActivityTestBase {
// Thresholds are barely loose enough for differences between sw and hw renderers.
private static final double REGULAR_THRESHOLD = 0.92;
@@ -67,42 +69,42 @@
.runWithVerifier(new GoldenImageVerifier(goldenBitmap, comparer));
}
- @SmallTest
+ @Test
public void testDefaultFont() {
fontTestBody("sans-serif",
Typeface.NORMAL,
R.drawable.hello1);
}
- @SmallTest
+ @Test
public void testBoldFont() {
fontTestBody("sans-serif",
Typeface.BOLD,
R.drawable.bold1);
}
- @SmallTest
+ @Test
public void testItalicFont() {
fontTestBody("sans-serif",
Typeface.ITALIC,
R.drawable.italic1);
}
- @SmallTest
+ @Test
public void testBoldItalicFont() {
fontTestBody("sans-serif",
Typeface.BOLD | Typeface.ITALIC,
R.drawable.bolditalic1);
}
- @SmallTest
+ @Test
public void testMediumFont() {
fontTestBody("sans-serif-medium",
Typeface.NORMAL,
R.drawable.medium1);
}
- @SmallTest
+ @Test
public void testMediumBoldFont() {
// bold attribute on medium base font = black
fontTestBody("sans-serif-medium",
@@ -110,28 +112,28 @@
R.drawable.black1);
}
- @SmallTest
+ @Test
public void testMediumItalicFont() {
fontTestBody("sans-serif-medium",
Typeface.ITALIC,
R.drawable.mediumitalic1);
}
- @SmallTest
+ @Test
public void testMediumBoldItalicFont() {
fontTestBody("sans-serif-medium",
Typeface.BOLD | Typeface.ITALIC,
R.drawable.blackitalic1);
}
- @SmallTest
+ @Test
public void testLightFont() {
fontTestBody("sans-serif-light",
Typeface.NORMAL,
R.drawable.light1);
}
- @SmallTest
+ @Test
public void testLightBoldFont() {
// bold attribute on light base font = medium
fontTestBody("sans-serif-light",
@@ -139,28 +141,28 @@
R.drawable.medium1);
}
- @SmallTest
+ @Test
public void testLightItalicFont() {
fontTestBody("sans-serif-light",
Typeface.ITALIC,
R.drawable.lightitalic1);
}
- @SmallTest
+ @Test
public void testLightBoldItalicFont() {
fontTestBody("sans-serif-light",
Typeface.BOLD | Typeface.ITALIC,
R.drawable.mediumitalic1);
}
- @SmallTest
+ @Test
public void testThinFont() {
fontTestBody("sans-serif-thin",
Typeface.NORMAL,
R.drawable.thin1);
}
- @SmallTest
+ @Test
public void testThinBoldFont() {
// bold attribute on thin base font = normal
fontTestBody("sans-serif-thin",
@@ -168,28 +170,28 @@
R.drawable.hello1);
}
- @SmallTest
+ @Test
public void testThinItalicFont() {
fontTestBody("sans-serif-thin",
Typeface.ITALIC,
R.drawable.thinitalic1);
}
- @SmallTest
+ @Test
public void testThinBoldItalicFont() {
fontTestBody("sans-serif-thin",
Typeface.BOLD | Typeface.ITALIC,
R.drawable.italic1);
}
- @SmallTest
+ @Test
public void testBlackFont() {
fontTestBody("sans-serif-black",
Typeface.NORMAL,
R.drawable.black1);
}
- @SmallTest
+ @Test
public void testBlackBoldFont() {
// bold attribute on black base font = black
fontTestBody("sans-serif-black",
@@ -197,14 +199,14 @@
R.drawable.black1);
}
- @SmallTest
+ @Test
public void testBlackItalicFont() {
fontTestBody("sans-serif-black",
Typeface.ITALIC,
R.drawable.blackitalic1);
}
- @SmallTest
+ @Test
public void testBlackBoldItalicFont() {
fontTestBody("sans-serif-black",
Typeface.BOLD | Typeface.ITALIC,
@@ -213,42 +215,42 @@
/* condensed fonts */
- @SmallTest
+ @Test
public void testCondensedFont() {
fontTestBody("sans-serif-condensed",
Typeface.NORMAL,
R.drawable.condensed1);
}
- @SmallTest
+ @Test
public void testCondensedBoldFont() {
fontTestBody("sans-serif-condensed",
Typeface.BOLD,
R.drawable.condensedbold1);
}
- @SmallTest
+ @Test
public void testCondensedItalicFont() {
fontTestBody("sans-serif-condensed",
Typeface.ITALIC,
R.drawable.condenseditalic1);
}
- @SmallTest
+ @Test
public void testCondensedBoldItalicFont() {
fontTestBody("sans-serif-condensed",
Typeface.BOLD | Typeface.ITALIC,
R.drawable.condensedbolditalic1);
}
- @SmallTest
+ @Test
public void testCondensedLightFont() {
fontTestBody("sans-serif-condensed-light",
Typeface.NORMAL,
R.drawable.condensedlight1);
}
- @SmallTest
+ @Test
public void testCondensedLightItalicFont() {
fontTestBody("sans-serif-condensed-light",
Typeface.ITALIC,
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/InfrastructureTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/InfrastructureTests.java
index 37329af..c070b96 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/InfrastructureTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/InfrastructureTests.java
@@ -16,12 +16,12 @@
package android.uirendering.cts.testclasses;
import android.graphics.Point;
+import android.test.suitebuilder.annotation.MediumTest;
import android.uirendering.cts.R;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Rect;
-import android.test.suitebuilder.annotation.SmallTest;
import android.uirendering.cts.bitmapcomparers.BitmapComparer;
import android.uirendering.cts.bitmapcomparers.MSSIMComparer;
import android.uirendering.cts.bitmapverifiers.RectVerifier;
@@ -29,10 +29,12 @@
import android.uirendering.cts.testinfrastructure.CanvasClient;
import android.uirendering.cts.testinfrastructure.ViewInitializer;
import android.view.View;
+import org.junit.Test;
+@MediumTest
public class InfrastructureTests extends ActivityTestBase {
- @SmallTest
+ @Test
public void testScreenshot() {
for (int i = 0 ; i < 500 ; i ++) {
takeScreenshot(new Point());
@@ -45,7 +47,7 @@
* by verifying that two paths that should render differently *do* render
* differently.
*/
- @SmallTest
+ @Test
public void testRenderSpecIsolation() {
CanvasClient canvasClient = new CanvasClient() {
@Override
@@ -70,7 +72,7 @@
.runWithComparer(inverseComparer);
}
- @SmallTest
+ @Test
public void testViewInitializer() {
final Rect clipRect = new Rect(0, 0, 50, 50);
ViewInitializer viewInitializer = new ViewInitializer() {
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/LayoutTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/LayoutTests.java
index 30851b6..d69126c 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/LayoutTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/LayoutTests.java
@@ -17,21 +17,23 @@
import android.graphics.Color;
import android.graphics.Rect;
+import android.test.suitebuilder.annotation.MediumTest;
import android.uirendering.cts.bitmapverifiers.ColorVerifier;
import android.uirendering.cts.bitmapverifiers.RectVerifier;
import android.uirendering.cts.R;
-import android.test.suitebuilder.annotation.SmallTest;
import android.uirendering.cts.testinfrastructure.ActivityTestBase;
+import org.junit.Test;
+@MediumTest
public class LayoutTests extends ActivityTestBase {
- @SmallTest
+ @Test
public void testSimpleRedLayout() {
createTest().addLayout(R.layout.simple_red_layout, null, false).runWithVerifier(
new ColorVerifier(Color.RED));
}
- @SmallTest
+ @Test
public void testSimpleRectLayout() {
createTest().addLayout(R.layout.simple_rect_layout, null, false).runWithVerifier(
new RectVerifier(Color.WHITE, Color.BLUE, new Rect(5, 5, 85, 85)));
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/PathClippingTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/PathClippingTests.java
index ae5f05d..03f5e89 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/PathClippingTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/PathClippingTests.java
@@ -23,7 +23,7 @@
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.Typeface;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.MediumTest;
import android.uirendering.cts.bitmapcomparers.MSSIMComparer;
import android.uirendering.cts.bitmapverifiers.SamplePointVerifier;
import android.uirendering.cts.testinfrastructure.ActivityTestBase;
@@ -33,9 +33,11 @@
import android.view.ViewGroup;
import android.webkit.WebView;
import android.uirendering.cts.R;
+import org.junit.Test;
import static org.junit.Assert.assertNotNull;
+@MediumTest
public class PathClippingTests extends ActivityTestBase {
// draw circle with hole in it, with stroked circle
static final CanvasClient sTorusDrawCanvasClient = new CanvasClient() {
@@ -77,7 +79,7 @@
}
};
- @SmallTest
+ @Test
public void testCircleWithCircle() {
createTest()
.addCanvasClient(sTorusDrawCanvasClient, false)
@@ -85,7 +87,7 @@
.runWithComparer(new MSSIMComparer(0.90));
}
- @SmallTest
+ @Test
public void testCircleWithPoints() {
createTest()
.addCanvasClient(sTorusClipCanvasClient)
@@ -107,7 +109,7 @@
}));
}
- @SmallTest
+ @Test
public void testViewRotate() {
createTest()
.addLayout(R.layout.blue_padded_layout, new ViewInitializer() {
@@ -139,7 +141,7 @@
}));
}
- @SmallTest
+ @Test
public void testTextClip() {
createTest()
.addCanvasClient(new CanvasClient() {
@@ -164,7 +166,7 @@
.runWithComparer(new MSSIMComparer(0.90));
}
- @SmallTest
+ @Test
public void testWebViewClipWithCircle() {
if (!getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) {
return; // no WebView to run test on
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/PictureTest.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/PictureTest.java
index 6619b11..9c8f9ba 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/PictureTest.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/PictureTest.java
@@ -21,18 +21,20 @@
import android.graphics.Paint;
import android.graphics.Picture;
import android.graphics.Rect;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.MediumTest;
import android.uirendering.cts.bitmapverifiers.ColorVerifier;
import android.uirendering.cts.bitmapverifiers.RectVerifier;
import android.uirendering.cts.testinfrastructure.ActivityTestBase;
import android.uirendering.cts.testinfrastructure.CanvasClient;
+import org.junit.Test;
+@MediumTest
public class PictureTest extends ActivityTestBase {
private static final Rect sRect = new Rect(0, 0, 40, 40);
private static final Rect sOffsetRect = new Rect(40, 0, 80, 40);
- private static final Picture greenSquare() {
+ private static Picture greenSquare() {
Paint pt = new Paint();
pt.setColor(Color.GREEN);
Picture pic = new Picture();
@@ -44,6 +46,7 @@
return pic;
}
+ @Test
public void testPictureRespectsClip() throws Exception {
createTest()
.addCanvasClient(
@@ -58,6 +61,7 @@
).runWithVerifier(new ColorVerifier(Color.WHITE));
}
+ @Test
public void testPictureRespectsTranslate() throws Exception {
createTest()
.addCanvasClient(
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ShaderTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ShaderTests.java
index 6500681..16a38e8 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ShaderTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ShaderTests.java
@@ -25,15 +25,17 @@
import android.graphics.PorterDuff;
import android.graphics.RadialGradient;
import android.graphics.Shader;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.MediumTest;
import android.uirendering.cts.bitmapcomparers.MSSIMComparer;
import android.uirendering.cts.bitmapverifiers.ColorVerifier;
import android.uirendering.cts.testinfrastructure.ActivityTestBase;
import android.uirendering.cts.testinfrastructure.CanvasClient;
import android.uirendering.cts.R;
+import org.junit.Test;
+@MediumTest
public class ShaderTests extends ActivityTestBase {
- @SmallTest
+ @Test
public void testSinglePixelBitmapShader() {
createTest()
.addCanvasClient(new CanvasClient() {
@@ -52,7 +54,7 @@
.runWithVerifier(new ColorVerifier(Color.BLUE));
}
- @SmallTest
+ @Test
public void testSinglePixelComposeShader() {
createTest()
.addCanvasClient(new CanvasClient() {
@@ -83,7 +85,7 @@
.runWithVerifier(new ColorVerifier(Color.BLUE));
}
- @SmallTest
+ @Test
public void testComplexShaderUsage() {
/*
* This test not only builds a very complex drawing operation, but also tests an
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ShadowTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ShadowTests.java
index bc76757..6b9fb79 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ShadowTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ShadowTests.java
@@ -17,14 +17,16 @@
import android.graphics.Color;
import android.graphics.Point;
+import android.test.suitebuilder.annotation.MediumTest;
import android.uirendering.cts.bitmapverifiers.SamplePointVerifier;
import android.uirendering.cts.R;
-import android.test.suitebuilder.annotation.SmallTest;
import android.uirendering.cts.testinfrastructure.ActivityTestBase;
import android.uirendering.cts.util.CompareUtils;
+import org.junit.Test;
+@MediumTest
public class ShadowTests extends ActivityTestBase {
private class GrayScaleVerifier extends SamplePointVerifier {
@@ -39,7 +41,7 @@
}
}
- @SmallTest
+ @Test
public void testShadowLayout() {
int shadowColorValue = 0xDB;
// Android TV theme overrides shadow opacity to be darker.
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ViewClippingTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ViewClippingTests.java
index 2db635f0..3b1df30 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ViewClippingTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ViewClippingTests.java
@@ -3,6 +3,7 @@
import android.graphics.Color;
import android.graphics.Outline;
import android.graphics.Rect;
+import android.test.suitebuilder.annotation.MediumTest;
import android.uirendering.cts.bitmapverifiers.BitmapVerifier;
import android.uirendering.cts.bitmapverifiers.RectVerifier;
import android.uirendering.cts.testclasses.view.UnclippedBlueView;
@@ -12,6 +13,7 @@
import android.view.ViewGroup;
import android.view.ViewOutlineProvider;
import android.uirendering.cts.R;
+import org.junit.Test;
/**
* This tests view clipping by modifying properties of blue_padded_layout, and validating
@@ -19,6 +21,7 @@
*
* Since the layout is blue on a white background, this is always done with a RectVerifier.
*/
+@MediumTest
public class ViewClippingTests extends ActivityTestBase {
final Rect FULL_RECT = new Rect(0, 0, 90, 90);
final Rect BOUNDS_RECT = new Rect(0, 0, 80, 80);
@@ -66,30 +69,35 @@
return new RectVerifier(Color.WHITE, Color.BLUE, blueBoundsRect, 75);
}
+ @Test
public void testSimpleUnclipped() {
createTest()
.addLayout(R.layout.blue_padded_layout, null)
.runWithVerifier(makeClipVerifier(FULL_RECT));
}
+ @Test
public void testSimpleBoundsClip() {
createTest()
.addLayout(R.layout.blue_padded_layout, BOUNDS_CLIP_INIT)
.runWithVerifier(makeClipVerifier(BOUNDS_RECT));
}
+ @Test
public void testSimpleClipBoundsClip() {
createTest()
.addLayout(R.layout.blue_padded_layout, CLIP_BOUNDS_CLIP_INIT)
.runWithVerifier(makeClipVerifier(CLIP_BOUNDS_RECT));
}
+ @Test
public void testSimplePaddingClip() {
createTest()
.addLayout(R.layout.blue_padded_layout, PADDING_CLIP_INIT)
.runWithVerifier(makeClipVerifier(PADDED_RECT));
}
+ @Test
public void testSimpleOutlineClip() {
// NOTE: Only HW is supported
createTest()
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/XfermodeTest.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/XfermodeTest.java
index 857d3ab..c6e9881 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/XfermodeTest.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/XfermodeTest.java
@@ -33,6 +33,7 @@
import java.util.ArrayList;
import java.util.List;
+@MediumTest
@RunWith(Parameterized.class)
public class XfermodeTest extends ActivityTestBase {
/**
@@ -173,7 +174,6 @@
};
@Test
- @MediumTest
public void test() {
createTest()
.addCanvasClient(mCanvasClient, mConfig.hardwareAccelerated)
diff --git a/tests/tests/view/Android.mk b/tests/tests/view/Android.mk
index eb6cee7..57dc0ce 100644
--- a/tests/tests/view/Android.mk
+++ b/tests/tests/view/Android.mk
@@ -28,7 +28,8 @@
LOCAL_JAVA_LIBRARIES := android.test.runner
-LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner mockito-target
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ ctsdeviceutil ctstestrunner mockito-target platform-test-annotations
LOCAL_JNI_SHARED_LIBRARIES := libctsview_jni libnativehelper_compat_libc++
diff --git a/tests/tests/view/AndroidTest.xml b/tests/tests/view/AndroidTest.xml
index def111d..c818923 100644
--- a/tests/tests/view/AndroidTest.xml
+++ b/tests/tests/view/AndroidTest.xml
@@ -20,5 +20,6 @@
</target_preparer>
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.view.cts" />
+ <option name="runtime-hint" value="6m47s" />
</test>
</configuration>
diff --git a/tests/tests/view/res/layout/view_layout.xml b/tests/tests/view/res/layout/view_layout.xml
index 9769aa4..c576350 100644
--- a/tests/tests/view/res/layout/view_layout.xml
+++ b/tests/tests/view/res/layout/view_layout.xml
@@ -123,4 +123,14 @@
</LinearLayout>
</LinearLayout>
+ <FrameLayout
+ android:id="@+id/aggregate_visibility_parent"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+ <android.view.cts.MockView
+ android:id="@+id/mock_view_aggregate_visibility"
+ android:layout_width="10px"
+ android:layout_height="10px" />
+ </FrameLayout>
+
</LinearLayout>
diff --git a/tests/tests/view/src/android/view/cts/MockView.java b/tests/tests/view/src/android/view/cts/MockView.java
index 0a56369..3e140c2 100644
--- a/tests/tests/view/src/android/view/cts/MockView.java
+++ b/tests/tests/view/src/android/view/cts/MockView.java
@@ -70,10 +70,13 @@
private boolean mCalledDispatchKeyEventPreIme = false;
private boolean mCalledOnKeyPreIme = false;
private boolean mCalledGetPointerIcon = false;
+ private boolean mCalledOnVisibilityAggregated = false;
private int mOldWidth = -1;
private int mOldHeight = -1;
+ private boolean mLastAggregatedVisibility;
+
public MockView(Context context) {
super(context);
}
@@ -616,6 +619,21 @@
return mCalledGetPointerIcon;
}
+ @Override
+ public void onVisibilityAggregated(boolean isVisible) {
+ super.onVisibilityAggregated(isVisible);
+ mCalledOnVisibilityAggregated = true;
+ mLastAggregatedVisibility = isVisible;
+ }
+
+ public boolean hasCalledOnVisibilityAggregated() {
+ return mCalledOnVisibilityAggregated;
+ }
+
+ public boolean getLastAggregatedVisibility() {
+ return mLastAggregatedVisibility;
+ }
+
public void reset() {
mCalledOnCreateContextMenu = false;
@@ -655,8 +673,10 @@
mCalledDispatchKeyEventPreIme = false;
mCalledOnKeyPreIme = false;
mCalledGetPointerIcon = false;
+ mCalledOnVisibilityAggregated = false;
mOldWidth = -1;
mOldHeight = -1;
+ mLastAggregatedVisibility = false;
}
}
diff --git a/tests/tests/view/src/android/view/cts/ViewGroupOverlayTest.java b/tests/tests/view/src/android/view/cts/ViewGroupOverlayTest.java
index c4cebb9..46f66ce 100644
--- a/tests/tests/view/src/android/view/cts/ViewGroupOverlayTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewGroupOverlayTest.java
@@ -23,6 +23,7 @@
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.SystemClock;
+import android.platform.test.annotations.Presubmit;
import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.Pair;
@@ -57,6 +58,7 @@
mContext = getInstrumentation().getTargetContext();
}
+ @Presubmit
public void testBasics() {
DrawingUtils.assertAllPixelsOfColor("Default fill", mViewGroupWithOverlay,
Color.WHITE, null);
@@ -396,4 +398,4 @@
mViewGroupWithOverlay, Color.WHITE, colorRectangles);
}
-}
\ No newline at end of file
+}
diff --git a/tests/tests/view/src/android/view/cts/ViewGroupTest.java b/tests/tests/view/src/android/view/cts/ViewGroupTest.java
index 10e743a..49979ca 100644
--- a/tests/tests/view/src/android/view/cts/ViewGroupTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewGroupTest.java
@@ -27,7 +27,6 @@
import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.drawable.BitmapDrawable;
-import android.os.Build;
import android.os.Parcelable;
import android.os.SystemClock;
import android.test.InstrumentationTestCase;
@@ -1011,18 +1010,6 @@
assertEquals(2, rect.top);
assertEquals(1, rect.left);
assertEquals(1, rect.right);
-
- if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M || Build.VERSION.CODENAME.equals("N")) {
- textView.setTranslationX(2);
- textView.setTranslationY(1);
-
- rect.setEmpty();
- vg.offsetDescendantRectToMyCoords(textView, rect);
- assertEquals(3, rect.bottom);
- assertEquals(3, rect.top);
- assertEquals(3, rect.left);
- assertEquals(3, rect.right);
- }
}
public void testOffsetRectIntoDescendantCoords() {
@@ -1046,18 +1033,6 @@
assertEquals(4, rect.top);
assertEquals(4, rect.left);
assertEquals(6, rect.right);
-
- if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M || Build.VERSION.CODENAME.equals("N")) {
- textView.setTranslationX(2);
- textView.setTranslationY(1);
-
- rect.set(5, 6, 7, 8);
- vg.offsetRectIntoDescendantCoords(textView, rect);
- assertEquals(5, rect.bottom);
- assertEquals(3, rect.top);
- assertEquals(2, rect.left);
- assertEquals(4, rect.right);
- }
}
public void testOnAnimationEnd() {
diff --git a/tests/tests/view/src/android/view/cts/ViewTest.java b/tests/tests/view/src/android/view/cts/ViewTest.java
index 1e23660..2082973 100644
--- a/tests/tests/view/src/android/view/cts/ViewTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewTest.java
@@ -3940,6 +3940,89 @@
assertFalse(view2.hasPointerCapture());
}
+ public void testVisibilityAggregated() throws Throwable {
+ final View grandparent = mActivity.findViewById(R.id.viewlayout_root);
+ final View parent = mActivity.findViewById(R.id.aggregate_visibility_parent);
+ final MockView mv = (MockView) mActivity.findViewById(R.id.mock_view_aggregate_visibility);
+
+ assertEquals(parent, mv.getParent());
+ assertEquals(grandparent, parent.getParent());
+
+ assertTrue(mv.hasCalledOnVisibilityAggregated());
+ assertTrue(mv.getLastAggregatedVisibility());
+
+ final Runnable reset = new Runnable() {
+ @Override
+ public void run() {
+ grandparent.setVisibility(View.VISIBLE);
+ parent.setVisibility(View.VISIBLE);
+ mv.setVisibility(View.VISIBLE);
+ mv.reset();
+ }
+ };
+
+ runTestOnUiThread(reset);
+
+ setVisibilityOnUiThread(parent, View.GONE);
+
+ assertTrue(mv.hasCalledOnVisibilityAggregated());
+ assertFalse(mv.getLastAggregatedVisibility());
+
+ runTestOnUiThread(reset);
+
+ setVisibilityOnUiThread(grandparent, View.GONE);
+
+ assertTrue(mv.hasCalledOnVisibilityAggregated());
+ assertFalse(mv.getLastAggregatedVisibility());
+
+ runTestOnUiThread(reset);
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ grandparent.setVisibility(View.GONE);
+ parent.setVisibility(View.GONE);
+ mv.setVisibility(View.VISIBLE);
+
+ grandparent.setVisibility(View.VISIBLE);
+ }
+ });
+
+ assertTrue(mv.hasCalledOnVisibilityAggregated());
+ assertFalse(mv.getLastAggregatedVisibility());
+
+ runTestOnUiThread(reset);
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ grandparent.setVisibility(View.GONE);
+ parent.setVisibility(View.INVISIBLE);
+
+ grandparent.setVisibility(View.VISIBLE);
+ }
+ });
+
+ assertTrue(mv.hasCalledOnVisibilityAggregated());
+ assertFalse(mv.getLastAggregatedVisibility());
+
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ parent.setVisibility(View.VISIBLE);
+ }
+ });
+
+ assertTrue(mv.getLastAggregatedVisibility());
+ }
+
+ private void setVisibilityOnUiThread(final View view, int visibility) throws Throwable {
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ view.setVisibility(visibility);
+ }
+ });
+ }
+
private static class MockViewGroup extends ViewGroup {
boolean isStartActionModeForChildCalled = false;
int startActionModeForChildType = ActionMode.TYPE_PRIMARY;
diff --git a/tests/tests/webkit/Android.mk b/tests/tests/webkit/Android.mk
index eb468dd..3a09f77 100644
--- a/tests/tests/webkit/Android.mk
+++ b/tests/tests/webkit/Android.mk
@@ -23,7 +23,12 @@
LOCAL_JAVA_LIBRARIES := android.test.runner org.apache.http.legacy
-LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctsdeviceutillegacy ctstestserver ctstestrunner
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ ctsdeviceutil \
+ ctsdeviceutillegacy \
+ ctstestserver \
+ ctstestrunner \
+ platform-test-annotations
LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/tests/tests/webkit/src/android/webkit/cts/CookieTest.java b/tests/tests/webkit/src/android/webkit/cts/CookieTest.java
index cca7e35..4f89ec1 100644
--- a/tests/tests/webkit/src/android/webkit/cts/CookieTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/CookieTest.java
@@ -17,6 +17,7 @@
package android.webkit.cts;
import android.cts.util.NullWebViewUtils;
+import android.platform.test.annotations.Presubmit;
import android.test.ActivityInstrumentationTestCase2;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
@@ -56,6 +57,7 @@
assertFalse(mCookieManager.hasCookies());
}
+ @Presubmit
public void testDomain() {
if (!NullWebViewUtils.isWebViewAvailable()) {
return;
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewStartupTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewStartupTest.java
index 6768b6f..a4ebaca 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewStartupTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewStartupTest.java
@@ -20,6 +20,7 @@
import android.content.Context;
import android.cts.util.NullWebViewUtils;
import android.cts.util.PollingCheck;
+import android.os.StrictMode;
import android.test.ActivityInstrumentationTestCase2;
import android.test.UiThreadTest;
import android.util.Log;
@@ -89,4 +90,20 @@
assertEquals("42", m.group(1)); // value got incremented
}
+ @UiThreadTest
+ public void testStrictModeNotViolatedOnStartup() throws Throwable {
+ StrictMode.ThreadPolicy oldPolicy = StrictMode.getThreadPolicy();
+ StrictMode.ThreadPolicy testPolicy = new StrictMode.ThreadPolicy.Builder()
+ .detectDiskReads()
+ .penaltyLog()
+ .penaltyDeath()
+ .build();
+ StrictMode.setThreadPolicy(testPolicy);
+ try {
+ mActivity.createAndAttachWebView();
+ } finally {
+ StrictMode.setThreadPolicy(oldPolicy);
+ }
+ }
+
}
diff --git a/tests/tests/widget/Android.mk b/tests/tests/widget/Android.mk
index c5c3de3..96f10fc 100644
--- a/tests/tests/widget/Android.mk
+++ b/tests/tests/widget/Android.mk
@@ -21,7 +21,12 @@
# and when built explicitly put it in the data partition
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-LOCAL_STATIC_JAVA_LIBRARIES += mockito-target android-common ctsdeviceutil ctstestrunner
+LOCAL_STATIC_JAVA_LIBRARIES += \
+ mockito-target \
+ android-common \
+ ctsdeviceutil \
+ ctstestrunner \
+ platform-test-annotations
LOCAL_JAVA_LIBRARIES := android.test.runner
diff --git a/tests/tests/widget/AndroidTest.xml b/tests/tests/widget/AndroidTest.xml
index d943b85..ed7742a 100644
--- a/tests/tests/widget/AndroidTest.xml
+++ b/tests/tests/widget/AndroidTest.xml
@@ -21,6 +21,6 @@
</target_preparer>
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.widget.cts" />
- <option name="runtime-hint" value="3m" />
+ <option name="runtime-hint" value="11m55s" />
</test>
</configuration>
diff --git a/tests/tests/widget/res/layout/popup_window_item.xml b/tests/tests/widget/res/layout/popup_window_item.xml
new file mode 100644
index 0000000..b53fd22
--- /dev/null
+++ b/tests/tests/widget/res/layout/popup_window_item.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+
+<TextView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@android:id/text1"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/popup_row_height"
+ android:textAppearance="?android:attr/textAppearanceListItemSmall"
+ android:gravity="center_vertical"
+ android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd" />
diff --git a/tests/tests/widget/res/layout/popupwindow.xml b/tests/tests/widget/res/layout/popupwindow.xml
index 0c7b5e8..d84770d 100644
--- a/tests/tests/widget/res/layout/popupwindow.xml
+++ b/tests/tests/widget/res/layout/popupwindow.xml
@@ -30,27 +30,27 @@
<View android:id="@+id/anchor_upper"
android:layout_width="10dp"
- android:layout_height="10dp"
+ android:layout_height="30dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:background="#f00" />
<View android:id="@+id/anchor_lower"
android:layout_width="10dp"
- android:layout_height="10dp"
+ android:layout_height="30dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:background="#0f0" />
<View android:id="@+id/anchor_middle_left"
- android:layout_width="10dp"
+ android:layout_width="30dp"
android:layout_height="10dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:background="#00f" />
<View android:id="@+id/anchor_middle_right"
- android:layout_width="10dp"
+ android:layout_width="30dp"
android:layout_height="10dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
diff --git a/tests/tests/widget/res/transition/custom_transition.xml b/tests/tests/widget/res/transition/custom_transition.xml
new file mode 100644
index 0000000..cb8ea5c
--- /dev/null
+++ b/tests/tests/widget/res/transition/custom_transition.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+
+<transition xmlns:android="http://schemas.android.com/apk/res/android"
+ class="android.widget.cts.PopupWindowTest$CustomTransition"
+ android:duration="250" />
diff --git a/tests/tests/widget/res/values/dimens.xml b/tests/tests/widget/res/values/dimens.xml
new file mode 100644
index 0000000..3690039
--- /dev/null
+++ b/tests/tests/widget/res/values/dimens.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+<resources>
+ <dimen name="popup_row_height">48dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/tests/tests/widget/res/values/styles.xml b/tests/tests/widget/res/values/styles.xml
index 14d575b..e92cf25 100644
--- a/tests/tests/widget/res/values/styles.xml
+++ b/tests/tests/widget/res/values/styles.xml
@@ -35,6 +35,18 @@
<item name="type16">Typed Value!</item>
</style>
+ <style name="PopupWindow" parent="@android:style/Widget.Material.ListPopupWindow" />
+
+ <style name="PopupWindow.NullTransitions">
+ <item name="android:popupEnterTransition">@null</item>
+ <item name="android:popupExitTransition">@null</item>
+ </style>
+
+ <style name="PopupWindow.CustomTransitions">
+ <item name="android:popupEnterTransition">@transition/custom_transition</item>
+ <item name="android:popupExitTransition">@transition/custom_transition</item>
+ </style>
+
<style name="TextViewWithoutColorAndAppearance">
<item name="android:textSize">18sp</item>
</style>
diff --git a/tests/tests/widget/src/android/widget/cts/LinearLayoutTest.java b/tests/tests/widget/src/android/widget/cts/LinearLayoutTest.java
index 76fa782..895184d 100644
--- a/tests/tests/widget/src/android/widget/cts/LinearLayoutTest.java
+++ b/tests/tests/widget/src/android/widget/cts/LinearLayoutTest.java
@@ -16,24 +16,24 @@
package android.widget.cts;
-import android.graphics.Color;
-import android.view.View;
-import android.view.ViewTreeObserver;
import org.xmlpull.v1.XmlPullParser;
import android.app.Activity;
import android.content.Context;
+import android.graphics.Color;
import android.test.ActivityInstrumentationTestCase;
import android.test.ViewAsserts;
import android.util.AttributeSet;
import android.util.Xml;
+import android.view.View;
+import android.view.View.MeasureSpec;
import android.view.ViewGroup;
-import android.widget.LinearLayout.LayoutParams;
+import android.view.ViewTreeObserver;
import android.widget.AbsoluteLayout;
import android.widget.LinearLayout;
+import android.widget.LinearLayout.LayoutParams;
import android.widget.ListView;
import android.widget.TextView;
-
import android.widget.cts.R;
import java.util.concurrent.CountDownLatch;
@@ -177,6 +177,54 @@
assertEquals(Math.ceil(parentWidth * 0.3), weight03.getWidth(), 1.0);
}
+ public void testWeightDistribution() {
+ LinearLayout layout = new LinearLayout(mActivity);
+ for (int i = 0; i < 3; i++) {
+ layout.addView(new View(mActivity), new LayoutParams(0, 0, 1));
+ }
+
+ int size = 100;
+ int spec = MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY);
+
+ for (int i = 0; i < 3; i++) {
+ View child = layout.getChildAt(i);
+ LayoutParams lp = (LayoutParams) child.getLayoutParams();
+ lp.height = 0;
+ lp.width = LayoutParams.MATCH_PARENT;
+ child.setLayoutParams(lp);
+ }
+ layout.setOrientation(LinearLayout.VERTICAL);
+ layout.measure(spec, spec);
+ layout.layout(0, 0, size, size);
+ assertEquals(100, layout.getWidth());
+ assertEquals(100, layout.getChildAt(0).getWidth());
+ assertEquals(100, layout.getChildAt(1).getWidth());
+ assertEquals(100, layout.getChildAt(2).getWidth());
+ assertEquals(100, layout.getHeight());
+ assertEquals(33, layout.getChildAt(0).getHeight());
+ assertEquals(33, layout.getChildAt(1).getHeight());
+ assertEquals(34, layout.getChildAt(2).getHeight());
+
+ for (int i = 0; i < 3; i++) {
+ View child = layout.getChildAt(i);
+ LayoutParams lp = (LayoutParams) child.getLayoutParams();
+ lp.height = LayoutParams.MATCH_PARENT;
+ lp.width = 0;
+ child.setLayoutParams(lp);
+ }
+ layout.setOrientation(LinearLayout.HORIZONTAL);
+ layout.measure(spec, spec);
+ layout.layout(0, 0, size, size);
+ assertEquals(100, layout.getWidth());
+ assertEquals(33, layout.getChildAt(0).getWidth());
+ assertEquals(33, layout.getChildAt(1).getWidth());
+ assertEquals(34, layout.getChildAt(2).getWidth());
+ assertEquals(100, layout.getHeight());
+ assertEquals(100, layout.getChildAt(0).getHeight());
+ assertEquals(100, layout.getChildAt(1).getHeight());
+ assertEquals(100, layout.getChildAt(2).getHeight());
+ }
+
public void testGenerateLayoutParams() {
ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(320, 240);
MockLinearLayout mockLinearLayout = new MockLinearLayout(mContext);
diff --git a/tests/tests/widget/src/android/widget/cts/ListPopupWindowTest.java b/tests/tests/widget/src/android/widget/cts/ListPopupWindowTest.java
index 1bdde5a..abe7848 100644
--- a/tests/tests/widget/src/android/widget/cts/ListPopupWindowTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ListPopupWindowTest.java
@@ -23,6 +23,7 @@
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.SystemClock;
+import android.platform.test.annotations.Presubmit;
import android.support.test.InstrumentationRegistry;
import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.SmallTest;
@@ -105,6 +106,11 @@
new ListPopupWindow(mActivity, null, 0, android.R.style.Widget_Material_ListPopupWindow);
}
+ public void noDefaultVisibility() {
+ mPopupWindow = new ListPopupWindow(mActivity);
+ assertFalse(mPopupWindow.isShowing());
+ }
+
public void testAccessBackground() {
mPopupWindowBuilder = new Builder();
mPopupWindowBuilder.show();
@@ -281,8 +287,6 @@
public void testDismiss() {
mPopupWindowBuilder = new Builder();
- assertFalse(mPopupWindow.isShowing());
-
mPopupWindowBuilder.show();
assertTrue(mPopupWindow.isShowing());
@@ -511,6 +515,7 @@
assertTrue(lastChildOnScreenXY[1] + lastListChild.getHeight() <= promptViewOnScreenXY[1]);
}
+ @Presubmit
public void testAccessSelection() throws Throwable {
mPopupWindowBuilder = new Builder().withItemSelectedListener();
mPopupWindowBuilder.show();
@@ -599,6 +604,7 @@
}
});
mInstrumentation.waitForIdleSync();
+ assertTrue(anchor.isFocused());
// Send BACK key event. As our custom extension of EditText calls
// ListPopupWindow.onKeyPreIme, the end result should be the dismissal of the
@@ -608,6 +614,165 @@
assertFalse(mPopupWindow.isShowing());
}
+ public void testListSelectionWithDPad() throws Throwable {
+ mPopupWindowBuilder = new Builder().withAnchor(R.id.anchor_upper_left)
+ .withDismissListener().withItemSelectedListener();
+ mPopupWindowBuilder.show();
+
+ // "Point" our custom extension of EditText to our ListPopupWindow
+ final MockViewForListPopupWindow anchor =
+ (MockViewForListPopupWindow) mPopupWindow.getAnchorView();
+ anchor.wireTo(mPopupWindow);
+ // Request focus on our EditText
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ anchor.requestFocus();
+ }
+ });
+ mInstrumentation.waitForIdleSync();
+ assertTrue(anchor.isFocused());
+
+ // Select entry #1 in the popup list
+ final ListView listView = mPopupWindow.getListView();
+ ViewTestUtils.runOnMainAndDrawSync(mInstrumentation, listView, new Runnable() {
+ public void run() {
+ mPopupWindow.setSelection(1);
+ }
+ });
+ verify(mPopupWindowBuilder.mOnItemSelectedListener, times(1)).onItemSelected(
+ any(AdapterView.class), any(View.class), eq(1), eq(1L));
+
+ // Send DPAD_DOWN key event. As our custom extension of EditText calls
+ // ListPopupWindow.onKeyDown and onKeyUp, the end result should be transfer of selection
+ // down one row
+ mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_DOWN);
+ mInstrumentation.waitForIdleSync();
+
+ // At this point we expect that item #2 was selected
+ verify(mPopupWindowBuilder.mOnItemSelectedListener, times(1)).onItemSelected(
+ any(AdapterView.class), any(View.class), eq(2), eq(2L));
+
+ // Send a DPAD_UP key event. As our custom extension of EditText calls
+ // ListPopupWindow.onKeyDown and onKeyUp, the end result should be transfer of selection
+ // up one row
+ mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_UP);
+ mInstrumentation.waitForIdleSync();
+
+ // At this point we expect that item #1 was selected
+ verify(mPopupWindowBuilder.mOnItemSelectedListener, times(2)).onItemSelected(
+ any(AdapterView.class), any(View.class), eq(1), eq(1L));
+
+ // Send one more DPAD_UP key event. As our custom extension of EditText calls
+ // ListPopupWindow.onKeyDown and onKeyUp, the end result should be transfer of selection
+ // up one more row
+ mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_UP);
+ mInstrumentation.waitForIdleSync();
+
+ // At this point we expect that item #0 was selected
+ verify(mPopupWindowBuilder.mOnItemSelectedListener, times(1)).onItemSelected(
+ any(AdapterView.class), any(View.class), eq(0), eq(0L));
+
+ // Send ENTER key event. As our custom extension of EditText calls
+ // ListPopupWindow.onKeyDown and onKeyUp, the end result should be dismissal of
+ // the popup window
+ mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_ENTER);
+ mInstrumentation.waitForIdleSync();
+
+ verify(mPopupWindowBuilder.mOnDismissListener, times(1)).onDismiss();
+ assertFalse(mPopupWindow.isShowing());
+
+ verifyNoMoreInteractions(mPopupWindowBuilder.mOnItemSelectedListener);
+ verifyNoMoreInteractions(mPopupWindowBuilder.mOnDismissListener);
+ }
+
+ /**
+ * Emulates a drag-down gestures by injecting ACTION events with {@link Instrumentation}.
+ */
+ private void emulateDragDownGesture(int emulatedX, int emulatedStartY, int swipeAmount) {
+ // The logic below uses Instrumentation to emulate a swipe / drag gesture to bring up
+ // the popup content.
+
+ // Inject DOWN event
+ long downTime = SystemClock.uptimeMillis();
+ MotionEvent eventDown = MotionEvent.obtain(
+ downTime, downTime, MotionEvent.ACTION_DOWN, emulatedX, emulatedStartY, 1);
+ mInstrumentation.sendPointerSync(eventDown);
+
+ // Inject a sequence of MOVE events that emulate a "swipe down" gesture
+ for (int i = 0; i < 10; i++) {
+ long moveTime = SystemClock.uptimeMillis();
+ final int moveY = emulatedStartY + swipeAmount * i / 10;
+ MotionEvent eventMove = MotionEvent.obtain(
+ moveTime, moveTime, MotionEvent.ACTION_MOVE, emulatedX, moveY, 1);
+ mInstrumentation.sendPointerSync(eventMove);
+ // sleep for a bit to emulate a 200ms swipe
+ SystemClock.sleep(20);
+ }
+
+ // Inject UP event
+ long upTime = SystemClock.uptimeMillis();
+ MotionEvent eventUp = MotionEvent.obtain(
+ upTime, upTime, MotionEvent.ACTION_UP, emulatedX, emulatedStartY + swipeAmount, 1);
+ mInstrumentation.sendPointerSync(eventUp);
+
+ // Wait for the system to process all events in the queue
+ mInstrumentation.waitForIdleSync();
+ }
+
+ public void testCreateOnDragListener() throws Throwable {
+ // In this test we want precise control over the height of the popup content since
+ // we need to know by how much to swipe down to end the emulated gesture over the
+ // specific item in the popup. This is why we're using a popup style that removes
+ // all decoration around the popup content, as well as our own row layout with known
+ // height.
+ mPopupWindowBuilder = new Builder()
+ .withPopupStyleAttr(R.style.PopupEmptyStyle)
+ .withContentRowLayoutId(R.layout.popup_window_item)
+ .withItemClickListener().withDismissListener();
+
+ // Configure ListPopupWindow without showing it
+ mPopupWindowBuilder.configure();
+
+ // Get the anchor view and configure it with ListPopupWindow's drag-to-open listener
+ final View anchor = mActivity.findViewById(mPopupWindowBuilder.mAnchorId);
+ View.OnTouchListener dragListener = mPopupWindow.createDragToOpenListener(anchor);
+ anchor.setOnTouchListener(dragListener);
+ // And also configure it to show the popup window on click
+ anchor.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mPopupWindow.show();
+ }
+ });
+
+ // Get the height of a row item in our popup window
+ final int popupRowHeight = mActivity.getResources().getDimensionPixelSize(
+ R.dimen.popup_row_height);
+
+ final int[] anchorOnScreenXY = new int[2];
+ anchor.getLocationOnScreen(anchorOnScreenXY);
+
+ // Compute the start coordinates of a downward swipe and the amount of swipe. We'll
+ // be swiping by twice the row height. That, combined with the swipe originating in the
+ // center of the anchor should result in clicking the second row in the popup.
+ int emulatedX = anchorOnScreenXY[0] + anchor.getWidth() / 2;
+ int emulatedStartY = anchorOnScreenXY[1] + anchor.getHeight() / 2;
+ int swipeAmount = 2 * popupRowHeight;
+
+ // Emulate drag-down gesture with a sequence of motion events
+ emulateDragDownGesture(emulatedX, emulatedStartY, swipeAmount);
+
+ // We expect the swipe / drag gesture to result in clicking the second item in our list.
+ verify(mPopupWindowBuilder.mOnItemClickListener, times(1)).onItemClick(
+ any(AdapterView.class), any(View.class), eq(1), eq(1L));
+ // Since our item click listener calls dismiss() on the popup, we expect the popup to not
+ // be showing
+ assertFalse(mPopupWindow.isShowing());
+ // At this point our popup should have notified its dismiss listener
+ verify(mPopupWindowBuilder.mOnDismissListener, times(1)).onDismiss();
+ }
+
/**
* Inner helper class to configure an instance of <code>ListPopupWindow</code> for the
* specific test. The main reason for its existence is that once a popup window is shown
@@ -625,10 +790,14 @@
private int mVerticalOffset;
private int mDropDownGravity;
private int mAnchorId = R.id.anchor_upper;
+ private int mContentRowLayoutId = android.R.layout.simple_list_item_1;
private boolean mHasWindowLayoutType;
private int mWindowLayoutType;
+ private boolean mUseCustomPopupStyle;
+ private int mPopupStyleAttr;
+
private View mPromptView;
private int mPromptPosition;
@@ -637,7 +806,6 @@
private PopupWindow.OnDismissListener mOnDismissListener;
public Builder() {
- mPopupWindow = new ListPopupWindow(mActivity);
}
public Builder withAnchor(int anchorId) {
@@ -645,6 +813,17 @@
return this;
}
+ public Builder withContentRowLayoutId(int contentRowLayoutId) {
+ mContentRowLayoutId = contentRowLayoutId;
+ return this;
+ }
+
+ public Builder withPopupStyleAttr(int popupStyleAttr) {
+ mUseCustomPopupStyle = true;
+ mPopupStyleAttr = popupStyleAttr;
+ return this;
+ }
+
public Builder ignoreContentWidth() {
mIgnoreContentWidth = true;
return this;
@@ -732,7 +911,12 @@
return width;
}
- private void show() {
+ private void configure() {
+ if (mUseCustomPopupStyle) {
+ mPopupWindow = new ListPopupWindow(mActivity, null, mPopupStyleAttr, 0);
+ } else {
+ mPopupWindow = new ListPopupWindow(mActivity);
+ }
final String[] POPUP_CONTENT =
new String[]{"Alice", "Bob", "Charlie", "Deirdre", "El"};
final BaseAdapter listPopupAdapter = new BaseAdapter() {
@@ -759,7 +943,7 @@
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(mActivity).inflate(
- android.R.layout.simple_list_item_1, parent, false);
+ mContentRowLayoutId, parent, false);
ViewHolder viewHolder = new ViewHolder();
viewHolder.title = (TextView) convertView.findViewById(android.R.id.text1);
convertView.setTag(viewHolder);
@@ -825,6 +1009,10 @@
mPopupWindow.setPromptPosition(mPromptPosition);
mPopupWindow.setPromptView(mPromptView);
}
+ }
+
+ private void show() {
+ configure();
mInstrumentation.runOnMainSync(new Runnable() {
public void run() {
diff --git a/tests/tests/widget/src/android/widget/cts/MockViewForListPopupWindow.java b/tests/tests/widget/src/android/widget/cts/MockViewForListPopupWindow.java
index 8e280fe..dc6cfc6 100644
--- a/tests/tests/widget/src/android/widget/cts/MockViewForListPopupWindow.java
+++ b/tests/tests/widget/src/android/widget/cts/MockViewForListPopupWindow.java
@@ -44,5 +44,21 @@
}
return super.onKeyPreIme(keyCode, event);
}
+
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ if (mListPopupWindow != null) {
+ return mListPopupWindow.onKeyDown(keyCode, event);
+ }
+ return super.onKeyDown(keyCode, event);
+ }
+
+ @Override
+ public boolean onKeyUp(int keyCode, KeyEvent event) {
+ if (mListPopupWindow != null) {
+ return mListPopupWindow.onKeyUp(keyCode, event);
+ }
+ return super.onKeyUp(keyCode, event);
+ }
}
diff --git a/tests/tests/widget/src/android/widget/cts/PopupMenuTest.java b/tests/tests/widget/src/android/widget/cts/PopupMenuTest.java
index 8df2930..2339101 100644
--- a/tests/tests/widget/src/android/widget/cts/PopupMenuTest.java
+++ b/tests/tests/widget/src/android/widget/cts/PopupMenuTest.java
@@ -124,6 +124,17 @@
assertEquals(Gravity.TOP, mPopupMenu.getGravity());
}
+ public void testConstructorWithGravity() throws Throwable {
+ mBuilder = new Builder().withGravity(Gravity.TOP);
+ runTestOnUiThread(new Runnable() {
+ public void run() {
+ mBuilder.show();
+ }
+ });
+
+ assertEquals(Gravity.TOP, mPopupMenu.getGravity());
+ }
+
public void testDismissalViaAPI() throws Throwable {
mBuilder = new Builder().withDismissListener();
runTestOnUiThread(new Runnable() {
@@ -154,6 +165,56 @@
verifyNoMoreInteractions(mBuilder.mOnDismissListener);
}
+ public void testNestedDismissalViaAPI() throws Throwable {
+ // Use empty popup style to remove all transitions from the popup. That way we don't
+ // need to synchronize with the popup window enter transition before proceeding to
+ // "click" a submenu item.
+ mBuilder = new Builder().withDismissListener()
+ .withPopupStyleAttr(R.style.PopupEmptyStyle);
+ runTestOnUiThread(new Runnable() {
+ public void run() {
+ mBuilder.show();
+ }
+ });
+ mInstrumentation.waitForIdleSync();
+ verify(mBuilder.mOnDismissListener, never()).onDismiss(mPopupMenu);
+
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mPopupMenu.getMenu().performIdentifierAction(R.id.action_share, 0);
+ }
+ });
+ mInstrumentation.waitForIdleSync();
+
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mPopupMenu.getMenu().findItem(R.id.action_share).getSubMenu().
+ performIdentifierAction(R.id.action_share_email, 0);
+ }
+ });
+ mInstrumentation.waitForIdleSync();
+
+ runTestOnUiThread(new Runnable() {
+ public void run() {
+ mPopupMenu.dismiss();
+ }
+ });
+ mInstrumentation.waitForIdleSync();
+ verify(mBuilder.mOnDismissListener, times(1)).onDismiss(mPopupMenu);
+
+ runTestOnUiThread(new Runnable() {
+ public void run() {
+ mPopupMenu.dismiss();
+ }
+ });
+ mInstrumentation.waitForIdleSync();
+ // Shouldn't have any more interactions with our dismiss listener since the menu was
+ // already dismissed when we called dismiss()
+ verifyNoMoreInteractions(mBuilder.mOnDismissListener);
+ }
+
public void testDismissalViaTouch() throws Throwable {
// Use empty popup style to remove all transitions from the popup. That way we don't
// need to synchronize with the popup window enter transition before proceeding to
@@ -234,6 +295,52 @@
// Popup menu should be automatically dismissed on selecting an item
verify(mBuilder.mOnDismissListener, times(1)).onDismiss(mPopupMenu);
+ verifyNoMoreInteractions(mBuilder.mOnDismissListener);
+ }
+
+ public void testSubMenuClickViaAPI() throws Throwable {
+ // Use empty popup style to remove all transitions from the popup. That way we don't
+ // need to synchronize with the popup window enter transition before proceeding to
+ // "click" a submenu item.
+ mBuilder = new Builder().withDismissListener().withMenuItemClickListener()
+ .withPopupStyleAttr(R.style.PopupEmptyStyle);
+ runTestOnUiThread(new Runnable() {
+ public void run() {
+ mBuilder.show();
+ }
+ });
+ mInstrumentation.waitForIdleSync();
+
+ // Verify that our menu item click listener hasn't been called yet
+ verify(mBuilder.mOnMenuItemClickListener, never()).onMenuItemClick(any(MenuItem.class));
+
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mPopupMenu.getMenu().performIdentifierAction(R.id.action_share, 0);
+ }
+ });
+ // Verify that our menu item click listener has been called on "share" action
+ verify(mBuilder.mOnMenuItemClickListener, times(1)).onMenuItemClick(
+ mPopupMenu.getMenu().findItem(R.id.action_share));
+
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mPopupMenu.getMenu().findItem(R.id.action_share).getSubMenu().
+ performIdentifierAction(R.id.action_share_email, 0);
+ }
+ });
+
+ // Verify that out menu item click listener has been called with the expected menu item
+ verify(mBuilder.mOnMenuItemClickListener, times(1)).onMenuItemClick(
+ mPopupMenu.getMenu().findItem(R.id.action_share).getSubMenu()
+ .findItem(R.id.action_share_email));
+ verifyNoMoreInteractions(mBuilder.mOnMenuItemClickListener);
+
+ // Popup menu should be automatically dismissed on selecting an item
+ verify(mBuilder.mOnDismissListener, times(1)).onDismiss(mPopupMenu);
+ verifyNoMoreInteractions(mBuilder.mOnDismissListener);
}
/**
@@ -247,8 +354,13 @@
private boolean mHasDismissListener;
private boolean mHasMenuItemClickListener;
private boolean mInflateWithInflater;
+
+ private boolean mUseCustomPopupStyle;
private int mPopupStyleAttr = android.R.attr.popupMenuStyle;
+ private boolean mUseCustomGravity;
+ private int mGravity = Gravity.NO_GRAVITY;
+
private PopupMenu.OnMenuItemClickListener mOnMenuItemClickListener;
private PopupMenu.OnDismissListener mOnDismissListener;
@@ -270,13 +382,28 @@
}
public Builder withPopupStyleAttr(int popupStyleAttr) {
+ mUseCustomPopupStyle = true;
mPopupStyleAttr = popupStyleAttr;
return this;
}
+ public Builder withGravity(int gravity) {
+ mUseCustomGravity = true;
+ mGravity = gravity;
+ return this;
+ }
+
private void configure() {
mAnchor = mActivity.findViewById(R.id.anchor_middle_left);
- mPopupMenu = new PopupMenu(mActivity, mAnchor, Gravity.NO_GRAVITY, mPopupStyleAttr, 0);
+ if (!mUseCustomGravity && !mUseCustomPopupStyle) {
+ mPopupMenu = new PopupMenu(mActivity, mAnchor);
+ } else if (!mUseCustomPopupStyle) {
+ mPopupMenu = new PopupMenu(mActivity, mAnchor, mGravity);
+ } else {
+ mPopupMenu = new PopupMenu(mActivity, mAnchor, Gravity.NO_GRAVITY,
+ mPopupStyleAttr, 0);
+ }
+
if (mInflateWithInflater) {
final MenuInflater menuInflater = mPopupMenu.getMenuInflater();
menuInflater.inflate(R.menu.popup_menu, mPopupMenu.getMenu());
diff --git a/tests/tests/widget/src/android/widget/cts/PopupWindowTest.java b/tests/tests/widget/src/android/widget/cts/PopupWindowTest.java
index db67787..fe8b2c4 100644
--- a/tests/tests/widget/src/android/widget/cts/PopupWindowTest.java
+++ b/tests/tests/widget/src/android/widget/cts/PopupWindowTest.java
@@ -130,6 +130,43 @@
assertTrue(mPopupWindow.isFocusable());
}
+ public void testAccessEnterExitTransitions() {
+ PopupWindow w;
+
+ w = new PopupWindow(mActivity, null, 0, 0);
+ assertNull(w.getEnterTransition());
+ assertNull(w.getExitTransition());
+
+ w = new PopupWindow(mActivity, null, 0, R.style.PopupWindow_NullTransitions);
+ assertNull(w.getEnterTransition());
+ assertNull(w.getExitTransition());
+
+ w = new PopupWindow(mActivity, null, 0, R.style.PopupWindow_CustomTransitions);
+ assertTrue(w.getEnterTransition() instanceof CustomTransition);
+ assertTrue(w.getExitTransition() instanceof CustomTransition);
+
+ Transition enterTransition = new CustomTransition();
+ Transition exitTransition = new CustomTransition();
+ w = new PopupWindow(mActivity, null, 0, 0);
+ w.setEnterTransition(enterTransition);
+ w.setExitTransition(exitTransition);
+ assertEquals(enterTransition, w.getEnterTransition());
+ assertEquals(exitTransition, w.getExitTransition());
+
+ w.setEnterTransition(null);
+ w.setExitTransition(null);
+ assertNull(w.getEnterTransition());
+ assertNull(w.getExitTransition());
+ }
+
+ public static class CustomTransition extends Transition {
+ @Override
+ public void captureStartValues(TransitionValues transitionValues) {}
+
+ @Override
+ public void captureEndValues(TransitionValues transitionValues) {}
+ }
+
public void testAccessBackground() {
mPopupWindow = new PopupWindow(mActivity);
diff --git a/tests/tests/widget/src/android/widget/cts/TextViewTest.java b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
index acaaf65..a95e43d 100644
--- a/tests/tests/widget/src/android/widget/cts/TextViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
@@ -72,6 +72,7 @@
import android.text.method.TimeKeyListener;
import android.text.method.TransformationMethod;
import android.text.style.URLSpan;
+import android.text.style.UnderlineSpan;
import android.text.util.Linkify;
import android.util.DisplayMetrics;
import android.util.LocaleList;
@@ -4014,10 +4015,53 @@
mTextView.getText().toString());
ExtractedText et = new ExtractedText();
+
+ // Update text and selection.
et.text = "test";
+ et.selectionStart = 0;
+ et.selectionEnd = 2;
mTextView.setExtractedText(et);
assertEquals("test", mTextView.getText().toString());
+ assertEquals(0, mTextView.getSelectionStart());
+ assertEquals(2, mTextView.getSelectionEnd());
+
+ // Use partialStartOffset and partialEndOffset
+ et.partialStartOffset = 2;
+ et.partialEndOffset = 3;
+ et.text = "x";
+ et.selectionStart = 2;
+ et.selectionEnd = 3;
+
+ mTextView.setExtractedText(et);
+ assertEquals("text", mTextView.getText().toString());
+ assertEquals(2, mTextView.getSelectionStart());
+ assertEquals(3, mTextView.getSelectionEnd());
+
+ // Update text with spans.
+ final SpannableString ss = new SpannableString("ex");
+ ss.setSpan(new UnderlineSpan(), 0, 2, 0);
+ ss.setSpan(new URLSpan("ctstest://TextView/test"), 1, 2, 0);
+
+ et.text = ss;
+ et.partialStartOffset = 1;
+ et.partialEndOffset = 3;
+ mTextView.setExtractedText(et);
+
+ assertEquals("text", mTextView.getText().toString());
+ final Editable editable = mTextView.getEditableText();
+ final UnderlineSpan[] underlineSpans = mTextView.getEditableText().getSpans(
+ 0, editable.length(), UnderlineSpan.class);
+ assertEquals(1, underlineSpans.length);
+ assertEquals(1, editable.getSpanStart(underlineSpans[0]));
+ assertEquals(3, editable.getSpanEnd(underlineSpans[0]));
+
+ final URLSpan[] urlSpans = mTextView.getEditableText().getSpans(
+ 0, editable.length(), URLSpan.class);
+ assertEquals(1, urlSpans.length);
+ assertEquals(2, editable.getSpanStart(urlSpans[0]));
+ assertEquals(3, editable.getSpanEnd(urlSpans[0]));
+ assertEquals("ctstest://TextView/test", urlSpans[0].getURL());
}
public void testMoveCursorToVisibleOffset() throws Throwable {
diff --git a/tests/vm/AndroidTest.xml b/tests/vm/AndroidTest.xml
index 2bac07b..fc1098b 100644
--- a/tests/vm/AndroidTest.xml
+++ b/tests/vm/AndroidTest.xml
@@ -20,5 +20,6 @@
</target_preparer>
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.vm.cts" />
+ <option name="runtime-hint" value="20m14s" />
</test>
</configuration>
diff --git a/tools/cts-tradefed/res/config/collect-tests-only.xml b/tools/cts-tradefed/res/config/collect-tests-only.xml
new file mode 100644
index 0000000..1c22b11
--- /dev/null
+++ b/tools/cts-tradefed/res/config/collect-tests-only.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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 CTS from a pre-existing CTS installation">
+
+ <include name="cts" />
+
+ <!-- This tells cts-tradefed and the server what the plan name is, reports that have this plan
+ name should not be accepted, as it doesn't actually run the tests it simply marks all of
+ them as passed.
+ Obviously no one would modify the report before uploadng to falsify this
+ information, as that would be dishonest, and dishonesty kills kittens :'( -->
+ <option name="compatibility:plan" value="collect-tests-only" />
+
+ <!-- Tell all AndroidJUnitTests to only list the tests -->
+ <option name="compatibility:test-arg" value="com.android.tradefed.testtype.AndroidJUnitTest:collect-tests-only:true" />
+
+ <!-- Tell all GTests to only list the tests -->
+ <option name="compatibility:test-arg" value="com.android.tradefed.testtype.GTest:collect-tests-only:true" />
+
+ <!-- Tell all HostTests to only list the tests -->
+ <option name="compatibility:test-arg" value="com.android.tradefed.testtype.HostTest:collect-tests-only:true" />
+
+</configuration>
diff --git a/tools/cts-tradefed/res/config/cts-known-failures.xml b/tools/cts-tradefed/res/config/cts-known-failures.xml
new file mode 100644
index 0000000..d8d8608
--- /dev/null
+++ b/tools/cts-tradefed/res/config/cts-known-failures.xml
@@ -0,0 +1,215 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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="Configuration with CTS known failures" >
+ <!-- <option name="compatibility:exclude-filter" value="MODULE_NAME" /> Excludes whole module -->
+ <!-- <option name="compatibility:exclude-filter" value="MODULE_NAME PACKAGE_NAME" /> Excludes whole package -->
+ <!-- <option name="compatibility:exclude-filter" value="MODULE_NAME PACKAGE_NAME.CLASS_NAME" /> Excludes whole class -->
+ <!-- <option name="compatibility:exclude-filter" value="MODULE_NAME PACKAGE_NAME.CLASS_NAME#TEST_NAME" /> Excludes individual test -->
+
+ <!-- b/17595050 -->
+ <option name="compatibility:exclude-filter" value="CtsAccessibilityServiceTestCases android.accessibilityservice.cts.AccessibilityTextTraversalTest#testActionNextAndPreviousAtGranularityPageOverText" />
+ <option name="compatibility:exclude-filter" value="CtsAccessibilityServiceTestCases android.accessibilityservice.cts.AccessibilityTextTraversalTest#testActionNextAndPreviousAtGranularityPageOverTextExtend" />
+
+ <!-- b/17508787 -->
+ <option name="compatibility:exclude-filter" value="CtsAdminTestCases android.admin.cts.DevicePolicyManagerTest#testUninstallAllUserCaCerts_failIfNotProfileOwner" />
+
+ <!-- b/23776083 -->
+ <option name="compatibility:exclude-filter" value="CtsAlarmClockTestCases android.alarmclock.cts.DismissAlarmTest#testAll" />
+ <option name="compatibility:exclude-filter" value="CtsAlarmClockTestCases android.alarmclock.cts.SetAlarmTest#testAll" />
+ <option name="compatibility:exclude-filter" value="CtsAlarmClockTestCases android.alarmclock.cts.SnoozeAlarmTest#testAll" />
+
+ <!-- b/17993121 -->
+ <option name="compatibility:exclude-filter" value="CtsAppWidgetTestCases android.appwidget.cts.AppWidgetTest#testAppWidgetProviderCallbacks" />
+ <option name="compatibility:exclude-filter" value="CtsAppWidgetTestCases android.appwidget.cts.AppWidgetTest#testBindAppWidget" />
+ <option name="compatibility:exclude-filter" value="CtsAppWidgetTestCases android.appwidget.cts.AppWidgetTest#testCollectionWidgets" />
+ <option name="compatibility:exclude-filter" value="CtsAppWidgetTestCases android.appwidget.cts.AppWidgetTest#testDeleteHost" />
+ <option name="compatibility:exclude-filter" value="CtsAppWidgetTestCases android.appwidget.cts.AppWidgetTest#testDeleteHosts" />
+ <option name="compatibility:exclude-filter" value="CtsAppWidgetTestCases android.appwidget.cts.AppWidgetTest#testGetAppWidgetIds" />
+ <option name="compatibility:exclude-filter" value="CtsAppWidgetTestCases android.appwidget.cts.AppWidgetTest#testGetAppWidgetInfo" />
+ <option name="compatibility:exclude-filter" value="CtsAppWidgetTestCases android.appwidget.cts.AppWidgetTest#testGetAppWidgetOptions" />
+ <option name="compatibility:exclude-filter" value="CtsAppWidgetTestCases android.appwidget.cts.AppWidgetTest#testPartiallyUpdateAppWidgetViaWidgetId" />
+ <option name="compatibility:exclude-filter" value="CtsAppWidgetTestCases android.appwidget.cts.AppWidgetTest#testPartiallyUpdateAppWidgetViaWidgetIds" />
+ <option name="compatibility:exclude-filter" value="CtsAppWidgetTestCases android.appwidget.cts.AppWidgetTest#testTwoAppWidgetProviderCallbacks" />
+ <option name="compatibility:exclude-filter" value="CtsAppWidgetTestCases android.appwidget.cts.AppWidgetTest#testUpdateAppWidgetViaComponentName" />
+ <option name="compatibility:exclude-filter" value="CtsAppWidgetTestCases android.appwidget.cts.AppWidgetTest#testUpdateAppWidgetViaWidgetId" />
+ <option name="compatibility:exclude-filter" value="CtsAppWidgetTestCases android.appwidget.cts.AppWidgetTest#testUpdateAppWidgetViaWidgetIds" />
+
+ <!-- b/21668302 -->
+ <option name="compatibility:exclude-filter" value="CtsAssistTestCases android.assist.cts.AssistantContentViewTest#testAssistantContentViewDimens" />
+ <option name="compatibility:exclude-filter" value="CtsAssistTestCases android.assist.cts.ExtraAssistDataTest#testAssistContentAndAssistData" />
+ <option name="compatibility:exclude-filter" value="CtsAssistTestCases android.assist.cts.FocusChangeTest#testLayerCausesUnderlyingActivityToLoseFocus" />
+ <option name="compatibility:exclude-filter" value="CtsAssistTestCases android.assist.cts.LargeViewHierarchyTest#testTextView" />
+ <option name="compatibility:exclude-filter" value="CtsAssistTestCases android.assist.cts.ScreenshotTest#testBlueScreenshot" />
+ <option name="compatibility:exclude-filter" value="CtsAssistTestCases android.assist.cts.ScreenshotTest#testGreenScreenshot" />
+ <option name="compatibility:exclude-filter" value="CtsAssistTestCases android.assist.cts.ScreenshotTest#testRedScreenshot" />
+ <option name="compatibility:exclude-filter" value="CtsAssistTestCases android.assist.cts.TextViewTest#testTextView" />
+ <option name="compatibility:exclude-filter" value="CtsAssistTestCases android.assist.cts.WebViewTest#testWebView" />
+
+ <!-- b/23776099 -->
+ <option name="compatibility:exclude-filter" value="CtsCallLogTestCases android.calllog.cts.CallLogBackupTest#testSingleCallBackup" />
+
+ <!-- b/17530117 -->
+ <option name="compatibility:exclude-filter" value="CtsCameraTestCases android.hardware.camera2.cts.AllocationTest#testBlackWhite" />
+ <option name="compatibility:exclude-filter" value="CtsCameraTestCases android.hardware.camera2.cts.AllocationTest#testParamSensitivity" />
+ <!-- b/17989532 -->
+ <option name="compatibility:exclude-filter" value="CtsCameraTestCases android.hardware.camera2.cts.SurfaceViewPreviewTest#testPreparePerformance" />
+ <!-- b/23008511 -->
+ <option name="compatibility:exclude-filter" value="CtsCameraTestCases android.hardware.cts.CameraTest#testPreviewFpsRange" />
+
+ <option name="compatibility:exclude-filter" value="CtsCarTestCases" />
+
+ <!-- b/27578806 -->
+ <option name="compatibility:exclude-filter" value="CtsCppToolsTestCases com.android.cts.cpptools.RunAsHostTest#testRunAs" />
+
+ <!-- b/23776893 -->
+ <option name="compatibility:exclude-filter" value="CtsDumpsysHostTestCases android.dumpsys.cts.DumpsysHostTest#testBatterystatsOutput" />
+ <option name="compatibility:exclude-filter" value="CtsDumpsysHostTestCases android.dumpsys.cts.DumpsysHostTest#testGfxinfoFramestats" />
+
+ <!-- b/22922206 b/27534791 -->
+ <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorBatchingTests#testAccelerometer_50hz_batching" />
+ <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorBatchingTests#testAccelerometer_fastest_batching" />
+ <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorBatchingTests#testGravity_50hz_batching" />
+ <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorBatchingTests#testGravity_fastest_batching" />
+ <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorBatchingTests#testGyroscope_50hz_batching" />
+ <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorBatchingTests#testGyroscope_50hz_flush" />
+ <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorBatchingTests#testGyroscope_fastest_batching" />
+ <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorBatchingTests#testLinearAcceleration_50hz_batching" />
+ <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorBatchingTests#testLinearAcceleration_fastest_batching" />
+ <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorBatchingTests#testMagneticField_50hz_batching" />
+ <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorBatchingTests#testMagneticField_fastest_batching" />
+ <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorBatchingTests#testMagneticFieldUncalibrated_50hz_batching" />
+ <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorBatchingTests#testMagneticFieldUncalibrated_fastest_batching" />
+ <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorBatchingTests#testPressure_50hz_batching" />
+ <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorBatchingTests#testPressure_fastest_batching" />
+ <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorBatchingTests#testRotationVector_50hz_batching" />
+ <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorBatchingTests#testRotationVector_50hz_flush" />
+ <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorBatchingTests#testRotationVector_fastest_batching" />
+ <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorIntegrationTests#testSensorsMovingRates" />
+ <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorIntegrationTests#testSensorsWithSeveralClients" />
+ <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorTest#testBatchAndFlush" />
+ <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SensorTest#testSensorTimeStamps" />
+ <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SingleSensorTests#testGyroscope_15hz" />
+ <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SingleSensorTests#testGyroscope_1hz" />
+ <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SingleSensorTests#testMagneticField_1hz" />
+ <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SingleSensorTests#testMagneticField_50hz" />
+ <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SingleSensorTests#testMagneticFieldUncalibrated_200hz" />
+ <option name="compatibility:exclude-filter" value="CtsHardwareTestCases android.hardware.cts.SingleSensorTests#testOrientation_5hz" />
+
+ <!-- b/16720689 -->
+ <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.DebuggerOnDemand.OnthrowDebuggerLaunchTest#testDebuggerLaunch001" />
+ <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.DebuggerOnDemand.OnthrowDebuggerLaunchTest#testDebuggerLaunch002" />
+ <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.DebuggerOnDemand.OnthrowDebuggerLaunchTest#testDebuggerLaunch003" />
+ <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.DebuggerOnDemand.OnthrowDebuggerLaunchTest#testDebuggerLaunch004" />
+ <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.DebuggerOnDemand.OnthrowLaunchDebugger001#testDebugger002" />
+ <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.DebuggerOnDemand.OnthrowLaunchDebugger002#testDebugger" />
+ <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.Events.ClassUnloadTest#testClassUnloadEvent" />
+ <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.Events.MonitorContendedEnteredTest#testMonitorContendedEnteredForClassMatch" />
+ <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.Events.MonitorContendedEnterTest#testMonitorContendedEnterForClassMatch" />
+ <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.Events.MonitorWaitedTest#testMonitorWaitedForClassExclude" />
+ <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.Events.MonitorWaitedTest#testMonitorWaitedForClassMatchExact" />
+ <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.Events.MonitorWaitedTest#testMonitorWaitedForClassMatchFirst" />
+ <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.Events.MonitorWaitedTest#testMonitorWaitedForClassMatchSecond" />
+ <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.Events.MonitorWaitedTest#testMonitorWaitedForClassOnly" />
+ <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.Events.MonitorWaitTest#testMonitorWaitForClassExclude" />
+ <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.Events.MonitorWaitTest#testMonitorWaitForClassMatchExact" />
+ <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.Events.MonitorWaitTest#testMonitorWaitForClassMatchFirst" />
+ <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.Events.MonitorWaitTest#testMonitorWaitForClassMatchSecond" />
+ <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.Events.MonitorWaitTest#testMonitorWaitForClassOnly" />
+ <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.ReferenceType.ClassFileVersionTest#testClassFileVersion001" />
+ <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.ReferenceType.NestedTypesTest#testNestedTypes001" />
+ <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.ThreadReference.StopTest#testStop001" />
+ <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.VirtualMachine.HoldEventsTest#testHoldEvents001" />
+ <option name="compatibility:exclude-filter" value="CtsJdwp org.apache.harmony.jpda.tests.jdwp.VirtualMachine.ReleaseEventsTest#testReleaseEvents001" />
+
+ <!-- b/18117279 b/21262226 b/23144425 -->
+ <option name="compatibility:exclude-filter" value="CtsJobSchedulerTestCases android.jobscheduler.cts.ConnectivityConstraintTest#testConnectivityConstraintExecutes_withMobile" />
+ <option name="compatibility:exclude-filter" value="CtsJobSchedulerTestCases android.jobscheduler.cts.ConnectivityConstraintTest#testConnectivityConstraintExecutes_withWifi" />
+ <option name="compatibility:exclude-filter" value="CtsJobSchedulerTestCases android.jobscheduler.cts.ConnectivityConstraintTest#testUnmeteredConstraintExecutes_withWifi" />
+ <option name="compatibility:exclude-filter" value="CtsJobSchedulerTestCases android.jobscheduler.cts.ConnectivityConstraintTest#testUnmeteredConstraintFails_withMobile" />
+ <option name="compatibility:exclude-filter" value="CtsJobSchedulerTestCases android.jobscheduler.cts.TimingConstraintsTest#testJobParameters_unexpiredDeadline" />
+
+ <!-- b/25850508 -->
+ <option name="compatibility:exclude-filter" value="CtsMediaStressTestCases android.mediastress.cts.preconditions.MediaPreparerTest#testCopyMediaFiles" />
+ <option name="compatibility:exclude-filter" value="CtsMediaStressTestCases android.mediastress.cts.preconditions.MediaPreparerTest#testGetMaxVideoPlaybackResolutionFound" />
+ <option name="compatibility:exclude-filter" value="CtsMediaStressTestCases android.mediastress.cts.preconditions.MediaPreparerTest#testGetMaxVideoPlaybackResolutionNotFound" />
+ <option name="compatibility:exclude-filter" value="CtsMediaStressTestCases android.mediastress.cts.preconditions.MediaPreparerTest#testMediaFilesExistOnDeviceFalse" />
+ <option name="compatibility:exclude-filter" value="CtsMediaStressTestCases android.mediastress.cts.preconditions.MediaPreparerTest#testMediaFilesExistOnDeviceTrue" />
+ <option name="compatibility:exclude-filter" value="CtsMediaStressTestCases android.mediastress.cts.preconditions.MediaPreparerTest#testSetMountPoint" />
+ <option name="compatibility:exclude-filter" value="CtsMediaStressTestCases android.mediastress.cts.preconditions.MediaPreparerTest#testSkipMediaDownload" />
+
+ <!-- b/17144778 -->
+ <option name="compatibility:exclude-filter" value="CtsMediaTestCases android.media.cts.ImageReaderDecoderTest#testHwAVCDecode360pForFlexibleYuv" />
+ <!-- b/23827982 -->
+ <option name="compatibility:exclude-filter" value="CtsMediaTestCases android.media.cts.VideoEncoderTest#testGoogH264FlexArbitraryW" />
+ <option name="compatibility:exclude-filter" value="CtsMediaTestCases android.media.cts.VideoEncoderTest#testGoogH264SurfArbitraryW" />
+
+ <!-- b/25651805 -->
+ <option name="compatibility:exclude-filter" value="CtsNetTestCases android.net.cts.ConnectivityManagerTest#testRestrictedNetworks" />
+ <!-- b/18682315 -->
+ <option name="compatibility:exclude-filter" value="CtsNetTestCases android.net.cts.SSLCertificateSocketFactoryTest#testCreateSocket" />
+ <option name="compatibility:exclude-filter" value="CtsNetTestCases android.net.cts.SSLCertificateSocketFactoryTest#test_createSocket_bind" />
+ <option name="compatibility:exclude-filter" value="CtsNetTestCases android.net.cts.SSLCertificateSocketFactoryTest#test_createSocket_simple" />
+ <option name="compatibility:exclude-filter" value="CtsNetTestCases android.net.cts.SSLCertificateSocketFactoryTest#test_createSocket_wrapping" />
+
+ <!-- b/17394321 -->
+ <option name="compatibility:exclude-filter" value="CtsOpenGlPerfTestCases android.openglperf.cts.GlAppSwitchTest#testGlActivitySwitchingFast" />
+ <option name="compatibility:exclude-filter" value="CtsOpenGlPerfTestCases android.openglperf.cts.GlAppSwitchTest#testGlActivitySwitchingSlow" />
+
+ <!-- b/18091590 -->
+ <option name="compatibility:exclude-filter" value="CtsOpenGlPerfTestCases android.openglperf.cts.GlVboPerfTest#testVboWithVaryingIndexBufferNumbers" />
+
+ <!-- b/23192492 -->
+ <option name="compatibility:exclude-filter" value="CtsPermission2TestCases android.permission2.cts.ProtectedBroadcastsTest#testSendProtectedBroadcasts" />
+
+ <option name="compatibility:exclude-filter" value="CtsSampleDeviceTestCases" />
+ <option name="compatibility:exclude-filter" value="CtsSampleHostTestCases" />
+
+ <!-- b/18461670 -->
+ <option name="compatibility:exclude-filter" value="CtsSecurityTestCases android.security.cts.AudioPolicyBinderTest#test_getStreamVolumeLeak" />
+ <option name="compatibility:exclude-filter" value="CtsSecurityTestCases android.security.cts.AudioPolicyBinderTest#test_isStreamActive" />
+ <option name="compatibility:exclude-filter" value="CtsSecurityTestCases android.security.cts.AudioPolicyBinderTest#test_isStreamActiveRemotely" />
+ <option name="compatibility:exclude-filter" value="CtsSecurityTestCases android.security.cts.AudioPolicyBinderTest#test_startAudioSource" />
+ <option name="compatibility:exclude-filter" value="CtsSecurityTestCases android.security.cts.AudioPolicyBinderTest#test_startOutput" />
+ <option name="compatibility:exclude-filter" value="CtsSecurityTestCases android.security.cts.AudioPolicyBinderTest#test_stopOutput" />
+ <!-- b/27218502 -->
+ <option name="compatibility:exclude-filter" value="CtsSecurityTestCases android.security.cts.MediaCryptoTest#testMediaCryptoClearKey" />
+ <option name="compatibility:exclude-filter" value="CtsSecurityTestCases android.security.cts.MediaCryptoTest#testMediaCryptoWidevine" />
+
+ <!-- b/26150806 -->
+ <option name="compatibility:exclude-filter" value="CtsSignatureTestCases android.signature.cts.tests" />
+
+ <!-- b/23427621 -->
+ <option name="compatibility:exclude-filter" value="CtsSystemUiTestCases android.systemui.cts.LightStatusBarTests#testLightStatusBarIcons" />
+
+ <!-- b/23604254 -->
+ <option name="compatibility:exclude-filter" value="CtsTelecomTestCases android.telecom.cts.ExtendedInCallServiceTest#testAddNewOutgoingCallAndThenDisconnect" />
+ <option name="compatibility:exclude-filter" value="CtsTelecomTestCases android.telecom.cts.RemoteConferenceTest#testRemoteConferenceCallbacks_ConferenceableConnections" />
+
+ <!-- b/23979591 -->
+ <option name="compatibility:exclude-filter" value="CtsTelephonyTestCases android.telephony.cts.CellInfoTest#testCellInfo" />
+
+ <!-- b/23779020 -->
+ <option name="compatibility:exclude-filter" value="CtsTransitionTestCases android.transition.cts.ChangeScrollTest#testChangeScroll" />
+
+ <!-- b/17536113 -->
+ <option name="compatibility:exclude-filter" value="CtsUsageStatsTestCases android.app.usage.cts.UsageStatsTest#testNoAccessSilentlyFails" />
+ <option name="compatibility:exclude-filter" value="CtsUsageStatsTestCases android.app.usage.cts.UsageStatsTest#testOrderedActivityLaunchSequenceInEventLog" />
+ <option name="compatibility:exclude-filter" value="CtsUsageStatsTestCases android.app.usage.cts.UsageStatsTest#testPackageUsageStatsIntervals" />
+ <option name="compatibility:exclude-filter" value="CtsUsageStatsTestCases android.app.usage.cts.UsageStatsTest#testUsageEventsParceling" />
+
+ <!-- b/23238984 -->
+ <option name="compatibility:exclude-filter" value="CtsVoiceSettingsTestCases android.voicesettings.cts.ZenModeTest#testAll" />
+</configuration>
diff --git a/tools/cts-tradefed/res/config/cts.xml b/tools/cts-tradefed/res/config/cts.xml
index c54f355..2eb0c3e 100644
--- a/tools/cts-tradefed/res/config/cts.xml
+++ b/tools/cts-tradefed/res/config/cts.xml
@@ -17,18 +17,12 @@
<include name="everything" />
<include name="cts-preconditions" />
+ <include name="cts-known-failures" />
<option name="compatibility:plan" value="cts" />
<option name="enable-root" value="false" />
- <!-- Exclude sample test cases -->
- <option name="compatibility:exclude-filter" value="CtsSampleDeviceTestCases" />
- <option name="compatibility:exclude-filter" value="CtsSampleHostTestCases" />
-
- <!-- Exclude automotive only test cases for now -->
- <option name="compatibility:exclude-filter" value="CtsCarTestCases" />
-
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.PropertyCheck">
<option name="property-name" value="ro.build.type" />
<option name="expected-value" value="user"/> <!-- Device should have user build -->
@@ -41,4 +35,5 @@
<option name="throw-error" value="false"/> <!-- Only print warning if not en-US -->
</target_preparer>
<template-include name="reporters" default="basic-reporters" />
+
</configuration>
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageDef.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageDef.java
index b75a67a..b68073d 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageDef.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageDef.java
@@ -316,10 +316,6 @@
// mName means 'apk file name' for instrumentation tests
instrTest.addInstallApk(String.format("%s.apk", mName), mAppNameSpace);
mDigest = generateDigest(testCaseDir, String.format("%s.apk", mName));
- if (mTests.size() > 1000) {
- // TODO: hack, large test suites can take longer to collect tests, increase timeout
- instrTest.setCollectsTestsShellTimeout(10 * 60 * 1000);
- }
return instrTest;
}
diff --git a/tools/utils/buildCts.py b/tools/utils/buildCts.py
index 9923fcd..f983b15 100755
--- a/tools/utils/buildCts.py
+++ b/tools/utils/buildCts.py
@@ -118,20 +118,20 @@
packages.sort()
plan = tools.TestPlan(packages)
- plan.Exclude('android\.car.*')
+ plan.Exclude('android\.car')
plan.Exclude('android\.performance.*')
self.__WritePlan(plan, 'CTS')
self.__WritePlan(plan, 'CTS-TF')
plan = tools.TestPlan(packages)
- plan.Exclude('android\.car.*')
+ plan.Exclude('android\.car')
plan.Exclude('android\.performance.*')
plan.Exclude('android\.media\.cts\.StreamingMediaPlayerTest.*')
# Test plan to not include media streaming tests
self.__WritePlan(plan, 'CTS-No-Media-Stream')
plan = tools.TestPlan(packages)
- plan.Exclude('android\.car.*')
+ plan.Exclude('android\.car')
plan.Exclude('android\.performance.*')
self.__WritePlan(plan, 'SDK')
@@ -140,19 +140,16 @@
self.__WritePlan(plan, 'Android')
plan = tools.TestPlan(packages)
- plan.Exclude('android\.car.*')
plan.Include(r'android\.core\.tests.*')
plan.Exclude(r'android\.core\.tests\.libcore\.package\.harmony*')
self.__WritePlan(plan, 'Java')
# TODO: remove this once the tests are fixed and merged into Java plan above.
plan = tools.TestPlan(packages)
- plan.Exclude('android\.car.*')
plan.Include(r'android\.core\.tests\.libcore\.package\.harmony*')
self.__WritePlan(plan, 'Harmony')
plan = tools.TestPlan(packages)
- plan.Exclude('android\.car.*')
plan.Include(r'android\.core\.vm-tests-tf')
self.__WritePlan(plan, 'VM-TF')
@@ -174,7 +171,7 @@
plan.Include('android\.telephony')
plan.Include('android\.nativemedia.*')
plan.Include('com\.android\.cts\..*')#TODO(stuartscott): Should PDK have all these?
- plan.Exclude('android\.car.*')
+ plan.Exclude('android\.car')
self.__WritePlan(plan, 'PDK')
temporarily_known_failure_tests = BuildCtsTemporarilyKnownFailureList();
@@ -183,7 +180,7 @@
# CTS Stable plan
plan = tools.TestPlan(packages)
- plan.Exclude('android\.car.*')
+ plan.Exclude('android\.car')
plan.Exclude(r'android\.browser')
for package, test_list in flaky_tests.iteritems():
plan.ExcludeTests(package, test_list)
@@ -198,7 +195,6 @@
for package, test_list in flaky_tests.iteritems():
plan.Include(package+'$')
plan.IncludeTests(package, test_list)
- plan.Exclude('android\.car.*')
self.__WritePlan(plan, 'CTS-flaky')
small_tests = BuildAospSmallSizeTestList()
@@ -211,7 +207,6 @@
for package, test_list in small_tests.iteritems():
plan.Include(package+'$')
plan.Exclude(r'android\.browser')
- plan.Exclude('android\.car.*')
for package, test_list in flaky_tests.iteritems():
plan.ExcludeTests(package, test_list)
for package, test_list in releasekey_tests.iteritems():
@@ -229,7 +224,6 @@
plan.ExcludeTests(package, test_list)
for package, test_list in releasekey_tests.iteritems():
plan.ExcludeTests(package, test_list)
- plan.Exclude('android\.car.*')
self.__WritePlan(plan, 'CTS-kitkat-medium')
self.__WritePlan(plan, 'CTS-public-medium')
@@ -326,7 +320,7 @@
plan.Exclude(r'android\.view$')
plan.Exclude(r'android\.mediastress$')
plan.Exclude(r'android\.browser')
- plan.Exclude('android\.car.*')
+ plan.Exclude('android\.car')
for package, test_list in flaky_tests.iteritems():
plan.ExcludeTests(package, test_list)
for package, test_list in releasekey_tests.iteritems():
diff --git a/tools/vm-tests-tf/Android.mk b/tools/vm-tests-tf/Android.mk
index 1704d84..ef6aa84 100644
--- a/tools/vm-tests-tf/Android.mk
+++ b/tools/vm-tests-tf/Android.mk
@@ -44,8 +44,7 @@
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
LOCAL_MODULE_TAGS := optional
-LOCAL_JAVA_LIBRARIES := dx dasm cfassembler junit
-LOCAL_JAVA_LIBRARIES += jack
+LOCAL_JAVA_LIBRARIES := dx dasm cfassembler junit jsr305lib
LOCAL_CLASSPATH := $(HOST_JDK_TOOLS_JAR)