Merge "Add KeySet key-rotation CTS tests." into lmp-dev
diff --git a/CtsTestCaseList.mk b/CtsTestCaseList.mk
index 6eda314..2215600 100644
--- a/CtsTestCaseList.mk
+++ b/CtsTestCaseList.mk
@@ -24,6 +24,17 @@
CtsSharedUidInstallDiffCert \
CtsSimpleAppInstall \
CtsSimpleAppInstallDiffCert \
+ CtsSplitApp \
+ CtsSplitApp_x86 \
+ CtsSplitApp_x86_64 \
+ CtsSplitApp_armeabi-v7a \
+ CtsSplitApp_armeabi \
+ CtsSplitApp_arm64-v8a \
+ CtsSplitApp_mips64 \
+ CtsSplitApp_mips \
+ CtsSplitAppDiffVersion \
+ CtsSplitAppDiffCert \
+ CtsSplitAppFeature \
CtsTargetInstrumentationApp \
CtsUsePermissionDiffCert \
CtsWriteExternalStorageApp \
@@ -140,6 +151,7 @@
CtsTvTestCases \
CtsUiAutomationTestCases \
CtsUiRenderingTestCases \
+ CtsUsageStatsTestCases \
CtsUtilTestCases \
CtsViewTestCases \
CtsWebkitTestCases \
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 55ce851..f37e1fa 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -18,10 +18,9 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.cts.verifier"
android:versionCode="3"
- android:versionName="L_r0">
+ android:versionName="5.0_r0.5">
- <!-- Using 10+ for more complete NFC support... -->
- <uses-sdk android:minSdkVersion="20" android:targetSdkVersion="20"/>
+ <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="21"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
@@ -107,6 +106,8 @@
<category android:name="android.cts.intent.category.MANUAL_TEST" />
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_device_admin" />
+ <meta-data android:name="test_excluded_features"
+ android:value="android.hardware.type.television:android.software.leanback" />
</activity>
<receiver android:name=".admin.TestDeviceAdminReceiver"
@@ -443,6 +444,8 @@
<category android:name="android.cts.intent.category.MANUAL_TEST" />
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_security" />
+ <meta-data android:name="test_excluded_features"
+ android:value="android.hardware.type.television:android.software.leanback" />
</activity>
<activity android:name=".streamquality.StreamingVideoActivity"
@@ -871,6 +874,8 @@
<category android:name="android.cts.intent.category.MANUAL_TEST" />
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_location" />
+ <meta-data android:name="test_excluded_features"
+ android:value="android.hardware.type.television:android.software.leanback" />
</activity>
<activity android:name=".location.LocationModeBatterySavingTestActivity"
android:label="@string/location_mode_battery_saving_test">
@@ -887,6 +892,8 @@
<category android:name="android.cts.intent.category.MANUAL_TEST" />
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_location" />
+ <meta-data android:name="test_excluded_features"
+ android:value="android.hardware.type.television:android.software.leanback" />
</activity>
<activity android:name=".camera.formats.CameraFormatsActivity"
@@ -998,6 +1005,8 @@
<category android:name="android.cts.intent.category.MANUAL_TEST" />
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_sensors" />
+ <meta-data android:name="test_excluded_features"
+ android:value="android.hardware.type.television:android.software.leanback" />
</activity>
<activity android:name=".p2p.P2pTestListActivity"
@@ -1137,6 +1146,8 @@
<category android:name="android.cts.intent.category.MANUAL_TEST" />
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_sensors" />
+ <meta-data android:name="test_excluded_features"
+ android:value="android.hardware.type.television:android.software.leanback" />
</activity>
<activity
@@ -1152,6 +1163,8 @@
<meta-data
android:name="test_category"
android:value="@string/test_category_sensors" />
+ <meta-data android:name="test_excluded_features"
+ android:value="android.hardware.type.television:android.software.leanback" />
</activity>
<receiver android:name=".widget.WidgetCtsProvider">
@@ -1234,6 +1247,7 @@
<category android:name="android.cts.intent.category.MANUAL_TEST" />
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_managed_provisioning" />
+ <meta-data android:name="test_required_features" android:value="android.software.managed_users:android.software.device_admin" />
</activity>
@@ -1249,6 +1263,7 @@
<category android:name="android.intent.category.DEFAULT"></category>
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_managed_provisioning" />
+ <meta-data android:name="test_required_features" android:value="android.software.managed_users:android.software.device_admin" />
</activity>
<activity android:name=".managedprovisioning.ByodHelperActivity">
@@ -1259,6 +1274,13 @@
</intent-filter>
</activity>
+ <activity android:name=".managedprovisioning.CrossProfileTestActivity">
+ <intent-filter>
+ <action android:name="com.android.cts.verifier.managedprovisioning.CROSS_PROFILE" />
+ <category android:name="android.intent.category.DEFAULT"></category>
+ </intent-filter>
+ </activity>
+
<receiver android:name=".managedprovisioning.DeviceAdminTestReceiver"
android:label="@string/provisioning_byod_device_admin"
android:permission="android.permission.BIND_DEVICE_ADMIN">
diff --git a/apps/CtsVerifier/res/layout/provisioning_byod.xml b/apps/CtsVerifier/res/layout/provisioning_byod.xml
index 5e59558..989266f 100644
--- a/apps/CtsVerifier/res/layout/provisioning_byod.xml
+++ b/apps/CtsVerifier/res/layout/provisioning_byod.xml
@@ -41,7 +41,7 @@
<ListView
android:id="@id/android:list"
android:layout_width="match_parent"
- android:layout_height="258dp" />
+ android:layout_height="wrap_content" />
<include layout="@layout/pass_fail_buttons" />
diff --git a/apps/CtsVerifier/res/layout/provisioning_cross_profile.xml b/apps/CtsVerifier/res/layout/provisioning_cross_profile.xml
new file mode 100644
index 0000000..345e99d
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/provisioning_cross_profile.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+ <TextView android:id="@+id/text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceLarge" />
+
+ <Button
+ android:id="@+id/button_finish"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/provisioning_button_finish" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index bb755cd..22e0cff 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -1215,6 +1215,19 @@
<string name="provisioning_byod_profile_visible">Work profile visible in Settings</string>
<string name="provisioning_byod_admin_visible">Device administrator visible in Settings</string>
<string name="provisioning_byod_workapps_visible">Badged work apps visible in Launcher</string>
+ <string name="provisioning_byod_cross_profile">Open app cross profiles</string>
+ <string name="provisioning_byod_cross_profile_app_personal">
+ You selected the CTS Verifier option.
+ </string>
+ <string name="provisioning_byod_cross_profile_app_work">You selected the Work option.</string>
+ <string name="provisioning_byod_cross_profile_instruction">
+ Please press the Go button to start an action.\n
+ \n
+ You should be asked to choose either \"CTS Verifier\" or \"Work\" to complete the action.
+ Pressing either should bring up a page stating your choice.\n
+ \n
+ Verify that you are prompted with the above choices and both options work as intended. Then mark this test accordingly.
+ </string>
<string name="provisioning_byod_profile_visible_instruction">
Please press the Go button to open the Settings page.
Navigate to Accounts and confirm that:\n
@@ -1247,6 +1260,8 @@
<string name="provisioning_byod_profile_deleted">Work profile deleted.</string>
<string name="provisioning_byod_disabled">Device provisioning is not enabled.</string>
<string name="provisioning_byod_go">Go</string>
+ <string name="provisioning_button_finish">Finish</string>
+ <string name="provisioning_cross_profile_chooser">Choose an app to complete action</string>
<!-- Strings for DeviceOwnerProvisioningTest -->
<string name="provisioning_device_owner">Device Owner Provisioning</string>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/ManifestTestListAdapter.java b/apps/CtsVerifier/src/com/android/cts/verifier/ManifestTestListAdapter.java
index 1f19cbe..2f42e81 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/ManifestTestListAdapter.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/ManifestTestListAdapter.java
@@ -67,6 +67,14 @@
* <meta-data android:name="test_required_features" android:value="android.hardware.sensor.accelerometer" />
* </pre>
* </li>
+ * <li>OPTIONAL: Add a meta data attribute to indicate features such that, if any present, the
+ * test gets excluded from being shown. If the device has any of the excluded features then
+ * the test will not appear in the test list. Use a colon (:) to specify multiple features
+ * to exclude for the test. Note that the colon means "or" in this case.
+ * <pre>
+ * <meta-data android:name="test_excluded_features" android:value="android.hardware.type.television" />
+ * </pre>
+ * </li>
*
* </ol>
*/
@@ -78,6 +86,8 @@
private static final String TEST_REQUIRED_FEATURES_META_DATA = "test_required_features";
+ private static final String TEST_EXCLUDED_FEATURES_META_DATA = "test_excluded_features";
+
private Context mContext;
private String mTestParent;
@@ -152,7 +162,9 @@
String testName = info.activityInfo.name;
Intent intent = getActivityIntent(info.activityInfo);
String[] requiredFeatures = getRequiredFeatures(info.activityInfo.metaData);
- TestListItem item = TestListItem.newTest(title, testName, intent, requiredFeatures);
+ String[] excludedFeatures = getExcludedFeatures(info.activityInfo.metaData);
+ TestListItem item = TestListItem.newTest(title, testName, intent,
+ requiredFeatures, excludedFeatures);
String testCategory = getTestCategory(mContext, info.activityInfo.metaData);
addTestToCategory(testsByCategory, testCategory, item);
@@ -190,6 +202,19 @@
}
}
+ static String[] getExcludedFeatures(Bundle metaData) {
+ if (metaData == null) {
+ return null;
+ } else {
+ String value = metaData.getString(TEST_EXCLUDED_FEATURES_META_DATA);
+ if (value == null) {
+ return null;
+ } else {
+ return value.split(":");
+ }
+ }
+ }
+
static String getTitle(Context context, ActivityInfo activityInfo) {
if (activityInfo.labelRes != 0) {
return context.getString(activityInfo.labelRes);
@@ -216,22 +241,39 @@
tests.add(item);
}
- List<TestListItem> filterTests(List<TestListItem> tests) {
- List<TestListItem> filteredTests = new ArrayList<TestListItem>(tests);
- PackageManager packageManager = mContext.getPackageManager();
- Iterator<TestListItem> iterator = filteredTests.iterator();
- while (iterator.hasNext()) {
- TestListItem item = iterator.next();
- String[] requiredFeatures = item.requiredFeatures;
- if (requiredFeatures != null) {
- for (int i = 0; i < requiredFeatures.length; i++) {
- if (!packageManager.hasSystemFeature(requiredFeatures[i])) {
- iterator.remove();
- break;
- }
+ private boolean hasAnyFeature(String[] features) {
+ if (features != null) {
+ PackageManager packageManager = mContext.getPackageManager();
+ for (String feature : features) {
+ if (packageManager.hasSystemFeature(feature)) {
+ return true;
}
}
}
+ return false;
+ }
+
+ private boolean hasAllFeatures(String[] features) {
+ if (features != null) {
+ PackageManager packageManager = mContext.getPackageManager();
+ for (String feature : features) {
+ if (!packageManager.hasSystemFeature(feature)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ List<TestListItem> filterTests(List<TestListItem> tests) {
+ List<TestListItem> filteredTests = new ArrayList<TestListItem>();
+ for (TestListItem test : tests) {
+ String[] excludedFeatures = test.excludedFeatures;
+ String[] requiredFeatures = test.requiredFeatures;
+ if (!hasAnyFeature(excludedFeatures) && hasAllFeatures(requiredFeatures)) {
+ filteredTests.add(test);
+ }
+ }
return filteredTests;
}
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/TestListAdapter.java b/apps/CtsVerifier/src/com/android/cts/verifier/TestListAdapter.java
index 2cc79fb..0d9985c 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/TestListAdapter.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/TestListAdapter.java
@@ -83,14 +83,29 @@
/** Features necessary to run this test. */
final String[] requiredFeatures;
+ /** Features such that, if any present, the test gets excluded from being shown. */
+ final String[] excludedFeatures;
+
+ public static TestListItem newTest(Context context, int titleResId, String testName,
+ Intent intent, String[] requiredFeatures, String[] excludedFeatures) {
+ return newTest(context.getString(titleResId), testName, intent,
+ requiredFeatures, excludedFeatures);
+ }
+
public static TestListItem newTest(Context context, int titleResId, String testName,
Intent intent, String[] requiredFeatures) {
- return newTest(context.getString(titleResId), testName, intent, requiredFeatures);
+ return newTest(context.getString(titleResId), testName, intent,
+ requiredFeatures, null);
+ }
+
+ public static TestListItem newTest(String title, String testName, Intent intent,
+ String[] requiredFeatures, String[] excludedFeatures) {
+ return new TestListItem(title, testName, intent, requiredFeatures, excludedFeatures);
}
public static TestListItem newTest(String title, String testName, Intent intent,
String[] requiredFeatures) {
- return new TestListItem(title, testName, intent, requiredFeatures);
+ return new TestListItem(title, testName, intent, requiredFeatures, null);
}
public static TestListItem newCategory(Context context, int titleResId) {
@@ -98,15 +113,16 @@
}
public static TestListItem newCategory(String title) {
- return new TestListItem(title, null, null, null);
+ return new TestListItem(title, null, null, null, null);
}
private TestListItem(String title, String testName, Intent intent,
- String[] requiredFeatures) {
+ String[] requiredFeatures, String[] excludedFeatures) {
this.title = title;
this.testName = testName;
this.intent = intent;
this.requiredFeatures = requiredFeatures;
+ this.excludedFeatures = excludedFeatures;
}
boolean isTest() {
@@ -366,4 +382,4 @@
}
}
-}
\ No newline at end of file
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/fov/PhotoCaptureActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/fov/PhotoCaptureActivity.java
index d71dca2..178a811 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/fov/PhotoCaptureActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/fov/PhotoCaptureActivity.java
@@ -69,7 +69,7 @@
private List<SelectableResolution> mSupportedResolutions;
private ArrayAdapter<SelectableResolution> mAdapter;
- private int mCameraId;
+ private SelectableResolution mSelectedResolution;
private Camera mCamera;
private Size mSurfaceSize;
private boolean mCameraInitialized = false;
@@ -165,12 +165,7 @@
AdapterView<?> parent, View view, int position, long id) {
if (mSupportedResolutions != null) {
SelectableResolution resolution = mSupportedResolutions.get(position);
-
- switchToCamera(resolution.cameraId, false);
-
- Camera.Parameters params = mCamera.getParameters();
- params.setPictureSize(resolution.width, resolution.height);
- mCamera.setParameters(params);
+ switchToCamera(resolution, false);
// It should be guaranteed that the FOV is correctly updated after setParameters().
mReportedFovPrePictureTaken = mCamera.getParameters().getHorizontalViewAngle();
@@ -376,7 +371,7 @@
public void onCancel(DialogInterface arg0) {
// User cancelled preview size selection.
mPreviewSizes = null;
- switchToCamera(mCameraId, true);
+ switchToCamera(mSelectedResolution, true);
}
}).
setSingleChoiceItems(choices, 0, new DialogInterface.OnClickListener() {
@@ -389,7 +384,7 @@
if (mPreviewSizeCamerasToProcess.isEmpty()) {
// We're done, re-initialize camera.
- switchToCamera(mCameraId, true);
+ switchToCamera(mSelectedResolution, true);
} else {
// Process other cameras.
showNextDialogToChoosePreviewSize();
@@ -415,7 +410,7 @@
// Either use chosen preview size for current camera or automatically
// choose preview size based on view dimensions.
- Size selectedPreviewSize = (mPreviewSizes != null) ? mPreviewSizes[mCameraId] :
+ Size selectedPreviewSize = (mPreviewSizes != null) ? mPreviewSizes[mSelectedResolution.cameraId] :
getBestPreviewSize(mSurfaceSize.width, mSurfaceSize.height, params);
if (selectedPreviewSize != null) {
params.setPreviewSize(selectedPreviewSize.width, selectedPreviewSize.height);
@@ -427,19 +422,20 @@
private void startPreview() {
if (mCameraInitialized && mCamera != null) {
- setCameraDisplayOrientation(this, mCameraId, mCamera);
+ setCameraDisplayOrientation(this, mSelectedResolution.cameraId, mCamera);
mCamera.startPreview();
mPreviewActive = true;
}
}
- private void switchToCamera(int cameraId, boolean initializeCamera) {
+ private void switchToCamera(SelectableResolution resolution, boolean initializeCamera) {
if (mCamera != null) {
mCamera.stopPreview();
mCamera.release();
}
- mCameraId = cameraId;
- mCamera = Camera.open(cameraId);
+
+ mSelectedResolution = resolution;
+ mCamera = Camera.open(mSelectedResolution.cameraId);
if (initializeCamera){
initializeCamera();
@@ -472,7 +468,7 @@
* Set the common camera parameters on the given camera and returns the
* parameter object for further modification, if needed.
*/
- private static Camera.Parameters setCameraParams(Camera camera) {
+ private Camera.Parameters setCameraParams(Camera camera) {
// The picture size is taken and set from the spinner selection
// callback.
Camera.Parameters params = camera.getParameters();
@@ -480,6 +476,7 @@
params.setJpegQuality(100);
params.setFocusMode(getFocusMode(camera));
params.setZoom(0);
+ params.setPictureSize(mSelectedResolution.width, mSelectedResolution.height);
return params;
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/features/FeatureSummaryActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/features/FeatureSummaryActivity.java
index 20ccd81..032442b 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/features/FeatureSummaryActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/features/FeatureSummaryActivity.java
@@ -229,7 +229,7 @@
// add features from latest to last so that the latest requirements are put in the set first
int apiVersion = Build.VERSION.SDK_INT;
- if (apiVersion >= Build.VERSION_CODES.L) {
+ if (apiVersion >= Build.VERSION_CODES.LOLLIPOP) {
Collections.addAll(features, ALL_LMP_FEATURES);
}
if (apiVersion >= Build.VERSION_CODES.KITKAT_WATCH) {
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 69071f6..da823e8 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
@@ -73,6 +73,7 @@
private TestItem mProfileVisibleTest;
private TestItem mDeviceAdminVisibleTest;
private TestItem mWorkAppVisibleTest;
+ private TestItem mCrossProfileIntentFiltersTest;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -173,11 +174,19 @@
R.string.provisioning_byod_workapps_visible_instruction,
new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME));
+ Intent intent = new Intent(CrossProfileTestActivity.ACTION_CROSS_PROFILE);
+ Intent chooser = Intent.createChooser(intent, getResources().getString(R.string.provisioning_cross_profile_chooser));
+ mCrossProfileIntentFiltersTest = new TestItem(this,
+ R.string.provisioning_byod_cross_profile,
+ R.string.provisioning_byod_cross_profile_instruction,
+ chooser);
+
mTests.add(mDiskEncryptionTest);
mTests.add(mProfileOwnerInstalled);
mTests.add(mProfileVisibleTest);
mTests.add(mDeviceAdminVisibleTest);
mTests.add(mWorkAppVisibleTest);
+ mTests.add(mCrossProfileIntentFiltersTest);
}
@Override
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CrossProfileTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CrossProfileTestActivity.java
new file mode 100644
index 0000000..6c38e12
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CrossProfileTestActivity.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2012 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;
+//package com.android.cts.verifier.managedprovisioning;
+
+import android.app.Activity;
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.Bundle;
+import android.os.Process;
+import android.os.UserManager;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.TextView;
+
+import com.android.cts.verifier.R;
+
+/**
+ * Test activity for cross profile intents.
+ */
+public class CrossProfileTestActivity extends Activity {
+ // Intent for app in both profiles
+ public static final String ACTION_CROSS_PROFILE = "com.android.cts.verifier.managedprovisioning.CROSS_PROFILE";
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.provisioning_cross_profile);
+ TextView textView = (TextView) findViewById(R.id.text);
+
+ // Check if we are running in the work or personal side, by testing if currently we are the
+ // profile owner or not.
+ textView.setText(isProfileOwner() ? R.string.provisioning_byod_cross_profile_app_work
+ : R.string.provisioning_byod_cross_profile_app_personal);
+
+ findViewById(R.id.button_finish).setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ CrossProfileTestActivity.this.finish();
+ }
+ });
+ }
+
+ private boolean isProfileOwner() {
+ ComponentName adminReceiver = new ComponentName(this, DeviceAdminTestReceiver.class.getName());
+ DevicePolicyManager dpm = (DevicePolicyManager)getSystemService(Context.DEVICE_POLICY_SERVICE);
+ return dpm.isAdminActive(adminReceiver) && dpm.isProfileOwnerApp(adminReceiver.getPackageName());
+ }
+}
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 861bca2..8dccac3 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java
@@ -26,6 +26,8 @@
import android.util.Log;
import android.widget.Toast;
+import com.android.cts.verifier.managedprovisioning.ByodHelperActivity;
+
/**
* Profile owner receiver for BYOD flow test.
* Setup cross-profile intent filter after successful provisioning.
@@ -48,6 +50,7 @@
IntentFilter filter = new IntentFilter();
filter.addAction(ByodHelperActivity.ACTION_QUERY_PROFILE_OWNER);
filter.addAction(ByodHelperActivity.ACTION_REMOVE_PROFILE_OWNER);
+ filter.addAction(CrossProfileTestActivity.ACTION_CROSS_PROFILE);
dpm.addCrossProfileIntentFilter(getWho(context), filter,
DevicePolicyManager.FLAG_MANAGED_CAN_ACCESS_PARENT);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hce/HceEmulatorTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hce/HceEmulatorTestActivity.java
index 3029796..87fa3d1 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hce/HceEmulatorTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hce/HceEmulatorTestActivity.java
@@ -103,7 +103,7 @@
OnAndOffHostEmulatorActivity.class.getName(),
new Intent(this, OnAndOffHostEmulatorActivity.class), null));
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.L) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
adapter.add(TestListItem.newTest(this, R.string.nfc_hce_payment_dynamic_aids_emulator,
DynamicAidEmulatorActivity.class.getName(),
new Intent(this, DynamicAidEmulatorActivity.class), null));
diff --git a/hostsidetests/appsecurity/src/com/android/cts/appsecurity/SplitTests.java b/hostsidetests/appsecurity/src/com/android/cts/appsecurity/SplitTests.java
new file mode 100644
index 0000000..b9bc768
--- /dev/null
+++ b/hostsidetests/appsecurity/src/com/android/cts/appsecurity/SplitTests.java
@@ -0,0 +1,397 @@
+/*
+ * Copyright (C) 2014 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.appsecurity;
+
+import com.android.cts.tradefed.build.CtsBuildHelper;
+import com.android.cts.util.AbiUtils;
+import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
+import com.android.ddmlib.testrunner.TestIdentifier;
+import com.android.ddmlib.testrunner.TestResult;
+import com.android.ddmlib.testrunner.TestResult.TestStatus;
+import com.android.ddmlib.testrunner.TestRunResult;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.result.CollectingTestListener;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.testtype.IAbi;
+import com.android.tradefed.testtype.IAbiReceiver;
+import com.android.tradefed.testtype.IBuildReceiver;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Tests that verify installing of various split APKs from host side.
+ */
+public class SplitTests extends DeviceTestCase implements IAbiReceiver, IBuildReceiver {
+ private static final String PKG = "com.android.cts.splitapp";
+
+ private static final String APK = "CtsSplitApp.apk";
+
+ private static final String APK_mdpi = "CtsSplitApp_mdpi-v4.apk";
+ private static final String APK_hdpi = "CtsSplitApp_hdpi-v4.apk";
+ private static final String APK_xhdpi = "CtsSplitApp_xhdpi-v4.apk";
+ private static final String APK_xxhdpi = "CtsSplitApp_xxhdpi-v4.apk";
+
+ private static final String APK_v7 = "CtsSplitApp_v7.apk";
+ private static final String APK_fr = "CtsSplitApp_fr.apk";
+ private static final String APK_de = "CtsSplitApp_de.apk";
+
+ private static final String APK_x86 = "CtsSplitApp_x86.apk";
+ private static final String APK_x86_64 = "CtsSplitApp_x86_64.apk";
+ private static final String APK_armeabi_v7a = "CtsSplitApp_armeabi-v7a.apk";
+ private static final String APK_armeabi = "CtsSplitApp_armeabi.apk";
+ private static final String APK_arm64_v8a = "CtsSplitApp_arm64-v8a.apk";
+ private static final String APK_mips64 = "CtsSplitApp_mips64.apk";
+ private static final String APK_mips = "CtsSplitApp_mips.apk";
+
+ private static final String APK_DIFF_VERSION_v7 = "CtsSplitAppDiffVersion_v7.apk";
+ private static final String APK_DIFF_CERT_v7 = "CtsSplitAppDiffCert_v7.apk";
+
+ private static final String APK_FEATURE = "CtsSplitAppFeature.apk";
+ private static final String APK_FEATURE_v7 = "CtsSplitAppFeature_v7.apk";
+
+ private static final HashMap<String, String> ABI_TO_APK = new HashMap<>();
+
+ static {
+ ABI_TO_APK.put("x86", APK_x86);
+ ABI_TO_APK.put("x86_64", APK_x86_64);
+ ABI_TO_APK.put("armeabi-v7a", APK_armeabi_v7a);
+ ABI_TO_APK.put("armeabi", APK_armeabi);
+ ABI_TO_APK.put("arm64-v8a", APK_arm64_v8a);
+ ABI_TO_APK.put("mips64", APK_mips64);
+ ABI_TO_APK.put("mips", APK_mips);
+ }
+
+ private IAbi mAbi;
+ private CtsBuildHelper mCtsBuild;
+
+ @Override
+ public void setAbi(IAbi abi) {
+ mAbi = abi;
+ }
+
+ @Override
+ public void setBuild(IBuildInfo buildInfo) {
+ mCtsBuild = CtsBuildHelper.createBuildHelper(buildInfo);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ assertNotNull(mAbi);
+ assertNotNull(mCtsBuild);
+
+ getDevice().uninstallPackage(PKG);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+
+ getDevice().uninstallPackage(PKG);
+ }
+
+ public void testSingleBase() throws Exception {
+ new InstallMultiple().addApk(APK).run();
+ runDeviceTests(PKG, ".SplitAppTest", "testSingleBase");
+ }
+
+ public void testDensitySingle() throws Exception {
+ new InstallMultiple().addApk(APK).addApk(APK_mdpi).run();
+ runDeviceTests(PKG, ".SplitAppTest", "testDensitySingle");
+ }
+
+ public void testDensityAll() throws Exception {
+ new InstallMultiple().addApk(APK).addApk(APK_mdpi).addApk(APK_hdpi).addApk(APK_xhdpi)
+ .addApk(APK_xxhdpi).run();
+ runDeviceTests(PKG, ".SplitAppTest", "testDensityAll");
+ }
+
+ /**
+ * Install first with low-resolution resources, then add a split that offers
+ * higher-resolution resources.
+ */
+ public void testDensityBest() throws Exception {
+ new InstallMultiple().addApk(APK).addApk(APK_mdpi).run();
+ runDeviceTests(PKG, ".SplitAppTest", "testDensityBest1");
+
+ // Now splice in an additional split which offers better resources
+ new InstallMultiple().inheritFrom(PKG).addApk(APK_xxhdpi).run();
+ runDeviceTests(PKG, ".SplitAppTest", "testDensityBest2");
+ }
+
+ /**
+ * Verify that an API-based split can change enabled/disabled state of
+ * manifest elements.
+ */
+ public void testApi() throws Exception {
+ new InstallMultiple().addApk(APK).addApk(APK_v7).run();
+ runDeviceTests(PKG, ".SplitAppTest", "testApi");
+ }
+
+ public void testLocale() throws Exception {
+ new InstallMultiple().addApk(APK).addApk(APK_de).addApk(APK_fr).run();
+ runDeviceTests(PKG, ".SplitAppTest", "testLocale");
+ }
+
+ /**
+ * Install test app with <em>single</em> split that exactly matches the
+ * currently active ABI. This also explicitly forces ABI when installing.
+ */
+ public void testNativeSingle() throws Exception {
+ final String abi = mAbi.getName();
+ final String apk = ABI_TO_APK.get(abi);
+ assertNotNull("Failed to find APK for ABI " + abi, apk);
+
+ new InstallMultiple().addApk(APK).addApk(apk).run();
+ runDeviceTests(PKG, ".SplitAppTest", "testNative");
+ }
+
+ /**
+ * Install test app with <em>single</em> split that exactly matches the
+ * currently active ABI. This variant <em>does not</em> force the ABI when
+ * installing, instead exercising the system's ability to choose the ABI
+ * through inspection of the installed app.
+ */
+ public void testNativeSingleNatural() throws Exception {
+ final String abi = mAbi.getName();
+ final String apk = ABI_TO_APK.get(abi);
+ assertNotNull("Failed to find APK for ABI " + abi, apk);
+
+ new InstallMultiple().useNaturalAbi().addApk(APK).addApk(apk).run();
+ runDeviceTests(PKG, ".SplitAppTest", "testNative");
+ }
+
+ /**
+ * Install test app with <em>all</em> possible ABI splits. This also
+ * explicitly forces ABI when installing.
+ */
+ public void testNativeAll() throws Exception {
+ final InstallMultiple inst = new InstallMultiple().addApk(APK);
+ for (String apk : ABI_TO_APK.values()) {
+ inst.addApk(apk);
+ }
+ inst.run();
+ runDeviceTests(PKG, ".SplitAppTest", "testNative");
+ }
+
+ /**
+ * Install test app with <em>all</em> possible ABI splits. This variant
+ * <em>does not</em> force the ABI when installing, instead exercising the
+ * system's ability to choose the ABI through inspection of the installed
+ * app.
+ */
+ public void testNativeAllNatural() throws Exception {
+ final InstallMultiple inst = new InstallMultiple().useNaturalAbi().addApk(APK);
+ for (String apk : ABI_TO_APK.values()) {
+ inst.addApk(apk);
+ }
+ inst.run();
+ runDeviceTests(PKG, ".SplitAppTest", "testNative");
+ }
+
+ public void testDuplicateBase() throws Exception {
+ new InstallMultiple().addApk(APK).addApk(APK).runExpectingFailure();
+ }
+
+ public void testDuplicateSplit() throws Exception {
+ new InstallMultiple().addApk(APK).addApk(APK_v7).addApk(APK_v7).runExpectingFailure();
+ }
+
+ public void testDiffCert() throws Exception {
+ new InstallMultiple().addApk(APK).addApk(APK_DIFF_CERT_v7).runExpectingFailure();
+ }
+
+ public void testDiffCertInherit() throws Exception {
+ new InstallMultiple().addApk(APK).run();
+ // TODO: remove this once we fix 17900178
+ runDeviceTests(PKG, ".SplitAppTest", "testSingleBase");
+ new InstallMultiple().inheritFrom(PKG).addApk(APK_DIFF_CERT_v7).runExpectingFailure();
+ }
+
+ public void testDiffVersion() throws Exception {
+ new InstallMultiple().addApk(APK).addApk(APK_DIFF_VERSION_v7).runExpectingFailure();
+ }
+
+ public void testDiffVersionInherit() throws Exception {
+ new InstallMultiple().addApk(APK).run();
+ // TODO: remove this once we fix 17900178
+ runDeviceTests(PKG, ".SplitAppTest", "testSingleBase");
+ new InstallMultiple().inheritFrom(PKG).addApk(APK_DIFF_VERSION_v7).runExpectingFailure();
+ }
+
+ public void testFeatureBase() throws Exception {
+ new InstallMultiple().addApk(APK).addApk(APK_FEATURE).run();
+ runDeviceTests(PKG, ".SplitAppTest", "testFeatureBase");
+ }
+
+ public void testFeatureApi() throws Exception {
+ new InstallMultiple().addApk(APK).addApk(APK_FEATURE).addApk(APK_FEATURE_v7).run();
+ runDeviceTests(PKG, ".SplitAppTest", "testFeatureApi");
+ }
+
+ public void testInheritUpdatedBase() throws Exception {
+ // TODO: flesh out this test
+ }
+
+ public void testInheritUpdatedSplit() throws Exception {
+ // TODO: flesh out this test
+ }
+
+ class InstallMultiple {
+ private List<String> mArgs = new ArrayList<>();
+ private List<File> mApks = new ArrayList<>();
+ private boolean mUseNaturalAbi;
+
+ InstallMultiple addArg(String arg) {
+ mArgs.add(arg);
+ return this;
+ }
+
+ InstallMultiple addApk(String apk) throws FileNotFoundException {
+ mApks.add(mCtsBuild.getTestApp(apk));
+ return this;
+ }
+
+ InstallMultiple inheritFrom(String packageName) {
+ addArg("-r");
+ addArg("-p " + packageName);
+ return this;
+ }
+
+ InstallMultiple useNaturalAbi() {
+ mUseNaturalAbi = true;
+ return this;
+ }
+
+ void run() throws DeviceNotAvailableException {
+ run(true);
+ }
+
+ void runExpectingFailure() throws DeviceNotAvailableException {
+ run(false);
+ }
+
+ private void run(boolean expectingSuccess) throws DeviceNotAvailableException {
+ final ITestDevice device = getDevice();
+
+ // Create an install session
+ final StringBuilder cmd = new StringBuilder();
+ cmd.append("pm install-create");
+ for (String arg : mArgs) {
+ cmd.append(' ').append(arg);
+ }
+ if (!mUseNaturalAbi) {
+ cmd.append(' ').append(AbiUtils.createAbiFlag(mAbi.getName()));
+ }
+
+ String result = device.executeShellCommand(cmd.toString());
+ assertTrue(result, result.startsWith("Success"));
+
+ final int start = result.lastIndexOf("[");
+ final int end = result.lastIndexOf("]");
+ int sessionId = -1;
+ try {
+ if (start != -1 && end != -1 && start < end) {
+ sessionId = Integer.parseInt(result.substring(start + 1, end));
+ }
+ } catch (NumberFormatException e) {
+ }
+ if (sessionId == -1) {
+ throw new IllegalStateException("Failed to create install session: " + result);
+ }
+
+ // Push our files into session. Ideally we'd use stdin streaming,
+ // but ddmlib doesn't support it yet.
+ for (int i = 0; i < mApks.size(); i++) {
+ final File apk = mApks.get(i);
+ final String remotePath = "/data/local/tmp/" + i + "_" + apk.getName();
+ if (!device.pushFile(apk, remotePath)) {
+ throw new IllegalStateException("Failed to push " + apk);
+ }
+
+ cmd.setLength(0);
+ cmd.append("pm install-write");
+ cmd.append(' ').append(sessionId);
+ cmd.append(' ').append(i + "_" + apk.getName());
+ cmd.append(' ').append(remotePath);
+
+ result = device.executeShellCommand(cmd.toString());
+ assertTrue(result, result.startsWith("Success"));
+ }
+
+ // Everything staged; let's pull trigger
+ cmd.setLength(0);
+ cmd.append("pm install-commit");
+ cmd.append(' ').append(sessionId);
+
+ result = device.executeShellCommand(cmd.toString());
+ if (expectingSuccess) {
+ assertTrue(result, result.startsWith("Success"));
+ } else {
+ assertFalse(result, result.startsWith("Success"));
+ }
+ }
+ }
+
+ public void runDeviceTests(String packageName) throws DeviceNotAvailableException {
+ runDeviceTests(packageName, null, null);
+ }
+
+ public void runDeviceTests(String packageName, String testClassName, String testMethodName)
+ throws DeviceNotAvailableException {
+ if (testClassName != null && testClassName.startsWith(".")) {
+ testClassName = packageName + testClassName;
+ }
+
+ RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(packageName,
+ "android.support.test.runner.AndroidJUnitRunner", getDevice().getIDevice());
+ if (testClassName != null && testMethodName != null) {
+ testRunner.setMethodName(testClassName, testMethodName);
+ }
+
+ final CollectingTestListener listener = new CollectingTestListener();
+ getDevice().runInstrumentationTests(testRunner, listener);
+
+ final TestRunResult result = listener.getCurrentRunResults();
+ if (result.isRunFailure()) {
+ fail("Failed to successfully run device tests for " + result.getName() + ": "
+ + result.getRunFailureMessage());
+ }
+
+ if (result.hasFailedTests()) {
+ // build a meaningful error message
+ StringBuilder errorBuilder = new StringBuilder("on-device tests failed:\n");
+ for (Map.Entry<TestIdentifier, TestResult> resultEntry :
+ result.getTestResults().entrySet()) {
+ if (!resultEntry.getValue().getStatus().equals(TestStatus.PASSED)) {
+ errorBuilder.append(resultEntry.getKey().toString());
+ errorBuilder.append(":\n");
+ errorBuilder.append(resultEntry.getValue().getStackTrace());
+ }
+ }
+ fail(errorBuilder.toString());
+ }
+ }
+}
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/Android.mk b/hostsidetests/appsecurity/test-apps/SplitApp/Android.mk
new file mode 100644
index 0000000..bc3acaf
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/Android.mk
@@ -0,0 +1,89 @@
+#
+# Copyright (C) 2014 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_TAGS := tests
+LOCAL_SDK_VERSION := current
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsSplitApp
+LOCAL_PACKAGE_SPLITS := mdpi-v4 hdpi-v4 xhdpi-v4 xxhdpi-v4 v7 fr de
+
+LOCAL_ASSET_DIR := $(LOCAL_PATH)/assets
+
+LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
+LOCAL_AAPT_FLAGS := --version-code 100 --version-name OneHundred --replace-version -c mdpi
+
+LOCAL_PROGUARD_ENABLED := disabled
+LOCAL_DEX_PREOPT := false
+
+include $(BUILD_PACKAGE)
+
+
+################################################
+# Define a variant with a different version code
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_SDK_VERSION := current
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsSplitAppDiffVersion
+LOCAL_PACKAGE_SPLITS := v7
+
+LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
+LOCAL_AAPT_FLAGS := --version-code 101 --version-name OneHundredOne --replace-version -c mdpi
+
+LOCAL_PROGUARD_ENABLED := disabled
+LOCAL_DEX_PREOPT := false
+
+include $(BUILD_PACKAGE)
+
+
+################################################
+# Define a variant with a different signature
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_SDK_VERSION := current
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsSplitAppDiffCert
+LOCAL_PACKAGE_SPLITS := v7
+
+LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey2
+LOCAL_AAPT_FLAGS := --version-code 100 --version-name OneHundred --replace-version -c mdpi
+
+LOCAL_PROGUARD_ENABLED := disabled
+LOCAL_DEX_PREOPT := false
+
+include $(BUILD_PACKAGE)
+
+
+ifeq (,$(ONE_SHOT_MAKEFILE))
+include $(LOCAL_PATH)/libs/Android.mk $(LOCAL_PATH)/feature/Android.mk
+endif
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/SplitApp/AndroidManifest.xml
new file mode 100644
index 0000000..dba384c
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/AndroidManifest.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.cts.splitapp">
+
+ <uses-permission android:name="android.permission.CAMERA" />
+
+ <application android:label="SplitApp">
+ <activity android:name=".MyActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ <meta-data android:name="android.service.wallpaper" android:resource="@xml/my_activity_meta" />
+ </activity>
+ <receiver android:name=".MyReceiver"
+ android:enabled="@bool/my_receiver_enabled">
+ <intent-filter>
+ <action android:name="android.intent.action.DATE_CHANGED" />
+ </intent-filter>
+ </receiver>
+
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+ android:targetPackage="com.android.cts.splitapp" />
+
+</manifest>
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/NativeTemplate.mk b/hostsidetests/appsecurity/test-apps/SplitApp/NativeTemplate.mk
new file mode 100644
index 0000000..b61c5d6
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/NativeTemplate.mk
@@ -0,0 +1,28 @@
+#
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsSplitApp_ARCHARCH
+
+LOCAL_JAVA_RESOURCE_DIRS := raw
+
+LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
+LOCAL_AAPT_FLAGS := --version-code 100 --replace-version
+
+include $(BUILD_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/README b/hostsidetests/appsecurity/test-apps/SplitApp/README
new file mode 100644
index 0000000..480289e
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/README
@@ -0,0 +1,7 @@
+
+The entire libs/ directory is built and constructed automatically with
+the build_libs.sh script. Don't attempt to modify manually. To rebuild
+the native code, make the following change to the NDK to pass through
+the target architecture, and then run build_libs.sh:
+
+build/core/build-binary.mk:LOCAL_CFLAGS := -DANDROID -D__ANDROID_ARCH__=\"$(TARGET_ARCH_ABI)\" $(LOCAL_CFLAGS)
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/assets/dir/dirfile1.txt b/hostsidetests/appsecurity/test-apps/SplitApp/assets/dir/dirfile1.txt
new file mode 100644
index 0000000..8fba750
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/assets/dir/dirfile1.txt
@@ -0,0 +1 @@
+DIRFILE1
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/assets/file1.txt b/hostsidetests/appsecurity/test-apps/SplitApp/assets/file1.txt
new file mode 100644
index 0000000..cb4ee5e
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/assets/file1.txt
@@ -0,0 +1 @@
+FILE1
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/build_libs.sh b/hostsidetests/appsecurity/test-apps/SplitApp/build_libs.sh
new file mode 100755
index 0000000..6090374
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/build_libs.sh
@@ -0,0 +1,51 @@
+#!/bin/bash
+#
+# Copyright (C) 2014 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.
+#
+
+NDK_BUILD="$HOME/android-ndk-r10b/ndk-build"
+
+# Go build everything
+rm -rf libs
+cd jni/
+$NDK_BUILD clean
+$NDK_BUILD
+cd ../
+
+for arch in `ls libs/`;
+do
+ (
+ mkdir -p tmp/$arch/raw/lib/$arch/
+ mv libs/$arch/* tmp/$arch/raw/lib/$arch/
+
+ echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>
+<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"
+ package=\"com.android.cts.splitapp\"
+ split=\"lib_${arch//[^a-zA-Z0-9_]/_}\">
+ <application android:hasCode=\"false\" />
+</manifest>" > tmp/$arch/AndroidManifest.xml
+
+ cp NativeTemplate.mk tmp/$arch/Android.mk
+ sed -i -r "s/ARCHARCH/$arch/" tmp/$arch/Android.mk
+
+ )
+done
+
+echo "include \$(call all-subdir-makefiles)" > tmp/Android.mk
+
+rm -rf libs
+rm -rf obj
+
+mv tmp libs
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/feature/Android.mk b/hostsidetests/appsecurity/test-apps/SplitApp/feature/Android.mk
new file mode 100644
index 0000000..9965f60
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/feature/Android.mk
@@ -0,0 +1,38 @@
+#
+# Copyright (C) 2014 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_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_PACKAGE_NAME := CtsSplitAppFeature
+LOCAL_PACKAGE_SPLITS := v7
+
+LOCAL_ASSET_DIR := $(LOCAL_PATH)/assets
+
+LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
+LOCAL_AAPT_FLAGS := --version-code 100 --version-name OneHundred --replace-version -c mdpi
+
+LOCAL_MODULE_TAGS := tests
+
+featureOf := CtsSplitApp
+featureOfApk := $(call intermediates-dir-for,APPS,$(featureOf))/package.apk
+localRStamp := $(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME),,COMMON)/src/R.stamp
+$(localRStamp): $(featureOfApk)
+
+LOCAL_AAPT_FLAGS += --feature-of $(featureOfApk)
+
+include $(BUILD_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/feature/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/SplitApp/feature/AndroidManifest.xml
new file mode 100644
index 0000000..8ba3c2f
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/feature/AndroidManifest.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.cts.splitapp"
+ featureName="feature">
+
+ <!-- New permission should be ignored -->
+ <uses-permission android:name="android.permission.INTERNET" />
+
+ <!-- New application flag should be ignored -->
+ <application android:largeHeap="true">
+ <activity android:name=".FeatureActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ <meta-data android:name="android.service.wallpaper" android:resource="@xml/my_activity_meta" />
+ </activity>
+ <receiver android:name=".FeatureReceiver"
+ android:enabled="@bool/feature_receiver_enabled">
+ <intent-filter>
+ <action android:name="android.intent.action.DATE_CHANGED" />
+ </intent-filter>
+ </receiver>
+ <service android:name=".FeatureService">
+ <intent-filter>
+ <action android:name="com.android.cts.splitapp.service" />
+ </intent-filter>
+ </service>
+ <provider android:name=".FeatureProvider" android:authorities="com.android.cts.splitapp.provider" />
+ </application>
+</manifest>
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/feature/assets/dir/dirfile2.txt b/hostsidetests/appsecurity/test-apps/SplitApp/feature/assets/dir/dirfile2.txt
new file mode 100644
index 0000000..c4a2fff
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/feature/assets/dir/dirfile2.txt
@@ -0,0 +1 @@
+DIRFILE2
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/feature/assets/file2.txt b/hostsidetests/appsecurity/test-apps/SplitApp/feature/assets/file2.txt
new file mode 100644
index 0000000..d77231c
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/feature/assets/file2.txt
@@ -0,0 +1 @@
+FILE2
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/feature/res/values-v7/values.xml b/hostsidetests/appsecurity/test-apps/SplitApp/feature/res/values-v7/values.xml
new file mode 100644
index 0000000..8d91234
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/feature/res/values-v7/values.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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>
+ <bool name="feature_receiver_enabled">false</bool>
+ <integer name="feature_integer">321</integer>
+</resources>
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/feature/res/values/values.xml b/hostsidetests/appsecurity/test-apps/SplitApp/feature/res/values/values.xml
new file mode 100644
index 0000000..7d670cf
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/feature/res/values/values.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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>
+ <bool name="feature_receiver_enabled">true</bool>
+ <string name="feature_string">red</string>
+ <integer name="feature_integer">123</integer>
+</resources>
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/feature/src/com/android/cts/splitapp/FeatureActivity.java b/hostsidetests/appsecurity/test-apps/SplitApp/feature/src/com/android/cts/splitapp/FeatureActivity.java
new file mode 100644
index 0000000..a4df004
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/feature/src/com/android/cts/splitapp/FeatureActivity.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2014 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.splitapp;
+
+import android.app.Activity;
+
+public class FeatureActivity extends Activity {
+}
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/feature/src/com/android/cts/splitapp/FeatureLogic.java b/hostsidetests/appsecurity/test-apps/SplitApp/feature/src/com/android/cts/splitapp/FeatureLogic.java
new file mode 100644
index 0000000..0481546
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/feature/src/com/android/cts/splitapp/FeatureLogic.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2014 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.splitapp;
+
+import android.util.Log;
+
+public class FeatureLogic {
+ private static final String TAG = "FeatureLogic";
+
+ public static int mult(int a, int b) {
+ Log.d(TAG, "FeatureLogic.mult(" + a + ", " + b + ")");
+ return a * b;
+ }
+}
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/feature/src/com/android/cts/splitapp/FeatureProvider.java b/hostsidetests/appsecurity/test-apps/SplitApp/feature/src/com/android/cts/splitapp/FeatureProvider.java
new file mode 100644
index 0000000..087aeb7
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/feature/src/com/android/cts/splitapp/FeatureProvider.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2014 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.splitapp;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+import android.util.Log;
+
+import java.lang.reflect.Field;
+
+public class FeatureProvider extends ContentProvider {
+ private static final String TAG = "FeatureProvider";
+
+ public static boolean sCreated = false;
+
+ @Override
+ public boolean onCreate() {
+ Log.d(TAG, "FeatureProvider.onCreate()");
+
+ sCreated = true;
+
+ try {
+ // Just reach out and touch
+ final Class<?> test = Class.forName("com.android.cts.splitapp.SplitAppTest");
+ final Field touched = test.getDeclaredField("sFeatureTouched");
+ touched.set(null, true);
+
+ // Also make sure we can read a resource from the base; we just
+ // stash the value we saw over on the test for them to verify.
+ final Class<?> baseR = Class.forName("com.android.cts.splitapp.BaseR");
+ final int stringId = (int) baseR.getDeclaredField("my_string1").get(null);
+ final Field value = test.getDeclaredField("sFeatureValue");
+ value.set(null, getContext().getResources().getString(stringId));
+
+ } catch (Throwable t) {
+ // We're okay if anything above fails, since the test later verifies
+ // that we actually touched the boolean.
+ Log.e(TAG, "Failed to communicate back to base", t);
+ }
+
+ return true;
+ }
+
+ @Override
+ public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+ String sortOrder) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getType(Uri uri) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Uri insert(Uri uri, ContentValues values) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int delete(Uri uri, String selection, String[] selectionArgs) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/feature/src/com/android/cts/splitapp/FeatureR.java b/hostsidetests/appsecurity/test-apps/SplitApp/feature/src/com/android/cts/splitapp/FeatureR.java
new file mode 100644
index 0000000..3dbd83b
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/feature/src/com/android/cts/splitapp/FeatureR.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2014 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.splitapp;
+
+public class FeatureR {
+ public static final int feature_receiver_enabled = R.bool.feature_receiver_enabled;
+ public static final int feature_integer = R.integer.feature_integer;
+ public static final int feature_string = R.string.feature_string;
+}
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/feature/src/com/android/cts/splitapp/FeatureReceiver.java b/hostsidetests/appsecurity/test-apps/SplitApp/feature/src/com/android/cts/splitapp/FeatureReceiver.java
new file mode 100644
index 0000000..49559f3
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/feature/src/com/android/cts/splitapp/FeatureReceiver.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2014 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.splitapp;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+public class FeatureReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // Ignored
+ }
+}
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/feature/src/com/android/cts/splitapp/FeatureService.java b/hostsidetests/appsecurity/test-apps/SplitApp/feature/src/com/android/cts/splitapp/FeatureService.java
new file mode 100644
index 0000000..b07297f
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/feature/src/com/android/cts/splitapp/FeatureService.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2014 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.splitapp;
+
+import android.app.IntentService;
+import android.content.Intent;
+
+public class FeatureService extends IntentService {
+ public FeatureService() {
+ super("Feature1Service");
+ }
+
+ @Override
+ protected void onHandleIntent(Intent intent) {
+ // Ignored
+ }
+}
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/jni/Android.mk b/hostsidetests/appsecurity/test-apps/SplitApp/jni/Android.mk
new file mode 100644
index 0000000..507b13a
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/jni/Android.mk
@@ -0,0 +1,26 @@
+#
+# 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.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libsplitappjni
+LOCAL_SRC_FILES := com_android_cts_splitapp_Native.cpp
+
+LOCAL_LDLIBS += -llog
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/jni/Application.mk b/hostsidetests/appsecurity/test-apps/SplitApp/jni/Application.mk
new file mode 100644
index 0000000..a304c8f
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/jni/Application.mk
@@ -0,0 +1,2 @@
+APP_ABI := all
+APP_PLATFORM := android-10
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/jni/com_android_cts_splitapp_Native.cpp b/hostsidetests/appsecurity/test-apps/SplitApp/jni/com_android_cts_splitapp_Native.cpp
new file mode 100644
index 0000000..01302f5
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/jni/com_android_cts_splitapp_Native.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#define LOG_TAG "SplitApp"
+
+#include <android/log.h>
+#include <stdio.h>
+
+#include "jni.h"
+
+#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
+#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
+
+
+static jint add(JNIEnv *env, jobject thiz, jint a, jint b) {
+ int result = a + b;
+ LOGI("%d + %d = %d", a, b, result);
+ return result;
+}
+
+static jstring arch(JNIEnv *env, jobject thiz) {
+ return env->NewStringUTF(__ANDROID_ARCH__);
+}
+
+static const char *classPathName = "com/android/cts/splitapp/Native";
+
+static JNINativeMethod methods[] = {
+ {"add", "(II)I", (void*)add },
+ {"arch", "()Ljava/lang/String;", (void*)arch },
+};
+
+static int registerNativeMethods(JNIEnv* env, const char* className, JNINativeMethod* gMethods, int numMethods) {
+ jclass clazz;
+
+ clazz = env->FindClass(className);
+ if (clazz == NULL) {
+ LOGE("Native registration unable to find class '%s'", className);
+ return JNI_FALSE;
+ }
+ if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) {
+ LOGE("RegisterNatives failed for '%s'", className);
+ return JNI_FALSE;
+ }
+
+ return JNI_TRUE;
+}
+
+static int registerNatives(JNIEnv* env) {
+ if (!registerNativeMethods(env, classPathName, methods, sizeof(methods) / sizeof(methods[0]))) {
+ return JNI_FALSE;
+ }
+
+ return JNI_TRUE;
+}
+
+typedef union {
+ JNIEnv* env;
+ void* venv;
+} UnionJNIEnvToVoid;
+
+jint JNI_OnLoad(JavaVM* vm, void* reserved) {
+ UnionJNIEnvToVoid uenv;
+ uenv.venv = NULL;
+ jint result = -1;
+ JNIEnv* env = NULL;
+
+ LOGI("JNI_OnLoad");
+
+ if (vm->GetEnv(&uenv.venv, JNI_VERSION_1_4) != JNI_OK) {
+ LOGE("ERROR: GetEnv failed");
+ goto bail;
+ }
+ env = uenv.env;
+
+ if (registerNatives(env) != JNI_TRUE) {
+ LOGE("ERROR: registerNatives failed");
+ goto bail;
+ }
+
+ result = JNI_VERSION_1_4;
+
+bail:
+ return result;
+}
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/libs/Android.mk b/hostsidetests/appsecurity/test-apps/SplitApp/libs/Android.mk
new file mode 100644
index 0000000..5053e7d
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/libs/Android.mk
@@ -0,0 +1 @@
+include $(call all-subdir-makefiles)
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/libs/arm64-v8a/Android.mk b/hostsidetests/appsecurity/test-apps/SplitApp/libs/arm64-v8a/Android.mk
new file mode 100644
index 0000000..543e4ac
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/libs/arm64-v8a/Android.mk
@@ -0,0 +1,28 @@
+#
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsSplitApp_arm64-v8a
+
+LOCAL_JAVA_RESOURCE_DIRS := raw
+
+LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
+LOCAL_AAPT_FLAGS := --version-code 100 --replace-version
+
+include $(BUILD_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/libs/arm64-v8a/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/SplitApp/libs/arm64-v8a/AndroidManifest.xml
new file mode 100644
index 0000000..206e207
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/libs/arm64-v8a/AndroidManifest.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.cts.splitapp"
+ split="lib_arm64_v8a">
+ <application android:hasCode="false" />
+</manifest>
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/libs/arm64-v8a/raw/lib/arm64-v8a/libsplitappjni.so b/hostsidetests/appsecurity/test-apps/SplitApp/libs/arm64-v8a/raw/lib/arm64-v8a/libsplitappjni.so
new file mode 100755
index 0000000..bcc8f51
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/libs/arm64-v8a/raw/lib/arm64-v8a/libsplitappjni.so
Binary files differ
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/libs/armeabi-v7a/Android.mk b/hostsidetests/appsecurity/test-apps/SplitApp/libs/armeabi-v7a/Android.mk
new file mode 100644
index 0000000..7cdef62
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/libs/armeabi-v7a/Android.mk
@@ -0,0 +1,28 @@
+#
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsSplitApp_armeabi-v7a
+
+LOCAL_JAVA_RESOURCE_DIRS := raw
+
+LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
+LOCAL_AAPT_FLAGS := --version-code 100 --replace-version
+
+include $(BUILD_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/libs/armeabi-v7a/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/SplitApp/libs/armeabi-v7a/AndroidManifest.xml
new file mode 100644
index 0000000..1d19420
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/libs/armeabi-v7a/AndroidManifest.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.cts.splitapp"
+ split="lib_armeabi_v7a">
+ <application android:hasCode="false" />
+</manifest>
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/libs/armeabi-v7a/raw/lib/armeabi-v7a/libsplitappjni.so b/hostsidetests/appsecurity/test-apps/SplitApp/libs/armeabi-v7a/raw/lib/armeabi-v7a/libsplitappjni.so
new file mode 100755
index 0000000..010c372
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/libs/armeabi-v7a/raw/lib/armeabi-v7a/libsplitappjni.so
Binary files differ
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/libs/armeabi/Android.mk b/hostsidetests/appsecurity/test-apps/SplitApp/libs/armeabi/Android.mk
new file mode 100644
index 0000000..26ec5bd
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/libs/armeabi/Android.mk
@@ -0,0 +1,28 @@
+#
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsSplitApp_armeabi
+
+LOCAL_JAVA_RESOURCE_DIRS := raw
+
+LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
+LOCAL_AAPT_FLAGS := --version-code 100 --replace-version
+
+include $(BUILD_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/libs/armeabi/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/SplitApp/libs/armeabi/AndroidManifest.xml
new file mode 100644
index 0000000..95fdb23
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/libs/armeabi/AndroidManifest.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.cts.splitapp"
+ split="lib_armeabi">
+ <application android:hasCode="false" />
+</manifest>
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/libs/armeabi/raw/lib/armeabi/libsplitappjni.so b/hostsidetests/appsecurity/test-apps/SplitApp/libs/armeabi/raw/lib/armeabi/libsplitappjni.so
new file mode 100755
index 0000000..8977e70
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/libs/armeabi/raw/lib/armeabi/libsplitappjni.so
Binary files differ
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/libs/mips/Android.mk b/hostsidetests/appsecurity/test-apps/SplitApp/libs/mips/Android.mk
new file mode 100644
index 0000000..fea0603
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/libs/mips/Android.mk
@@ -0,0 +1,28 @@
+#
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsSplitApp_mips
+
+LOCAL_JAVA_RESOURCE_DIRS := raw
+
+LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
+LOCAL_AAPT_FLAGS := --version-code 100 --replace-version
+
+include $(BUILD_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/libs/mips/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/SplitApp/libs/mips/AndroidManifest.xml
new file mode 100644
index 0000000..53ea38f
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/libs/mips/AndroidManifest.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.cts.splitapp"
+ split="lib_mips">
+ <application android:hasCode="false" />
+</manifest>
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/libs/mips/raw/lib/mips/libsplitappjni.so b/hostsidetests/appsecurity/test-apps/SplitApp/libs/mips/raw/lib/mips/libsplitappjni.so
new file mode 100755
index 0000000..45b8382
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/libs/mips/raw/lib/mips/libsplitappjni.so
Binary files differ
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/libs/mips64/Android.mk b/hostsidetests/appsecurity/test-apps/SplitApp/libs/mips64/Android.mk
new file mode 100644
index 0000000..3cc5609
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/libs/mips64/Android.mk
@@ -0,0 +1,28 @@
+#
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsSplitApp_mips64
+
+LOCAL_JAVA_RESOURCE_DIRS := raw
+
+LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
+LOCAL_AAPT_FLAGS := --version-code 100 --replace-version
+
+include $(BUILD_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/libs/mips64/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/SplitApp/libs/mips64/AndroidManifest.xml
new file mode 100644
index 0000000..0b75613
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/libs/mips64/AndroidManifest.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.cts.splitapp"
+ split="lib_mips64">
+ <application android:hasCode="false" />
+</manifest>
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/libs/mips64/raw/lib/mips64/libsplitappjni.so b/hostsidetests/appsecurity/test-apps/SplitApp/libs/mips64/raw/lib/mips64/libsplitappjni.so
new file mode 100755
index 0000000..8c29904
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/libs/mips64/raw/lib/mips64/libsplitappjni.so
Binary files differ
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/libs/x86/Android.mk b/hostsidetests/appsecurity/test-apps/SplitApp/libs/x86/Android.mk
new file mode 100644
index 0000000..d45ca8f
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/libs/x86/Android.mk
@@ -0,0 +1,28 @@
+#
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsSplitApp_x86
+
+LOCAL_JAVA_RESOURCE_DIRS := raw
+
+LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
+LOCAL_AAPT_FLAGS := --version-code 100 --replace-version
+
+include $(BUILD_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/libs/x86/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/SplitApp/libs/x86/AndroidManifest.xml
new file mode 100644
index 0000000..4219791
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/libs/x86/AndroidManifest.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.cts.splitapp"
+ split="lib_x86">
+ <application android:hasCode="false" />
+</manifest>
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/libs/x86/raw/lib/x86/libsplitappjni.so b/hostsidetests/appsecurity/test-apps/SplitApp/libs/x86/raw/lib/x86/libsplitappjni.so
new file mode 100755
index 0000000..2993d92
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/libs/x86/raw/lib/x86/libsplitappjni.so
Binary files differ
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/libs/x86_64/Android.mk b/hostsidetests/appsecurity/test-apps/SplitApp/libs/x86_64/Android.mk
new file mode 100644
index 0000000..fa0e488
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/libs/x86_64/Android.mk
@@ -0,0 +1,28 @@
+#
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsSplitApp_x86_64
+
+LOCAL_JAVA_RESOURCE_DIRS := raw
+
+LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
+LOCAL_AAPT_FLAGS := --version-code 100 --replace-version
+
+include $(BUILD_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/libs/x86_64/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/SplitApp/libs/x86_64/AndroidManifest.xml
new file mode 100644
index 0000000..e697d5c
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/libs/x86_64/AndroidManifest.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.cts.splitapp"
+ split="lib_x86_64">
+ <application android:hasCode="false" />
+</manifest>
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/libs/x86_64/raw/lib/x86_64/libsplitappjni.so b/hostsidetests/appsecurity/test-apps/SplitApp/libs/x86_64/raw/lib/x86_64/libsplitappjni.so
new file mode 100755
index 0000000..23f4169
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/libs/x86_64/raw/lib/x86_64/libsplitappjni.so
Binary files differ
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/res/drawable-hdpi/image.png b/hostsidetests/appsecurity/test-apps/SplitApp/res/drawable-hdpi/image.png
new file mode 100644
index 0000000..b5f1a13
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/res/drawable-hdpi/image.png
Binary files differ
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/res/drawable-mdpi/image.png b/hostsidetests/appsecurity/test-apps/SplitApp/res/drawable-mdpi/image.png
new file mode 100644
index 0000000..2d67c8f
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/res/drawable-mdpi/image.png
Binary files differ
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/res/drawable-xhdpi/image.png b/hostsidetests/appsecurity/test-apps/SplitApp/res/drawable-xhdpi/image.png
new file mode 100644
index 0000000..2540371
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/res/drawable-xhdpi/image.png
Binary files differ
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/res/drawable-xxhdpi/image.png b/hostsidetests/appsecurity/test-apps/SplitApp/res/drawable-xxhdpi/image.png
new file mode 100644
index 0000000..18a3443
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/res/drawable-xxhdpi/image.png
Binary files differ
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/res/values-de/values.xml b/hostsidetests/appsecurity/test-apps/SplitApp/res/values-de/values.xml
new file mode 100644
index 0000000..88b6f84
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/res/values-de/values.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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>
+ <string name="my_string1">blau</string>
+</resources>
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/res/values-fr/values.xml b/hostsidetests/appsecurity/test-apps/SplitApp/res/values-fr/values.xml
new file mode 100644
index 0000000..c372f6a
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/res/values-fr/values.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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>
+ <string name="my_string2">pourpre</string>
+</resources>
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/res/values-sw600dp/values.xml b/hostsidetests/appsecurity/test-apps/SplitApp/res/values-sw600dp/values.xml
new file mode 100644
index 0000000..edf4525
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/res/values-sw600dp/values.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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="my_dimen">46dp</dimen>
+</resources>
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/res/values-v7/values.xml b/hostsidetests/appsecurity/test-apps/SplitApp/res/values-v7/values.xml
new file mode 100644
index 0000000..d0a0db9
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/res/values-v7/values.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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>
+ <bool name="my_receiver_enabled">true</bool>
+</resources>
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/res/values/values.xml b/hostsidetests/appsecurity/test-apps/SplitApp/res/values/values.xml
new file mode 100644
index 0000000..3118fde
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/res/values/values.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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>
+ <bool name="my_receiver_enabled">false</bool>
+
+ <string name="my_string1">blue</string>
+ <string name="my_string2">purple</string>
+
+ <string-array name="my_string_array">
+ <item>@string/my_string1</item>
+ <item>@string/my_string2</item>
+ </string-array>
+
+ <color name="my_color">#00FF00</color>
+ <dimen name="my_dimen">23dp</dimen>
+ <integer name="my_integer">123</integer>
+</resources>
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/res/xml-v7/my_activity_meta.xml b/hostsidetests/appsecurity/test-apps/SplitApp/res/xml-v7/my_activity_meta.xml
new file mode 100644
index 0000000..50cb6ec
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/res/xml-v7/my_activity_meta.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<tag value="v7" />
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/res/xml/my_activity_meta.xml b/hostsidetests/appsecurity/test-apps/SplitApp/res/xml/my_activity_meta.xml
new file mode 100644
index 0000000..58f2a6a
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/res/xml/my_activity_meta.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<tag value="base" />
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/BaseActivity.java b/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/BaseActivity.java
new file mode 100644
index 0000000..efd1843
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/BaseActivity.java
@@ -0,0 +1,33 @@
+/*
+ * 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 com.android.cts.splitapp;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.TextView;
+
+public class BaseActivity extends Activity {
+ /** Called when the activity is first created. */
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ TextView tv = new TextView(this);
+ int sum = Native.add(2, 3);
+ tv.setText("2 + 3 = " + Integer.toString(sum));
+ setContentView(tv);
+ }
+}
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/BaseR.java b/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/BaseR.java
new file mode 100644
index 0000000..ecf6975
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/BaseR.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2014 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.splitapp;
+
+public class BaseR {
+ public static final int my_string1 = R.string.my_string1;
+}
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/Native.java b/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/Native.java
new file mode 100644
index 0000000..080053a
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/Native.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2014 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.splitapp;
+
+public class Native {
+ static {
+ System.loadLibrary("splitappjni");
+ }
+
+ public static native int add(int a, int b);
+ public static native String arch();
+}
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/SplitAppTest.java b/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/SplitAppTest.java
new file mode 100644
index 0000000..277a1a2
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/SplitAppTest.java
@@ -0,0 +1,358 @@
+/*
+ * Copyright (C) 2014 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.splitapp;
+
+import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
+import static org.xmlpull.v1.XmlPullParser.START_TAG;
+
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ProviderInfo;
+import android.content.pm.ResolveInfo;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.drawable.Drawable;
+import android.test.AndroidTestCase;
+import android.util.DisplayMetrics;
+import android.util.Log;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.Locale;
+
+public class SplitAppTest extends AndroidTestCase {
+ private static final String TAG = "SplitAppTest";
+ private static final String PKG = "com.android.cts.splitapp";
+
+ public static boolean sFeatureTouched = false;
+ public static String sFeatureValue = null;
+
+ public void testSingleBase() throws Exception {
+ final Resources r = getContext().getResources();
+ final PackageManager pm = getContext().getPackageManager();
+
+ // Should have untouched resources from base
+ assertEquals(false, r.getBoolean(R.bool.my_receiver_enabled));
+
+ assertEquals("blue", r.getString(R.string.my_string1));
+ assertEquals("purple", r.getString(R.string.my_string2));
+
+ assertEquals(0xff00ff00, r.getColor(R.color.my_color));
+ assertEquals(123, r.getInteger(R.integer.my_integer));
+
+ assertEquals("base", getXmlTestValue(r.getXml(R.xml.my_activity_meta)));
+
+ // We know about drawable IDs, but they're stripped from base
+ try {
+ r.getDrawable(R.drawable.image);
+ fail("Unexpected drawable in base");
+ } catch (Resources.NotFoundException expected) {
+ }
+
+ // Should have base assets
+ assertAssetContents(r, "file1.txt", "FILE1");
+ assertAssetContents(r, "dir/dirfile1.txt", "DIRFILE1");
+
+ try {
+ assertAssetContents(r, "file2.txt", null);
+ fail("Unexpected asset file2");
+ } catch (IOException expected) {
+ }
+
+ // Should only have base manifest items
+ Intent intent = new Intent(Intent.ACTION_MAIN);
+ intent.addCategory(Intent.CATEGORY_LAUNCHER);
+ intent.setPackage(PKG);
+
+ List<ResolveInfo> result = pm.queryIntentActivities(intent, 0);
+ assertEquals(1, result.size());
+ assertEquals("com.android.cts.splitapp.MyActivity", result.get(0).activityInfo.name);
+
+ // Receiver disabled by default in base
+ intent = new Intent(Intent.ACTION_DATE_CHANGED);
+ intent.setPackage(PKG);
+
+ result = pm.queryBroadcastReceivers(intent, 0);
+ assertEquals(0, result.size());
+
+ // We shouldn't have any native code in base
+ try {
+ Native.add(2, 4);
+ fail("Unexpected native code in base");
+ } catch (UnsatisfiedLinkError expected) {
+ }
+ }
+
+ public void testDensitySingle() throws Exception {
+ final Resources r = getContext().getResources();
+
+ // We should still have base resources
+ assertEquals("blue", r.getString(R.string.my_string1));
+ assertEquals("purple", r.getString(R.string.my_string2));
+
+ // Now we know about drawables, but only mdpi
+ final Drawable d = r.getDrawable(R.drawable.image);
+ assertEquals(0xff7e00ff, getDrawableColor(d));
+ }
+
+ public void testDensityAll() throws Exception {
+ final Resources r = getContext().getResources();
+
+ // We should still have base resources
+ assertEquals("blue", r.getString(R.string.my_string1));
+ assertEquals("purple", r.getString(R.string.my_string2));
+
+ // Pretend that we're at each density
+ updateDpi(r, DisplayMetrics.DENSITY_MEDIUM);
+ assertEquals(0xff7e00ff, getDrawableColor(r.getDrawable(R.drawable.image)));
+
+ updateDpi(r, DisplayMetrics.DENSITY_HIGH);
+ assertEquals(0xff00fcff, getDrawableColor(r.getDrawable(R.drawable.image)));
+
+ updateDpi(r, DisplayMetrics.DENSITY_XHIGH);
+ assertEquals(0xff80ff00, getDrawableColor(r.getDrawable(R.drawable.image)));
+
+ updateDpi(r, DisplayMetrics.DENSITY_XXHIGH);
+ assertEquals(0xffff0000, getDrawableColor(r.getDrawable(R.drawable.image)));
+ }
+
+ public void testDensityBest1() throws Exception {
+ final Resources r = getContext().getResources();
+
+ // Pretend that we're really high density, but we only have mdpi installed
+ updateDpi(r, DisplayMetrics.DENSITY_XXHIGH);
+ assertEquals(0xff7e00ff, getDrawableColor(r.getDrawable(R.drawable.image)));
+ }
+
+ public void testDensityBest2() throws Exception {
+ final Resources r = getContext().getResources();
+
+ // Pretend that we're really high density, and now we have better match
+ updateDpi(r, DisplayMetrics.DENSITY_XXHIGH);
+ assertEquals(0xffff0000, getDrawableColor(r.getDrawable(R.drawable.image)));
+ }
+
+ public void testApi() throws Exception {
+ final Resources r = getContext().getResources();
+ final PackageManager pm = getContext().getPackageManager();
+
+ // We should have updated boolean, different from base
+ assertEquals(true, r.getBoolean(R.bool.my_receiver_enabled));
+
+ // Receiver should be enabled now
+ Intent intent = new Intent(Intent.ACTION_DATE_CHANGED);
+ intent.setPackage(PKG);
+
+ List<ResolveInfo> result = pm.queryBroadcastReceivers(intent, 0);
+ assertEquals(1, result.size());
+ assertEquals("com.android.cts.splitapp.MyReceiver", result.get(0).activityInfo.name);
+ }
+
+ public void testLocale() throws Exception {
+ final Resources r = getContext().getResources();
+
+ updateLocale(r, Locale.ENGLISH);
+ assertEquals("blue", r.getString(R.string.my_string1));
+ assertEquals("purple", r.getString(R.string.my_string2));
+
+ updateLocale(r, Locale.GERMAN);
+ assertEquals("blau", r.getString(R.string.my_string1));
+ assertEquals("purple", r.getString(R.string.my_string2));
+
+ updateLocale(r, Locale.FRENCH);
+ assertEquals("blue", r.getString(R.string.my_string1));
+ assertEquals("pourpre", r.getString(R.string.my_string2));
+ }
+
+ public void testNative() throws Exception {
+ Log.d(TAG, "testNative() thinks it's using ABI " + Native.arch());
+
+ // Make sure we can do the maths
+ assertEquals(11642, Native.add(4933, 6709));
+ }
+
+ public void testFeatureBase() throws Exception {
+ final Resources r = getContext().getResources();
+ final PackageManager pm = getContext().getPackageManager();
+
+ // Should have untouched resources from base
+ assertEquals(false, r.getBoolean(R.bool.my_receiver_enabled));
+
+ assertEquals("blue", r.getString(R.string.my_string1));
+ assertEquals("purple", r.getString(R.string.my_string2));
+
+ assertEquals(0xff00ff00, r.getColor(R.color.my_color));
+ assertEquals(123, r.getInteger(R.integer.my_integer));
+
+ assertEquals("base", getXmlTestValue(r.getXml(R.xml.my_activity_meta)));
+
+ // And that we can access resources from feature
+ // TODO: enable these once 17924027 is fixed
+// assertEquals("red", r.getString(r.getIdentifier("feature_string", "string", PKG)));
+// assertEquals(123, r.getInteger(r.getIdentifier("feature_integer", "integer", PKG)));
+
+ final Class<?> featR = Class.forName("com.android.cts.splitapp.FeatureR");
+ final int boolId = (int) featR.getDeclaredField("feature_receiver_enabled").get(null);
+ final int intId = (int) featR.getDeclaredField("feature_integer").get(null);
+ final int stringId = (int) featR.getDeclaredField("feature_string").get(null);
+ assertEquals(true, r.getBoolean(boolId));
+ assertEquals(123, r.getInteger(intId));
+ assertEquals("red", r.getString(stringId));
+
+ // Should have both base and feature assets
+ assertAssetContents(r, "file1.txt", "FILE1");
+ assertAssetContents(r, "file2.txt", "FILE2");
+ assertAssetContents(r, "dir/dirfile1.txt", "DIRFILE1");
+ assertAssetContents(r, "dir/dirfile2.txt", "DIRFILE2");
+
+ // Should have both base and feature components
+ Intent intent = new Intent(Intent.ACTION_MAIN);
+ intent.addCategory(Intent.CATEGORY_LAUNCHER);
+ intent.setPackage(PKG);
+ List<ResolveInfo> result = pm.queryIntentActivities(intent, 0);
+ assertEquals(2, result.size());
+ assertEquals("com.android.cts.splitapp.MyActivity", result.get(0).activityInfo.name);
+ assertEquals("com.android.cts.splitapp.FeatureActivity", result.get(1).activityInfo.name);
+
+ // Receiver only enabled in feature
+ intent = new Intent(Intent.ACTION_DATE_CHANGED);
+ intent.setPackage(PKG);
+ result = pm.queryBroadcastReceivers(intent, 0);
+ assertEquals(1, result.size());
+ assertEquals("com.android.cts.splitapp.FeatureReceiver", result.get(0).activityInfo.name);
+
+ // And we should have a service
+ intent = new Intent("com.android.cts.splitapp.service");
+ intent.setPackage(PKG);
+ result = pm.queryIntentServices(intent, 0);
+ assertEquals(1, result.size());
+ assertEquals("com.android.cts.splitapp.FeatureService", result.get(0).serviceInfo.name);
+
+ // And a provider too
+ ProviderInfo info = pm.resolveContentProvider("com.android.cts.splitapp.provider", 0);
+ assertEquals("com.android.cts.splitapp.FeatureProvider", info.name);
+
+ // And assert that we spun up the provider in this process
+ final Class<?> provider = Class.forName("com.android.cts.splitapp.FeatureProvider");
+ final Field field = provider.getDeclaredField("sCreated");
+ assertTrue("Expected provider to have been created", (boolean) field.get(null));
+ assertTrue("Expected provider to have touched us", sFeatureTouched);
+ assertEquals(r.getString(R.string.my_string1), sFeatureValue);
+
+ // Finally ensure that we can execute some code from split
+ final Class<?> logic = Class.forName("com.android.cts.splitapp.FeatureLogic");
+ final Method method = logic.getDeclaredMethod("mult", new Class[] {
+ Integer.TYPE, Integer.TYPE });
+ assertEquals(72, (int) method.invoke(null, 12, 6));
+
+ // Make sure we didn't get an extra flag from feature split
+ assertTrue("Someone parsed application flag!",
+ (getContext().getApplicationInfo().flags & ApplicationInfo.FLAG_LARGE_HEAP) == 0);
+
+ // Make sure we have permission from base APK
+ getContext().enforceCallingOrSelfPermission(android.Manifest.permission.CAMERA, null);
+
+ try {
+ // But no new permissions from the feature APK
+ getContext().enforceCallingOrSelfPermission(android.Manifest.permission.INTERNET, null);
+ fail("Whaaa, we somehow gained permission from feature?");
+ } catch (SecurityException expected) {
+ }
+ }
+
+ public void testFeatureApi() throws Exception {
+ final Resources r = getContext().getResources();
+ final PackageManager pm = getContext().getPackageManager();
+
+ // Should have untouched resources from base
+ assertEquals(false, r.getBoolean(R.bool.my_receiver_enabled));
+
+ // And that we can access resources from feature
+ // TODO: enable these once 17924027 is fixed
+// assertEquals(321, r.getInteger(r.getIdentifier("feature_integer", "integer", PKG)));
+
+ final Class<?> featR = Class.forName("com.android.cts.splitapp.FeatureR");
+ final int boolId = (int) featR.getDeclaredField("feature_receiver_enabled").get(null);
+ final int intId = (int) featR.getDeclaredField("feature_integer").get(null);
+ final int stringId = (int) featR.getDeclaredField("feature_string").get(null);
+ assertEquals(false, r.getBoolean(boolId));
+ assertEquals(321, r.getInteger(intId));
+ assertEquals("red", r.getString(stringId));
+
+ // And now both receivers should be disabled
+ Intent intent = new Intent(Intent.ACTION_DATE_CHANGED);
+ intent.setPackage(PKG);
+ List<ResolveInfo> result = pm.queryBroadcastReceivers(intent, 0);
+ assertEquals(0, result.size());
+ }
+
+ private static void updateDpi(Resources r, int densityDpi) {
+ final Configuration c = new Configuration(r.getConfiguration());
+ c.densityDpi = densityDpi;
+ r.updateConfiguration(c, r.getDisplayMetrics());
+ }
+
+ private static void updateLocale(Resources r, Locale locale) {
+ final Configuration c = new Configuration(r.getConfiguration());
+ c.locale = locale;
+ r.updateConfiguration(c, r.getDisplayMetrics());
+ }
+
+ private static int getDrawableColor(Drawable d) {
+ final Bitmap bitmap = Bitmap.createBitmap(d.getIntrinsicWidth(), d.getIntrinsicHeight(),
+ Bitmap.Config.ARGB_8888);
+ final Canvas canvas = new Canvas(bitmap);
+ d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
+ d.draw(canvas);
+ return bitmap.getPixel(0, 0);
+ }
+
+ private static String getXmlTestValue(XmlPullParser in) throws XmlPullParserException,
+ IOException {
+ int type;
+ while ((type = in.next()) != END_DOCUMENT) {
+ if (type == START_TAG) {
+ final String tag = in.getName();
+ if ("tag".equals(tag)) {
+ return in.getAttributeValue(null, "value");
+ }
+ }
+ }
+ return null;
+ }
+
+ private static void assertAssetContents(Resources r, String path, String expected)
+ throws IOException {
+ BufferedReader in = null;
+ try {
+ in = new BufferedReader(new InputStreamReader(r.getAssets().open(path)));
+ assertEquals(expected, in.readLine());
+ } finally {
+ if (in != null) in.close();
+ }
+ }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/LockTaskTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/LockTaskTest.java
index c0ca8e2..42aa847 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/LockTaskTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/LockTaskTest.java
@@ -30,6 +30,9 @@
private static final String TEST_PACKAGE = "com.google.android.example.somepackage";
+ private static final int ACTIVITY_RESUMED_TIMEOUT_MILLIS = 60000; // 60 seconds
+ private static final int ACTIVITY_RUNNING_TIMEOUT_MILLIS = 20000; // 20 seconds
+
/**
* The tests below need to keep detailed track of the state of the activity
* that is started and stopped frequently. To do this it sends a number of
@@ -139,52 +142,49 @@
// This test has the UtilityActivity trigger starting another activity (settings)
// this should be permitted as a part of lock task (since it isn't a new task).
// As a result onPause should be called as it goes to a new activity.
-// TODO: Reinstate once we make this test not flaky (if fails on Nexus 7 v2 most of the time,
-// especially if testCannotStartActivityOutsideTask() is commented out.
-// public void testStartActivityWithinTask() {
-// mDevicePolicyManager.setLockTaskPackages(getWho(), new String[] { PACKAGE_NAME });
-// startLockTask();
-// waitForResume();
-//
-// Intent launchIntent = new Intent(Settings.ACTION_SETTINGS);
-// Intent lockTaskUtility = getLockTaskUtility();
-// lockTaskUtility.putExtra(LockTaskUtilityActivity.START_ACTIVITY, launchIntent);
-// mContext.startActivity(lockTaskUtility);
-//
-// synchronized (mActivityResumedLock) {
-// if (mIsActivityResumed) {
-// try {
-// mActivityResumedLock.wait(60000);
-// } catch (InterruptedException e) {
-// }
-// assertFalse(mIsActivityResumed);
-// }
-// }
-// stopAndFinish(null);
-// }
+ public void testStartActivityWithinTask() {
+ mDevicePolicyManager.setLockTaskPackages(getWho(), new String[] { PACKAGE_NAME });
+ startLockTask();
+ waitForResume();
+
+ Intent launchIntent = new Intent(Settings.ACTION_SETTINGS);
+ Intent lockTaskUtility = getLockTaskUtility();
+ lockTaskUtility.putExtra(LockTaskUtilityActivity.START_ACTIVITY, launchIntent);
+ mContext.startActivity(lockTaskUtility);
+
+ synchronized (mActivityResumedLock) {
+ if (mIsActivityResumed) {
+ try {
+ mActivityResumedLock.wait(ACTIVITY_RESUMED_TIMEOUT_MILLIS);
+ } catch (InterruptedException e) {
+ }
+ assertFalse(mIsActivityResumed);
+ }
+ }
+ stopAndFinish(null);
+ }
// This launches an activity that is not part of the current task and therefore
// should be blocked. This is verified by making sure that the activity does
// not get a call to onPause.
-// TODO: Reinstate once we make this test not flaky (if fails on Nexus 7 v2 most of the time)
-// public void testCannotStartActivityOutsideTask() {
-// mDevicePolicyManager.setLockTaskPackages(getWho(), new String[] { PACKAGE_NAME });
-// startLockTask();
-// waitForResume();
-//
-// Intent launchIntent = new Intent(Settings.ACTION_SETTINGS);
-// launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-// mContext.startActivity(launchIntent);
-//
-// synchronized (mActivityResumedLock) {
-// try {
-// mActivityResumedLock.wait(90000);
-// } catch (InterruptedException e) {
-// }
-// assertTrue(mIsActivityResumed);
-// }
-// stopAndFinish(null);
-// }
+ public void testCannotStartActivityOutsideTask() {
+ mDevicePolicyManager.setLockTaskPackages(getWho(), new String[] { PACKAGE_NAME });
+ startLockTask();
+ waitForResume();
+
+ Intent launchIntent = new Intent(Settings.ACTION_SETTINGS);
+ launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ mContext.startActivity(launchIntent);
+
+ synchronized (mActivityResumedLock) {
+ try {
+ mActivityResumedLock.wait(ACTIVITY_RESUMED_TIMEOUT_MILLIS);
+ } catch (InterruptedException e) {
+ }
+ assertTrue(mIsActivityResumed);
+ }
+ stopAndFinish(null);
+ }
/**
* Call stopLockTask and finish on the LockTaskUtilityActivity.
@@ -212,7 +212,7 @@
finish();
if (mIsActivityRunning) {
try {
- mActivityRunningLock.wait(20000);
+ mActivityRunningLock.wait(ACTIVITY_RUNNING_TIMEOUT_MILLIS);
} catch (InterruptedException e) {
}
}
@@ -227,7 +227,7 @@
synchronized (mActivityResumedLock) {
if (!mIsActivityResumed) {
try {
- mActivityResumedLock.wait(20000);
+ mActivityResumedLock.wait(ACTIVITY_RESUMED_TIMEOUT_MILLIS);
} catch (InterruptedException e) {
}
}
@@ -272,7 +272,7 @@
mContext.startActivity(intent);
// Give 20 secs to finish.
try {
- wait(20000);
+ wait(ACTIVITY_RUNNING_TIMEOUT_MILLIS);
} catch (InterruptedException e) {
}
assertTrue(mIntentHandled);
diff --git a/hostsidetests/devicepolicy/app/IntentReceiver/AndroidManifest.xml b/hostsidetests/devicepolicy/app/IntentReceiver/AndroidManifest.xml
index ab01ffb..e1f6886 100644
--- a/hostsidetests/devicepolicy/app/IntentReceiver/AndroidManifest.xml
+++ b/hostsidetests/devicepolicy/app/IntentReceiver/AndroidManifest.xml
@@ -19,11 +19,14 @@
<uses-sdk android:minSdkVersion="19"/>
+ <uses-permission android:name="com.android.cts.managedprofile.permission.SAMPLE"/>
+
<application>
<activity android:name="com.android.cts.intent.receiver.IntentReceiverActivity">
<intent-filter>
<action android:name="com.android.cts.action.READ_FROM_URI" />
<action android:name="com.android.cts.action.WRITE_TO_URI" />
+ <action android:name="com.android.cts.action.TAKE_PERSISTABLE_URI_PERMISSION" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
diff --git a/hostsidetests/devicepolicy/app/IntentReceiver/src/com/android/cts/intent/receiver/IntentReceiverActivity.java b/hostsidetests/devicepolicy/app/IntentReceiver/src/com/android/cts/intent/receiver/IntentReceiverActivity.java
index 2389402..17dc3f1 100644
--- a/hostsidetests/devicepolicy/app/IntentReceiver/src/com/android/cts/intent/receiver/IntentReceiverActivity.java
+++ b/hostsidetests/devicepolicy/app/IntentReceiver/src/com/android/cts/intent/receiver/IntentReceiverActivity.java
@@ -40,24 +40,48 @@
private static final String ACTION_WRITE_TO_URI = "com.android.cts.action.WRITE_TO_URI";
+ private static final String ACTION_TAKE_PERSISTABLE_URI_PERMISSION =
+ "com.android.cts.action.TAKE_PERSISTABLE_URI_PERMISSION";
+
+ private static final String EXTRA_CAUGHT_SECURITY_EXCEPTION = "extra_caught_security_exception";
+
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent received = getIntent();
String action = received.getAction();
-
+ Uri uri = getIntent().getClipData().getItemAt(0).getUri();
if (ACTION_READ_FROM_URI.equals(action)) {
Intent result = new Intent();
- String message = getFirstLineFromUri(getIntent().getClipData().getItemAt(0).getUri());
- Log.i(TAG, "message received in reading test: " + message);
+ String message = null;
+ try {
+ message = getFirstLineFromUri(uri);
+ } catch (SecurityException e) {
+ Log.i(TAG, "Caught a SecurityException while trying to read " + uri, e);
+ result.putExtra(EXTRA_CAUGHT_SECURITY_EXCEPTION, true);
+ } catch (IOException e) {
+ Log.i(TAG, "Caught a IOException while trying to read " + uri, e);
+ }
+ Log.i(TAG, "Message received in reading test: " + message);
result.putExtra("extra_response", message);
- setResult(message != null ? Activity.RESULT_OK : Activity.RESULT_CANCELED, result);
+ setResult(Activity.RESULT_OK, result);
} else if (ACTION_WRITE_TO_URI.equals(action)) {
Intent result = new Intent();
String message = received.getStringExtra("extra_message");
- Log.i(TAG, "message received in writing test: " + message);
- Uri uri = getIntent().getClipData().getItemAt(0).getUri();
- boolean succeded = writeToUri(uri, message);
- setResult(succeded ? Activity.RESULT_OK : Activity.RESULT_CANCELED);
+ Log.i(TAG, "Message received in writing test: " + message);
+ try {
+ writeToUri(uri, message);
+ } catch (SecurityException e) {
+ Log.i(TAG, "Caught a SecurityException while trying to write to " + uri, e);
+ result.putExtra(EXTRA_CAUGHT_SECURITY_EXCEPTION, true);
+ } catch (IOException e) {
+ Log.i(TAG, "Caught a IOException while trying to write to " + uri, e);
+ }
+ setResult(Activity.RESULT_OK, result);
+ } else if (ACTION_TAKE_PERSISTABLE_URI_PERMISSION.equals(action)) {
+ Log.i(TAG, "Taking persistable uri permission to " + uri);
+ getContentResolver().takePersistableUriPermission(uri,
+ Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ setResult(Activity.RESULT_OK);
}
finish();
}
@@ -65,28 +89,17 @@
/**
* Returns the first line of the file associated with uri.
*/
- private String getFirstLineFromUri(Uri uri) {
- try {
- InputStream is = getContentResolver().openInputStream(uri);
- BufferedReader r = new BufferedReader(new InputStreamReader(is));
- return r.readLine();
- } catch (IOException e) {
- Log.e(TAG, "could not read the uri " + uri, e);
- return null;
- }
+ private String getFirstLineFromUri(Uri uri) throws IOException {
+ InputStream is = getContentResolver().openInputStream(uri);
+ BufferedReader r = new BufferedReader(new InputStreamReader(is));
+ return r.readLine();
}
- private boolean writeToUri(Uri uri, String text) {
- try {
- OutputStreamWriter writer = new OutputStreamWriter(
- getContentResolver().openOutputStream(uri));
- writer.write(text);
- writer.flush();
- writer.close();
- return true;
- } catch (IOException e) {
- Log.e(TAG, "could not write to the uri " + uri, e);
- return false;
- }
+ private void writeToUri(Uri uri, String text) throws IOException {
+ OutputStreamWriter writer = new OutputStreamWriter(
+ getContentResolver().openOutputStream(uri));
+ writer.write(text);
+ writer.flush();
+ writer.close();
}
}
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml b/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml
index 643400b..56b3671 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml
@@ -19,6 +19,9 @@
<uses-sdk android:minSdkVersion="20"/>
+ <permission android:name="com.android.cts.managedprofile.permission.SAMPLE"
+ android:label="Sample Permission"/>
+
<application>
<uses-library android:name="android.test.runner" />
<receiver
@@ -67,6 +70,13 @@
<action android:name="android.intent.action.MAIN"/>
</intent-filter>
</activity>
+ <activity android:name=".UserRestrictionActivity" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.DEFAULT"/>
+ </intent-filter>
+ </activity>
+ <activity android:name=".TestActivity" />
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.android.cts.managedprofile.fileprovider"
@@ -76,7 +86,13 @@
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>
- <activity android:name=".TestActivity" />
+ <provider
+ android:name="com.android.cts.managedprofile.crossprofilecontent.BasicContentProvider"
+ android:authorities="com.android.cts.managedprofile.basiccontentProvider"
+ android:grantUriPermissions="true"
+ android:exported="true"
+ android:permission="com.android.cts.managedprofile.permission.SAMPLE"
+ />
</application>
<instrumentation android:name="android.test.InstrumentationTestRunner"
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/UserRestrictionActivity.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/UserRestrictionActivity.java
new file mode 100644
index 0000000..e8decf8
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/UserRestrictionActivity.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2014 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.managedprofile;
+
+import android.app.Activity;
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Process;
+import android.util.Log;
+
+import com.android.cts.managedprofile.BaseManagedProfileTest;
+
+/**
+ * Simple activity that adds or clears a user restriction depending on the value of the extras.
+ */
+public class UserRestrictionActivity extends Activity {
+
+ private static final String TAG = UserRestrictionActivity.class.getName();
+
+ private static final String EXTRA_RESTRICTION_KEY = "extra-restriction-key";
+ private static final String EXTRA_COMMAND = "extra-command";
+
+ private static final String ADD_COMMAND = "add-restriction";
+ private static final String CLEAR_COMMAND = "clear-restriction";
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ handleIntent(getIntent());
+ }
+
+ // Overriding this method in case another intent is sent to this activity before finish()
+ @Override
+ public void onNewIntent(Intent intent) {
+ super.onNewIntent(intent);
+ handleIntent(intent);
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ // Calling finish() here because doing it in onCreate(), onStart() or onResume() makes
+ // "adb shell am start" timeout if using the -W option.
+ finish();
+ }
+
+ private void handleIntent(Intent intent) {
+ DevicePolicyManager dpm = (DevicePolicyManager)
+ getSystemService(Context.DEVICE_POLICY_SERVICE);
+ String restrictionKey = intent.getStringExtra(EXTRA_RESTRICTION_KEY);
+ String command = intent.getStringExtra(EXTRA_COMMAND);
+ Log.i(TAG, "Command: \"" + command + "\". Restriction: \"" + restrictionKey + "\"");
+
+ if (ADD_COMMAND.equals(command)) {
+ dpm.addUserRestriction(BaseManagedProfileTest.ADMIN_RECEIVER_COMPONENT, restrictionKey);
+ Log.i(TAG, "Added user restriction " + restrictionKey
+ + " for user " + Process.myUserHandle());
+ } else if (CLEAR_COMMAND.equals(command)) {
+ dpm.clearUserRestriction(
+ BaseManagedProfileTest.ADMIN_RECEIVER_COMPONENT, restrictionKey);
+ Log.i(TAG, "Cleared user restriction " + restrictionKey
+ + " for user " + Process.myUserHandle());
+ } else {
+ Log.e(TAG, "Invalid command: " + command);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofilecontent/BasicContentProvider.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofilecontent/BasicContentProvider.java
new file mode 100644
index 0000000..f91d404
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofilecontent/BasicContentProvider.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2012 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.managedprofile.crossprofilecontent;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.ParcelFileDescriptor;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+
+/**
+ * Empty content provider, all permissions are enforced in manifest
+ */
+public class BasicContentProvider extends ContentProvider {
+
+ @Override
+ public int delete(Uri uri, String selection, String[] selectionArgs) {
+ // do nothing
+ return 0;
+ }
+
+ @Override
+ public String getType(Uri uri) {
+ return "";
+ }
+
+ @Override
+ public Uri insert(Uri uri, ContentValues values) {
+ return null;
+ }
+
+ @Override
+ public boolean onCreate() {
+ return false;
+ }
+
+ @Override
+ public Cursor query(Uri uri, String[] projection, String selection,
+ String[] selectionArgs, String sortOrder) {
+ return null;
+ }
+
+ @Override
+ public int update(Uri uri, ContentValues values, String selection,
+ String[] selectionArgs) {
+ return 0;
+ }
+
+ @Override
+ public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
+ return ParcelFileDescriptor.open(
+ new File("/dev/null"), ParcelFileDescriptor.MODE_READ_ONLY);
+ }
+}
+
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofilecontent/CrossProfileContentTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofilecontent/CrossProfileContentTest.java
index aa9506b..85e7d1b 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofilecontent/CrossProfileContentTest.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofilecontent/CrossProfileContentTest.java
@@ -18,33 +18,194 @@
import static com.android.cts.managedprofile.BaseManagedProfileTest.ADMIN_RECEIVER_COMPONENT;
import android.app.admin.DevicePolicyManager;
+import android.content.ClipData;
+import android.content.ContentResolver;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.Uri;
+import android.support.v4.content.FileProvider;
import android.test.ActivityInstrumentationTestCase2;
+import android.util.Log;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.IOException;
public class CrossProfileContentTest extends
ActivityInstrumentationTestCase2<IntentSenderActivity> {
private static final String MESSAGE = "Sample Message";
+ private static final String ACTION_READ_FROM_URI = "com.android.cts.action.READ_FROM_URI";
+
+ private static final String ACTION_WRITE_TO_URI = "com.android.cts.action.WRITE_TO_URI";
+
+ private static final String ACTION_TAKE_PERSISTABLE_URI_PERMISSION =
+ "com.android.cts.action.TAKE_PERSISTABLE_URI_PERMISSION";
+
+ private static final String TAG = "CrossProfileContentTest";
+
+ private static final String BASIC_CONTENT_PROVIDER_AUTHORITY =
+ "com.android.cts.managedprofile.basiccontentProvider";
+
+
+ private DevicePolicyManager mDpm;
+
+ private Context mContext;
+
public CrossProfileContentTest() {
super(IntentSenderActivity.class);
}
@Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mContext = getInstrumentation().getTargetContext();
+ mDpm = (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+ IntentFilter intentFilter = new IntentFilter();
+ intentFilter.addAction(ACTION_READ_FROM_URI);
+ intentFilter.addAction(ACTION_WRITE_TO_URI);
+ intentFilter.addAction(ACTION_TAKE_PERSISTABLE_URI_PERMISSION);
+ mDpm.addCrossProfileIntentFilter(ADMIN_RECEIVER_COMPONENT, intentFilter,
+ DevicePolicyManager.FLAG_PARENT_CAN_ACCESS_MANAGED);
+ }
+
+ @Override
protected void tearDown() throws Exception {
- DevicePolicyManager dpm = (DevicePolicyManager)
- getActivity().getSystemService(Context.DEVICE_POLICY_SERVICE);
- dpm.clearCrossProfileIntentFilters(ADMIN_RECEIVER_COMPONENT);
+ mDpm.clearCrossProfileIntentFilters(ADMIN_RECEIVER_COMPONENT);
super.tearDown();
}
+ /**
+ * This method will send an intent to a receiver in another profile.
+ * This intent will have, in the ClipData, a uri whose associated file stores a message.
+ * The receiver will read the message from the uri, and put it inside the result intent.
+ */
public void testReceiverCanRead() {
- String response = getActivity().testReceiverCanRead(MESSAGE);
- assertEquals(response, MESSAGE);
+ Uri uri = getUriWithTextInFile("reading_test", MESSAGE);
+ assertTrue(uri != null);
+ Intent intent = new Intent(ACTION_READ_FROM_URI);
+ intent.setClipData(ClipData.newRawUri("", uri));
+ intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ Intent result = getActivity().getResultForIntent(intent);
+ assertTrue(result != null);
+ assertEquals(MESSAGE, result.getStringExtra("extra_response"));
}
+ /**
+ * This method will send an intent to a receiver in another profile.
+ * This intent will have a message in an extra, and a uri specified by the ClipData.
+ * The receiver will read the message from the extra, and write it to the uri in
+ * the ClipData.
+ */
public void testReceiverCanWrite() {
- String response = getActivity().testReceiverCanWrite(MESSAGE);
- assertEquals(response, MESSAGE);
+ // It's the receiver of the intent that should write to the uri, not us. So, for now, we
+ // write an empty string.
+ Uri uri = getUriWithTextInFile("writing_test", "");
+ assertTrue(uri != null);
+ Intent intent = new Intent(ACTION_WRITE_TO_URI);
+ intent.setClipData(ClipData.newRawUri("", uri));
+ intent.putExtra("extra_message", MESSAGE);
+ intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION
+ | Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ getActivity().getResultForIntent(intent);
+ assertEquals(MESSAGE, getFirstLineFromUri(uri));
+ }
+
+ public void testPersistablePermission() {
+ Uri uri = getUriWithTextInFile("persistable_test", MESSAGE);
+ grantPersistableReadPermission(uri);
+
+ // Now checking if the receiver can read this uri, without re-granting the read permission.
+ Intent intent = new Intent(ACTION_READ_FROM_URI);
+ intent.setClipData(ClipData.newRawUri("", uri));
+ Intent result = getActivity().getResultForIntent(intent);
+ assertTrue(result != null);
+ assertEquals(MESSAGE, result.getStringExtra("extra_response"));
+ }
+
+ /**
+ * The intent receiver will try to read uriNotGranted.
+ * Inside the same user, this uri can be read if the receiver has the
+ * com.android.cts.managedprofile.permission.SAMPLE permission. But since we cross
+ * user-boundaries, it should not be able to (only uri grants work accross users for apps
+ * without special permission).
+ * We also grant uriGranted to the receiver (this uri belongs to the same content provider as
+ * uriNotGranted), to enforce that even if an app has permission to one uri of a
+ * ContentProvider, it still cannot access a uri it does not have access to.
+ */
+ public void testAppPermissionsDontWorkAcrossProfiles() {
+ // The FileProvider does not allow to use app permissions. So we need to use another
+ // ContentProvider.
+ Uri uriGranted = getBasicContentProviderUri("uri_granted");
+ Uri uriNotGranted = getBasicContentProviderUri("uri_not_granted");
+
+ // Granting uriGranted to the receiver
+ // Using a persistable permission so that it is kept even after we restart the receiver
+ // activity with another intent.
+ grantPersistableReadPermission(uriGranted);
+
+ Intent notGrant = new Intent(ACTION_READ_FROM_URI);
+ notGrant.setClipData(ClipData.newRawUri("", uriNotGranted));
+
+ Intent result = getActivity().getResultForIntent(notGrant);
+ assertTrue(result != null);
+ // The receiver did not have permission to read the uri. So it should have caught a security
+ // exception.
+ assertTrue(result.getBooleanExtra("extra_caught_security_exception", false));
+ }
+
+ private void grantPersistableReadPermission(Uri uri) {
+ Intent grantPersistable = new Intent(ACTION_TAKE_PERSISTABLE_URI_PERMISSION);
+ grantPersistable.setClipData(ClipData.newRawUri("", uri));
+ grantPersistable.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
+ | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
+ getActivity().getResultForIntent(grantPersistable);
+ }
+
+ private Uri getBasicContentProviderUri(String path) {
+ // The uris created here are not associated with any data. But this does not prevent us from
+ // granting these uris to other apps, or these apps from trying to access these uris.
+ return new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_CONTENT)
+ .authority(BASIC_CONTENT_PROVIDER_AUTHORITY)
+ .path(path)
+ .build();
+ }
+
+ private Uri getUriWithTextInFile(String name, String text) {
+ String filename = mContext.getFilesDir() + File.separator + "texts" + File.separator
+ + name + ".txt";
+ Log.i(TAG, "Creating file " + filename + " with text \"" + text + "\"");
+ final File file = new File(filename);
+ file.getParentFile().mkdirs(); // If the folder doesn't exists it is created
+ try {
+ FileWriter writer = new FileWriter(file);
+ writer.write(text);
+ writer.close();
+ } catch(IOException e) {
+ Log.e(TAG, "Could not create file " + filename + " with text " + text);
+ return null;
+ }
+ return FileProvider.getUriForFile(mContext, "com.android.cts.managedprofile.fileprovider",
+ file);
+ }
+
+ /**
+ * Returns the first line of the file associated with uri.
+ */
+ private String getFirstLineFromUri(Uri uri) {
+ try {
+ InputStream is = mContext.getContentResolver().openInputStream(uri);
+ BufferedReader r = new BufferedReader(new InputStreamReader(is));
+ return r.readLine();
+ } catch (IOException e) {
+ Log.e(TAG, "could not read the uri " + uri);
+ return null;
+ }
}
}
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofilecontent/IntentSenderActivity.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofilecontent/IntentSenderActivity.java
index 6c8020f..e4c8ddf 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofilecontent/IntentSenderActivity.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/crossprofilecontent/IntentSenderActivity.java
@@ -17,152 +17,36 @@
import static com.android.cts.managedprofile.BaseManagedProfileTest.ADMIN_RECEIVER_COMPONENT;
-import android.app.admin.DevicePolicyManager;
import android.app.Activity;
-import android.content.ClipData;
-import android.content.Context;
import android.content.Intent;
-import android.content.IntentFilter;
-import android.net.Uri;
-import android.os.Bundle;
import android.util.Log;
-import android.support.v4.content.FileProvider;
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileWriter;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
public class IntentSenderActivity extends Activity {
- private final static String TAG = "IntentSenderActivity";
-
- private final CountDownLatch mLatch = new CountDownLatch(1);
-
- private static final String ACTION_READ_FROM_URI = "com.android.cts.action.READ_FROM_URI";
-
- private static final String ACTION_WRITE_TO_URI = "com.android.cts.action.WRITE_TO_URI";
-
- private static final int TEST_RECEIVER_CAN_READ = 1;
- private static final int TEST_RECEIVER_CAN_WRITE = 2;
+ private CountDownLatch mLatch;
private static final int WAIT_FOR_RESPONSE_TIMEOUT_SECONDS = 5;
- private String mResponse;
+ private Intent mResult;
- private Uri mUriToWrite;
-
- private DevicePolicyManager mDevicePolicyManager;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- mDevicePolicyManager = (DevicePolicyManager)
- getSystemService(Context.DEVICE_POLICY_SERVICE);
- }
-
- /**
- * This method will send an intent to a receiver in another profile.
- * This intent will have, in the ClipData, a uri whose associated file stores this message.
- * The receiver will read the message from the uri, and put it inside the result intent.
- * This method returns the response in the result intent, or null if no response was received.
- */
- String testReceiverCanRead(String message) {
- IntentFilter testIntentFilter = new IntentFilter();
- testIntentFilter.addAction(ACTION_READ_FROM_URI);
- mDevicePolicyManager.addCrossProfileIntentFilter(ADMIN_RECEIVER_COMPONENT, testIntentFilter,
- DevicePolicyManager.FLAG_PARENT_CAN_ACCESS_MANAGED);
-
- Intent intent = new Intent(ACTION_READ_FROM_URI);
- intent.setClipData(ClipData.newRawUri("", getUriWithTextInFile("reading_test", message)));
- intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
- startActivityForResult(intent, TEST_RECEIVER_CAN_READ);
+ Intent getResultForIntent(Intent intent) {
+ mLatch = new CountDownLatch(1);
+ mResult = null;
+ startActivityForResult(intent, 0);
try {
mLatch.await(WAIT_FOR_RESPONSE_TIMEOUT_SECONDS, TimeUnit.SECONDS);
} catch (InterruptedException e) {
- return null;
}
- return mResponse;
- }
-
- /**
- * This method will send an intent to a receiver in another profile.
- * This intent will have a message in an extra, and a uri specified by the ClipData.
- * The receiver will read the message from the extra, and write it to the uri in
- * the ClipData.
- * This method returns what has been written in the uri.
- */
- String testReceiverCanWrite(String message) {
- IntentFilter testIntentFilter = new IntentFilter();
- testIntentFilter.addAction(ACTION_WRITE_TO_URI);
- mDevicePolicyManager.addCrossProfileIntentFilter(ADMIN_RECEIVER_COMPONENT, testIntentFilter,
- DevicePolicyManager.FLAG_PARENT_CAN_ACCESS_MANAGED);
- // It's the receiver of the intent that should write to the uri, not us. So, for now, we
- // write an empty string.
- mUriToWrite = getUriWithTextInFile("writing_test", "");
- Intent intent = new Intent(ACTION_WRITE_TO_URI);
- intent.setClipData(ClipData.newRawUri("", mUriToWrite));
- intent.putExtra("extra_message", message);
- intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION
- | Intent.FLAG_GRANT_READ_URI_PERMISSION);
- startActivityForResult(intent, TEST_RECEIVER_CAN_WRITE);
- try {
- mLatch.await(WAIT_FOR_RESPONSE_TIMEOUT_SECONDS, TimeUnit.SECONDS);
- } catch (InterruptedException e) {
- return null;
- }
- return mResponse;
+ return mResult;
}
@Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (requestCode == TEST_RECEIVER_CAN_READ) {
- if (resultCode == Activity.RESULT_OK) {
- mResponse = data.getStringExtra("extra_response");
- Log.i(TAG, "response received in reading test: " + mResponse);
- }
- } else if (requestCode == TEST_RECEIVER_CAN_WRITE) {
- if (resultCode == Activity.RESULT_OK) {
- mResponse = getFirstLineFromUri(mUriToWrite);
- Log.i(TAG, "response received in writing test: " + mResponse);
- }
+ protected void onActivityResult(int requestCode, int resultCode, Intent result) {
+ if (resultCode == Activity.RESULT_OK) {
+ mResult = result;
}
mLatch.countDown();
- finish();
- }
-
- private Uri getUriWithTextInFile(String name, String text) {
- String filename = getFilesDir() + File.separator + "texts" + File.separator + name + ".txt";
- Log.i(TAG, "Creating file " + filename + " with text \"" + text + "\"");
- final File file = new File(filename);
- file.getParentFile().mkdirs(); // If the folder doesn't exists it is created
- try {
- FileWriter writer = new FileWriter(file);
- writer.write(text);
- writer.close();
- } catch(IOException e) {
- Log.e(TAG, "Could not create file " + filename + " with text " + text);
- return null;
- }
- return FileProvider.getUriForFile(this,
- "com.android.cts.managedprofile.fileprovider", file);
- }
-
- /**
- * Returns the first line of the file associated with uri.
- */
- private String getFirstLineFromUri(Uri uri) {
- try {
- InputStream is = getContentResolver().openInputStream(uri);
- BufferedReader r = new BufferedReader(new InputStreamReader(is));
- return r.readLine();
- } catch (IOException e) {
- Log.e(TAG, "could not read the uri " + uri);
- return null;
- }
}
}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
index 4e57b28..88a3b70 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
@@ -124,16 +124,55 @@
}
}
+ // TODO: This test is not specific to managed profiles, but applies to multi-user in general.
+ // Move it to a MultiUserTest class when there is one. Should probably move
+ // UserRestrictionActivity to a more generic apk too as it might be useful for different kinds
+ // of tests (same applies to ComponentDisablingActivity).
+ public void testNoDebuggingFeaturesRestriction() throws Exception {
+ if (!mHasFeature) {
+ return;
+ }
+ String restriction = "no_debugging_features"; // UserManager.DISALLOW_DEBUGGING_FEATURES
+ String command = "add-restriction";
+
+ String addRestrictionCommandOutput =
+ changeUserRestrictionForUser(restriction, command, mUserId);
+ assertTrue("Command was expected to succeed " + addRestrictionCommandOutput,
+ addRestrictionCommandOutput.contains("Status: ok"));
+
+ // This should now fail, as the shell is not available to start activities under a different
+ // user once the restriction is in place.
+ addRestrictionCommandOutput =
+ changeUserRestrictionForUser(restriction, command, mUserId);
+ assertTrue(
+ "Expected SecurityException when starting the activity "
+ + addRestrictionCommandOutput,
+ addRestrictionCommandOutput.contains("SecurityException"));
+ }
+
private void disableActivityForUser(String activityName, int userId)
throws DeviceNotAvailableException {
String command = "am start -W --user " + userId
+ " --es extra-package " + MANAGED_PROFILE_PKG
- + " --es extra-class-name " + MANAGED_PROFILE_PKG + "." + activityName + " "
- + MANAGED_PROFILE_PKG + "/.ComponentDisablingActivity ";
+ + " --es extra-class-name " + MANAGED_PROFILE_PKG + "." + activityName
+ + " " + MANAGED_PROFILE_PKG + "/.ComponentDisablingActivity ";
CLog.logAndDisplay(LogLevel.INFO, "Output for command " + command + ": "
+ getDevice().executeShellCommand(command));
}
+ private String changeUserRestrictionForUser(String key, String command, int userId)
+ throws DeviceNotAvailableException {
+ String adbCommand = "am start -W --user " + userId
+ + " -c android.intent.category.DEFAULT "
+ + " --es extra-command " + command
+ + " --es extra-restriction-key " + key
+ + " " + MANAGED_PROFILE_PKG + "/.UserRestrictionActivity";
+ String commandOutput = getDevice().executeShellCommand(adbCommand);
+ CLog.logAndDisplay(LogLevel.INFO,
+ "Output for command " + adbCommand + ": " + commandOutput);
+ return commandOutput;
+ }
+
private int createManagedProfile() throws DeviceNotAvailableException {
String command =
"pm create-user --profileOf 0 --managed TestProfile_" + System.currentTimeMillis();
diff --git a/libs/deviceutil/Android.mk b/libs/deviceutil/Android.mk
index d5a2c57..8c81ee4 100644
--- a/libs/deviceutil/Android.mk
+++ b/libs/deviceutil/Android.mk
@@ -29,3 +29,5 @@
LOCAL_SDK_VERSION := current
include $(BUILD_STATIC_JAVA_LIBRARY)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/libs/deviceutil/jni/Android.mk b/libs/deviceutil/jni/Android.mk
new file mode 100644
index 0000000..b801a4d
--- /dev/null
+++ b/libs/deviceutil/jni/Android.mk
@@ -0,0 +1,32 @@
+# Copyright (C) 2010 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 := libcts_jni
+
+# Don't include this package in any configuration by default.
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := \
+ CtsJniOnLoad.cpp \
+ android_cts_FileUtils.cpp
+
+LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
+
+LOCAL_SHARED_LIBRARIES := libnativehelper liblog libdl
+
+include $(BUILD_SHARED_LIBRARY)
\ No newline at end of file
diff --git a/libs/deviceutil/jni/CtsJniOnLoad.cpp b/libs/deviceutil/jni/CtsJniOnLoad.cpp
new file mode 100644
index 0000000..abf8e01
--- /dev/null
+++ b/libs/deviceutil/jni/CtsJniOnLoad.cpp
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2010 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 <jni.h>
+#include <stdio.h>
+
+extern int register_android_cts_FileUtils(JNIEnv*);
+
+jint JNI_OnLoad(JavaVM *vm, void *reserved) {
+ JNIEnv *env = NULL;
+
+ if (vm->GetEnv((void **) &env, JNI_VERSION_1_4) != JNI_OK) {
+ return JNI_ERR;
+ }
+
+ if (register_android_cts_FileUtils(env)) {
+ return JNI_ERR;
+ }
+
+ return JNI_VERSION_1_4;
+}
diff --git a/tests/tests/security/jni/android_security_cts_FileUtils.cpp b/libs/deviceutil/jni/android_cts_FileUtils.cpp
similarity index 80%
rename from tests/tests/security/jni/android_security_cts_FileUtils.cpp
rename to libs/deviceutil/jni/android_cts_FileUtils.cpp
index 8009c04..91b74bf 100644
--- a/tests/tests/security/jni/android_security_cts_FileUtils.cpp
+++ b/libs/deviceutil/jni/android_cts_FileUtils.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2011 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.
@@ -40,12 +40,12 @@
/*
* Native methods used by
- * cts/tests/src/android/security/cts/FileUtils.java
+ * cts/libs/deviceutil/src/android/cts/util/FileUtils.java
*
- * Copied from hidden API: frameworks/base/core/jni/android_security_FileUtils.cpp
+ * Copied from hidden API: frameworks/base/core/jni/android_FileUtils.cpp
*/
-jboolean android_security_cts_FileUtils_getFileStatus(JNIEnv* env, jobject thiz,
+jboolean android_cts_FileUtils_getFileStatus(JNIEnv* env, jobject thiz,
jstring path, jobject fileStatus, jboolean statLinks)
{
const char* pathStr = env->GetStringUTFChars(path, NULL);
@@ -77,21 +77,21 @@
return ret;
}
-jstring android_security_cts_FileUtils_getUserName(JNIEnv* env, jobject thiz,
+jstring android_cts_FileUtils_getUserName(JNIEnv* env, jobject thiz,
jint uid)
{
struct passwd *pwd = getpwuid(uid);
return env->NewStringUTF(pwd->pw_name);
}
-jstring android_security_cts_FileUtils_getGroupName(JNIEnv* env, jobject thiz,
+jstring android_cts_FileUtils_getGroupName(JNIEnv* env, jobject thiz,
jint gid)
{
struct group *grp = getgrgid(gid);
return env->NewStringUTF(grp->gr_name);
}
-jint android_security_cts_FileUtils_setPermissions(JNIEnv* env, jobject clazz,
+jint android_cts_FileUtils_setPermissions(JNIEnv* env, jobject clazz,
jstring file, jint mode)
{
const char *fileStr = env->GetStringUTFChars(file, NULL);
@@ -110,22 +110,22 @@
}
static JNINativeMethod gMethods[] = {
- { "getFileStatus", "(Ljava/lang/String;Landroid/security/cts/FileUtils$FileStatus;Z)Z",
- (void *) android_security_cts_FileUtils_getFileStatus },
+ { "getFileStatus", "(Ljava/lang/String;Landroid/cts/util/FileUtils$FileStatus;Z)Z",
+ (void *) android_cts_FileUtils_getFileStatus },
{ "getUserName", "(I)Ljava/lang/String;",
- (void *) android_security_cts_FileUtils_getUserName },
+ (void *) android_cts_FileUtils_getUserName },
{ "getGroupName", "(I)Ljava/lang/String;",
- (void *) android_security_cts_FileUtils_getGroupName },
+ (void *) android_cts_FileUtils_getGroupName },
{ "setPermissions", "(Ljava/lang/String;I)I",
- (void *) android_security_cts_FileUtils_setPermissions },
+ (void *) android_cts_FileUtils_setPermissions },
};
-int register_android_security_cts_FileUtils(JNIEnv* env)
+int register_android_cts_FileUtils(JNIEnv* env)
{
- jclass clazz = env->FindClass("android/security/cts/FileUtils");
+ jclass clazz = env->FindClass("android/cts/util/FileUtils");
assert(clazz != null);
- gFileStatusClass = env->FindClass("android/security/cts/FileUtils$FileStatus");
+ gFileStatusClass = env->FindClass("android/cts/util/FileUtils$FileStatus");
assert(gFileStatusClass != null);
gFileStatusDevFieldID = env->GetFieldID(gFileStatusClass, "dev", "I");
gFileStatusInoFieldID = env->GetFieldID(gFileStatusClass, "ino", "I");
diff --git a/libs/deviceutil/src/android/app/cts/CTSResult.java b/libs/deviceutil/src/android/cts/util/CTSResult.java
similarity index 96%
rename from libs/deviceutil/src/android/app/cts/CTSResult.java
rename to libs/deviceutil/src/android/cts/util/CTSResult.java
index ae4dbfd..c780f57 100644
--- a/libs/deviceutil/src/android/app/cts/CTSResult.java
+++ b/libs/deviceutil/src/android/cts/util/CTSResult.java
@@ -14,7 +14,7 @@
* the License.
*/
-package android.app.cts;
+package android.cts.util;
public interface CTSResult {
public static final int RESULT_OK = 1;
diff --git a/libs/deviceutil/src/android/provider/cts/FileCopyHelper.java b/libs/deviceutil/src/android/cts/util/FileCopyHelper.java
similarity index 98%
rename from libs/deviceutil/src/android/provider/cts/FileCopyHelper.java
rename to libs/deviceutil/src/android/cts/util/FileCopyHelper.java
index 507eb06..e84e920 100644
--- a/libs/deviceutil/src/android/provider/cts/FileCopyHelper.java
+++ b/libs/deviceutil/src/android/cts/util/FileCopyHelper.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.provider.cts;
+package android.cts.util;
import android.content.Context;
diff --git a/tests/tests/os/src/android/os/cts/FileUtils.java b/libs/deviceutil/src/android/cts/util/FileUtils.java
similarity index 98%
rename from tests/tests/os/src/android/os/cts/FileUtils.java
rename to libs/deviceutil/src/android/cts/util/FileUtils.java
index 8600d8b..055f2d6 100644
--- a/tests/tests/os/src/android/os/cts/FileUtils.java
+++ b/libs/deviceutil/src/android/cts/util/FileUtils.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.os.cts;
+package android.cts.util;
import java.io.ByteArrayOutputStream;
import java.io.File;
@@ -54,7 +54,7 @@
public static final int S_IXOTH = 00001;
static {
- System.loadLibrary("ctsos_jni");
+ System.loadLibrary("cts_jni");
}
public static class FileStatus {
diff --git a/tests/tests/os/src/android/os/cts/IBinderParcelable.java b/libs/deviceutil/src/android/cts/util/IBinderParcelable.java
similarity index 97%
rename from tests/tests/os/src/android/os/cts/IBinderParcelable.java
rename to libs/deviceutil/src/android/cts/util/IBinderParcelable.java
index e48f58a..c80716e 100644
--- a/tests/tests/os/src/android/os/cts/IBinderParcelable.java
+++ b/libs/deviceutil/src/android/cts/util/IBinderParcelable.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package android.os.cts;
+package android.cts.util;
import android.os.IBinder;
import android.os.Parcel;
diff --git a/tests/tests/widget/src/android/widget/cts/NullWebViewUtils.java b/libs/deviceutil/src/android/cts/util/NullWebViewUtils.java
similarity index 98%
rename from tests/tests/widget/src/android/widget/cts/NullWebViewUtils.java
rename to libs/deviceutil/src/android/cts/util/NullWebViewUtils.java
index d7a73fa..e1b23f7 100644
--- a/tests/tests/widget/src/android/widget/cts/NullWebViewUtils.java
+++ b/libs/deviceutil/src/android/cts/util/NullWebViewUtils.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.widget.cts;
+package android.cts.util;
import android.content.Context;
import android.content.pm.PackageManager;
diff --git a/tests/tests/os/src/android/os/cts/ReadElf.java b/libs/deviceutil/src/android/cts/util/ReadElf.java
similarity index 99%
rename from tests/tests/os/src/android/os/cts/ReadElf.java
rename to libs/deviceutil/src/android/cts/util/ReadElf.java
index 4a20031..559cbd0 100644
--- a/tests/tests/os/src/android/os/cts/ReadElf.java
+++ b/libs/deviceutil/src/android/cts/util/ReadElf.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.os.cts;
+package android.cts.util;
import java.io.File;
import java.io.IOException;
diff --git a/tests/tests/telephony/src/android/telephony/cts/TestThread.java b/libs/deviceutil/src/android/cts/util/TestThread.java
similarity index 98%
rename from tests/tests/telephony/src/android/telephony/cts/TestThread.java
rename to libs/deviceutil/src/android/cts/util/TestThread.java
index 9bf40de..14df61c 100644
--- a/tests/tests/telephony/src/android/telephony/cts/TestThread.java
+++ b/libs/deviceutil/src/android/cts/util/TestThread.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package android.telephony.cts;
+package android.cts.util;
/**
* Thread class for executing a Runnable containing assertions in a separate thread.
diff --git a/tests/tests/view/src/android/view/cts/WidgetTestUtils.java b/libs/deviceutil/src/android/cts/util/WidgetTestUtils.java
similarity index 98%
rename from tests/tests/view/src/android/view/cts/WidgetTestUtils.java
rename to libs/deviceutil/src/android/cts/util/WidgetTestUtils.java
index e82e9df..813672e 100644
--- a/tests/tests/view/src/android/view/cts/WidgetTestUtils.java
+++ b/libs/deviceutil/src/android/cts/util/WidgetTestUtils.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.view.cts;
+package android.cts.util;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
diff --git a/libs/deviceutillegacy/Android.mk b/libs/deviceutillegacy/Android.mk
new file mode 100644
index 0000000..852ce38
--- /dev/null
+++ b/libs/deviceutillegacy/Android.mk
@@ -0,0 +1,30 @@
+# Copyright (C) 2014 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_STATIC_JAVA_LIBRARIES := ctsdeviceutil
+
+LOCAL_SRC_FILES := \
+ $(call all-java-files-under, src)
+
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE := ctsdeviceutillegacy
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewOnUiThread.java b/libs/deviceutillegacy/src/android/webkit/cts/WebViewOnUiThread.java
similarity index 99%
rename from tests/tests/webkit/src/android/webkit/cts/WebViewOnUiThread.java
rename to libs/deviceutillegacy/src/android/webkit/cts/WebViewOnUiThread.java
index 9b2d803..b9d3af1 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewOnUiThread.java
+++ b/libs/deviceutillegacy/src/android/webkit/cts/WebViewOnUiThread.java
@@ -17,6 +17,7 @@
package android.webkit.cts;
import android.cts.util.PollingCheck;
+import android.cts.util.TestThread;
import android.graphics.Bitmap;
import android.graphics.Picture;
import android.graphics.Rect;
diff --git a/suite/cts/deviceTests/dram/Android.mk b/suite/cts/deviceTests/dram/Android.mk
index 13de747..879d151 100644
--- a/suite/cts/deviceTests/dram/Android.mk
+++ b/suite/cts/deviceTests/dram/Android.mk
@@ -18,6 +18,9 @@
# don't include this package in any target
LOCAL_MODULE_TAGS := tests
+# Include both the 32 and 64 bit versions
+LOCAL_MULTILIB := both
+
LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner
LOCAL_JNI_SHARED_LIBRARIES := libctsdram_jni
diff --git a/suite/cts/deviceTests/opengl/Android.mk b/suite/cts/deviceTests/opengl/Android.mk
index 7e93dd7..0708efb 100644
--- a/suite/cts/deviceTests/opengl/Android.mk
+++ b/suite/cts/deviceTests/opengl/Android.mk
@@ -18,6 +18,9 @@
# don't include this package in any target
LOCAL_MODULE_TAGS := tests
+# Include both the 32 and 64 bit versions
+LOCAL_MULTILIB := both
+
LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner
LOCAL_JNI_SHARED_LIBRARIES := libctsopengl_jni
diff --git a/suite/cts/deviceTests/simplecpu/Android.mk b/suite/cts/deviceTests/simplecpu/Android.mk
index cc25223..17e7506 100644
--- a/suite/cts/deviceTests/simplecpu/Android.mk
+++ b/suite/cts/deviceTests/simplecpu/Android.mk
@@ -18,6 +18,9 @@
# don't include this package in any target
LOCAL_MODULE_TAGS := tests
+# Include both the 32 and 64 bit versions
+LOCAL_MULTILIB := both
+
LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner
LOCAL_JNI_SHARED_LIBRARIES := libctscpu_jni
diff --git a/tests/app/src/android/app/cts/CTSActivityTestCaseBase.java b/tests/app/src/android/app/cts/CTSActivityTestCaseBase.java
index 9ab1965..efe693a 100644
--- a/tests/app/src/android/app/cts/CTSActivityTestCaseBase.java
+++ b/tests/app/src/android/app/cts/CTSActivityTestCaseBase.java
@@ -16,6 +16,7 @@
package android.app.cts;
+import android.cts.util.CTSResult;
import android.test.InstrumentationTestCase;
public class CTSActivityTestCaseBase extends InstrumentationTestCase implements CTSResult {
diff --git a/tests/app/src/android/app/cts/IBinderParcelable.java b/tests/app/src/android/app/cts/IBinderParcelable.java
deleted file mode 100644
index 228097f..0000000
--- a/tests/app/src/android/app/cts/IBinderParcelable.java
+++ /dev/null
@@ -1,52 +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.app.cts;
-
-import android.os.IBinder;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-public class IBinderParcelable implements Parcelable {
- public IBinder binder;
-
- public IBinderParcelable(IBinder source) {
- binder = source;
- }
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeStrongBinder(binder);
- }
-
- public static final Parcelable.Creator<IBinderParcelable>
- CREATOR = new Parcelable.Creator<IBinderParcelable>() {
-
- public IBinderParcelable createFromParcel(Parcel source) {
- return new IBinderParcelable(source);
- }
-
- public IBinderParcelable[] newArray(int size) {
- return new IBinderParcelable[size];
- }
- };
-
- private IBinderParcelable(Parcel source) {
- binder = source.readStrongBinder();
- }
-}
diff --git a/tests/app/src/android/app/cts/LocalActivityManagerTestHelper.java b/tests/app/src/android/app/cts/LocalActivityManagerTestHelper.java
index 76af648..70764e4 100644
--- a/tests/app/src/android/app/cts/LocalActivityManagerTestHelper.java
+++ b/tests/app/src/android/app/cts/LocalActivityManagerTestHelper.java
@@ -21,9 +21,9 @@
import android.app.ActivityGroup;
import android.app.LocalActivityManager;
import android.content.Intent;
+import android.cts.util.CTSResult;
import android.os.Bundle;
import android.view.Window;
-import android.app.cts.CTSResult;
public class LocalActivityManagerTestHelper extends ActivityGroup {
diff --git a/tests/app/src/android/app/cts/LocalService.java b/tests/app/src/android/app/cts/LocalService.java
index 22273b0..6c4ae99 100644
--- a/tests/app/src/android/app/cts/LocalService.java
+++ b/tests/app/src/android/app/cts/LocalService.java
@@ -18,6 +18,7 @@
import android.app.Service;
import android.content.Intent;
+import android.cts.util.IBinderParcelable;
import android.os.Binder;
import android.os.IBinder;
import android.os.Parcel;
diff --git a/tests/app/src/android/app/cts/SearchManagerStubActivity.java b/tests/app/src/android/app/cts/SearchManagerStubActivity.java
index 6385fef..0dbd832 100644
--- a/tests/app/src/android/app/cts/SearchManagerStubActivity.java
+++ b/tests/app/src/android/app/cts/SearchManagerStubActivity.java
@@ -20,6 +20,7 @@
import android.app.SearchManager;
import android.content.ComponentName;
import android.content.Context;
+import android.cts.util.CTSResult;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
diff --git a/tests/expectations/knownfailures.txt b/tests/expectations/knownfailures.txt
index 9ec1f61..40a66d2 100644
--- a/tests/expectations/knownfailures.txt
+++ b/tests/expectations/knownfailures.txt
@@ -1,5 +1,12 @@
[
{
+ description: "signature test stil needs more work",
+ names: [
+ "android.signature.cts.SignatureTest#testSignature"
+ ],
+ bug: 17894722
+},
+{
description: "Not all jdwp features are currently supported. These tests will fail",
names: [
"org.apache.harmony.jpda.tests.jdwp.DebuggerOnDemand.OnthrowDebuggerLaunchTest#testDebuggerLaunch001",
@@ -84,19 +91,6 @@
bug: 17496766
},
{
- description: "As per new CTS test case adding policy",
- names: [
- "com.android.cts.managedprofile.PrimaryUserTest#testAddCrossProfileIntentFilter_primary",
- "com.android.cts.managedprofile.PrimaryUserTest#testAddCrossProfileIntentFilter_all",
- "com.android.cts.managedprofile.PrimaryUserTest#testAddCrossProfileIntentFilter_managed",
- "com.android.cts.managedprofile.ManagedProfile#testClearCrossProfileIntentFilters",
- "com.android.cts.managedprofile.ManagedProfile#testAddCrossProfileIntentFilter_primary",
- "com.android.cts.managedprofile.ManagedProfile#testAddCrossProfileIntentFilter_all",
- "com.android.cts.managedprofile.ManagedProfile#testAddCrossProfileIntentFilter_managed"
- ],
- bug: 15900074
-},
-{
description: "these tests locks the screen with an emtpy password or swipe-to-unlock, blocking subsequent test to dismiss keyguard",
names: [
"com.android.cts.devicepolicy.DeviceOwnerTest#testKeyManagement"
@@ -111,6 +105,28 @@
bug: 17508787
},
{
+ description: "New tests recently added for Android Enterprise. To be moved out of CTS-staging as soon as they show that they are stable",
+ names: [
+ "com.android.cts.devicepolicy.DeviceOwnerTest#testApplicationRestrictions",
+ "com.android.cts.devicepolicy.DeviceOwnerTest#testCaCertManagement",
+ "com.android.cts.devicepolicy.DeviceOwnerTest#testDeviceOwnerSetup",
+ "com.android.cts.devicepolicy.DeviceOwnerTest#testPersistentIntentResolving",
+ "com.android.cts.devicepolicy.DeviceOwnerTest#testScreenCaptureDisabled",
+ "com.android.cts.devicepolicy.ManagedProfileTest#testManagedProfileSetup",
+ "com.android.cts.devicepolicy.ManagedProfileTest#testWipeData",
+ "com.android.cts.devicepolicy.ManagedProfileTest#testCrossProfileIntentFilters",
+ "com.android.cts.devicepolicy.ManagedProfileTest#testCrossProfileContent",
+ "com.android.cts.devicepolicy.ManagedProfileTest#testNoDebuggingFeaturesRestriction"
+ ]
+},
+{
+ description: "Flaky test which ocassionally fails",
+ names: [
+ "com.android.cts.devicepolicy.DeviceOwnerTest#testLockTask"
+ ],
+ bug: 17890673
+},
+{
description: "These tests fail on some devices.",
names: [
@@ -299,5 +315,12 @@
"android.hardware.cts.SensorTest#testBatchAndFlushWithHandler"
],
bug: 17675466
+},
+{
+ description: "This test failed on hw decoder that doesn't output frame with the configured format.",
+ names: [
+ "android.meida.cts.ImageReaderDecoderTest#testHwAVCDecode360pForFlexibleYuv"
+ ],
+ bug: 17144778
}
]
diff --git a/tests/tests/app/src/android/app/cts/LocalActivityManagerTest.java b/tests/tests/app/src/android/app/cts/LocalActivityManagerTest.java
index 1b40476..db3baba 100644
--- a/tests/tests/app/src/android/app/cts/LocalActivityManagerTest.java
+++ b/tests/tests/app/src/android/app/cts/LocalActivityManagerTest.java
@@ -20,6 +20,7 @@
import android.app.Instrumentation;
import android.app.LocalActivityManager;
import android.content.Intent;
+import android.cts.util.CTSResult;
import android.test.InstrumentationTestCase;
import android.test.UiThreadTest;
diff --git a/tests/tests/app/src/android/app/cts/SearchManagerTest.java b/tests/tests/app/src/android/app/cts/SearchManagerTest.java
index 8e465e8..1cece76 100644
--- a/tests/tests/app/src/android/app/cts/SearchManagerTest.java
+++ b/tests/tests/app/src/android/app/cts/SearchManagerTest.java
@@ -17,6 +17,7 @@
package android.app.cts;
import android.content.Intent;
+import android.cts.util.CTSResult;
public class SearchManagerTest extends CTSActivityTestCaseBase {
diff --git a/tests/tests/app/src/android/app/cts/ServiceTest.java b/tests/tests/app/src/android/app/cts/ServiceTest.java
index 675b7ae..b66f4c8 100644
--- a/tests/tests/app/src/android/app/cts/ServiceTest.java
+++ b/tests/tests/app/src/android/app/cts/ServiceTest.java
@@ -20,6 +20,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
+import android.cts.util.IBinderParcelable;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
diff --git a/tests/tests/content/AndroidManifest.xml b/tests/tests/content/AndroidManifest.xml
index f7080ae..d54bc02 100644
--- a/tests/tests/content/AndroidManifest.xml
+++ b/tests/tests/content/AndroidManifest.xml
@@ -205,7 +205,6 @@
android:value="com.android.cts.runner.CtsTestRunListener" />
</instrumentation>
- <!--Test for PackageManager, please put this at the very beginning-->
<instrumentation android:name="android.content.pm.cts.TestPmInstrumentation"
android:targetPackage="android"
android:label="PackageManager Instrumentation Test" />
diff --git a/tests/tests/content/src/android/content/pm/cts/ComponentInfoTest.java b/tests/tests/content/src/android/content/pm/cts/ComponentInfoTest.java
index 361bfe4..14a42c0 100644
--- a/tests/tests/content/src/android/content/pm/cts/ComponentInfoTest.java
+++ b/tests/tests/content/src/android/content/pm/cts/ComponentInfoTest.java
@@ -20,6 +20,7 @@
import android.content.pm.ComponentInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
+import android.cts.util.WidgetTestUtils;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Parcel;
diff --git a/tests/tests/content/src/android/content/pm/cts/WidgetTestUtils.java b/tests/tests/content/src/android/content/pm/cts/WidgetTestUtils.java
deleted file mode 100644
index 6efd8b1..0000000
--- a/tests/tests/content/src/android/content/pm/cts/WidgetTestUtils.java
+++ /dev/null
@@ -1,138 +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.content.pm.cts;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-
-import java.io.IOException;
-
-import junit.framework.Assert;
-
-/**
- * The useful methods for widget test.
- */
-public class WidgetTestUtils {
- /**
- * Assert that two bitmaps are equal.
- *
- * @param Bitmap b1 the first bitmap which needs to compare.
- * @param Bitmap b2 the second bitmap which needs to compare.
- */
- public static void assertEquals(Bitmap b1, Bitmap b2) {
- if (b1 == b2) {
- return;
- }
-
- if (b1 == null || b2 == null) {
- Assert.fail("the bitmaps are not equal");
- }
-
- // b1 and b2 are all not null.
- if (b1.getWidth() != b2.getWidth() || b1.getHeight() != b2.getHeight()
- || b1.getConfig() != b2.getConfig()) {
- Assert.fail("the bitmaps are not equal");
- }
-
- int w = b1.getWidth();
- int h = b1.getHeight();
- int s = w * h;
- int[] pixels1 = new int[s];
- int[] pixels2 = new int[s];
-
- b1.getPixels(pixels1, 0, w, 0, 0, w, h);
- b2.getPixels(pixels2, 0, w, 0, 0, w, h);
-
- for (int i = 0; i < s; i++) {
- if (pixels1[i] != pixels2[i]) {
- Assert.fail("the bitmaps are not equal");
- }
- }
- }
-
- /**
- * Find beginning of the special element.
- * @param parser XmlPullParser will be parsed.
- * @param firstElementName the target element name.
- *
- * @throws XmlPullParserException if XML Pull Parser related faults occur.
- * @throws IOException if I/O-related error occur when parsing.
- */
- public static final void beginDocument(XmlPullParser parser, String firstElementName)
- throws XmlPullParserException, IOException {
- Assert.assertNotNull(parser);
- Assert.assertNotNull(firstElementName);
-
- int type;
- while ((type = parser.next()) != XmlPullParser.START_TAG
- && type != XmlPullParser.END_DOCUMENT) {
- ;
- }
-
- if (!parser.getName().equals(firstElementName)) {
- throw new XmlPullParserException("Unexpected start tag: found " + parser.getName()
- + ", expected " + firstElementName);
- }
- }
-
- /**
- * Compare the expected pixels with actual, scaling for the target context density
- *
- * @throws AssertionFailedError
- */
- public static void assertScaledPixels(int expected, int actual, Context context) {
- Assert.assertEquals(expected * context.getResources().getDisplayMetrics().density,
- actual, 3);
- }
-
- /** Converts dips into pixels using the {@link Context}'s density. */
- public static int convertDipToPixels(Context context, int dip) {
- float density = context.getResources().getDisplayMetrics().density;
- return Math.round(density * dip);
- }
-
- /**
- * Retrieve a bitmap that can be used for comparison on any density
- * @param resources
- * @return the {@link Bitmap} or <code>null</code>
- */
- public static Bitmap getUnscaledBitmap(Resources resources, int resId) {
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inScaled = false;
- return BitmapFactory.decodeResource(resources, resId, options);
- }
-
- /**
- * Retrieve a dithered bitmap that can be used for comparison on any density
- * @param resources
- * @param config the preferred config for the returning bitmap
- * @return the {@link Bitmap} or <code>null</code>
- */
- public static Bitmap getUnscaledAndDitheredBitmap(Resources resources,
- int resId, Bitmap.Config config) {
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inDither = true;
- options.inScaled = false;
- options.inPreferredConfig = config;
- return BitmapFactory.decodeResource(resources, resId, options);
- }
-}
diff --git a/tests/tests/dpi/Android.mk b/tests/tests/dpi/Android.mk
index fde990b..4c05ecf 100644
--- a/tests/tests/dpi/Android.mk
+++ b/tests/tests/dpi/Android.mk
@@ -44,6 +44,4 @@
LOCAL_MODULE := android.cts.dpi
-LOCAL_SDK_VERSION := current
-
include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/tests/tests/drm/Android.mk b/tests/tests/drm/Android.mk
index 74422a0..6272e9c 100644
--- a/tests/tests/drm/Android.mk
+++ b/tests/tests/drm/Android.mk
@@ -16,6 +16,9 @@
include $(CLEAR_VARS)
+# Include both the 32 and 64 bit versions of libs
+LOCAL_MULTILIB := both
+
LOCAL_MODULE_TAGS := tests
# and when built explicitly put it in the data partition
diff --git a/tests/tests/graphics/src/android/graphics/cts/BitmapTest.java b/tests/tests/graphics/src/android/graphics/cts/BitmapTest.java
index 4ea89c7..f58b871 100644
--- a/tests/tests/graphics/src/android/graphics/cts/BitmapTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/BitmapTest.java
@@ -19,6 +19,7 @@
import android.content.res.Resources;
+import android.cts.util.WidgetTestUtils;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
diff --git a/tests/tests/graphics/src/android/graphics/cts/MovieTest.java b/tests/tests/graphics/src/android/graphics/cts/MovieTest.java
index 2facdc9..b18b800 100644
--- a/tests/tests/graphics/src/android/graphics/cts/MovieTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/MovieTest.java
@@ -24,12 +24,12 @@
import java.io.OutputStream;
import android.content.Context;
+import android.cts.util.WidgetTestUtils;
import android.graphics.Canvas;
import android.graphics.Movie;
import android.graphics.Paint;
import android.test.ActivityInstrumentationTestCase2;
-
public class MovieTest extends ActivityInstrumentationTestCase2<MockActivity> {
private Movie mMovie;
private final int MOVIE = com.android.cts.graphics.R.drawable.animated;
diff --git a/tests/tests/graphics/src/android/graphics/cts/WidgetTestUtils.java b/tests/tests/graphics/src/android/graphics/cts/WidgetTestUtils.java
deleted file mode 100644
index 63bafac..0000000
--- a/tests/tests/graphics/src/android/graphics/cts/WidgetTestUtils.java
+++ /dev/null
@@ -1,138 +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 org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-
-import java.io.IOException;
-
-import junit.framework.Assert;
-
-/**
- * The useful methods for widget test.
- */
-public class WidgetTestUtils {
- /**
- * Assert that two bitmaps are equal.
- *
- * @param Bitmap b1 the first bitmap which needs to compare.
- * @param Bitmap b2 the second bitmap which needs to compare.
- */
- public static void assertEquals(Bitmap b1, Bitmap b2) {
- if (b1 == b2) {
- return;
- }
-
- if (b1 == null || b2 == null) {
- Assert.fail("the bitmaps are not equal");
- }
-
- // b1 and b2 are all not null.
- if (b1.getWidth() != b2.getWidth() || b1.getHeight() != b2.getHeight()
- || b1.getConfig() != b2.getConfig()) {
- Assert.fail("the bitmaps are not equal");
- }
-
- int w = b1.getWidth();
- int h = b1.getHeight();
- int s = w * h;
- int[] pixels1 = new int[s];
- int[] pixels2 = new int[s];
-
- b1.getPixels(pixels1, 0, w, 0, 0, w, h);
- b2.getPixels(pixels2, 0, w, 0, 0, w, h);
-
- for (int i = 0; i < s; i++) {
- if (pixels1[i] != pixels2[i]) {
- Assert.fail("the bitmaps are not equal");
- }
- }
- }
-
- /**
- * Find beginning of the special element.
- * @param parser XmlPullParser will be parsed.
- * @param firstElementName the target element name.
- *
- * @throws XmlPullParserException if XML Pull Parser related faults occur.
- * @throws IOException if I/O-related error occur when parsing.
- */
- public static final void beginDocument(XmlPullParser parser, String firstElementName)
- throws XmlPullParserException, IOException {
- Assert.assertNotNull(parser);
- Assert.assertNotNull(firstElementName);
-
- int type;
- while ((type = parser.next()) != XmlPullParser.START_TAG
- && type != XmlPullParser.END_DOCUMENT) {
- ;
- }
-
- if (!parser.getName().equals(firstElementName)) {
- throw new XmlPullParserException("Unexpected start tag: found " + parser.getName()
- + ", expected " + firstElementName);
- }
- }
-
- /**
- * Compare the expected pixels with actual, scaling for the target context density
- *
- * @throws AssertionFailedError
- */
- public static void assertScaledPixels(int expected, int actual, Context context) {
- Assert.assertEquals(expected * context.getResources().getDisplayMetrics().density,
- actual, 3);
- }
-
- /** Converts dips into pixels using the {@link Context}'s density. */
- public static int convertDipToPixels(Context context, int dip) {
- float density = context.getResources().getDisplayMetrics().density;
- return Math.round(density * dip);
- }
-
- /**
- * Retrieve a bitmap that can be used for comparison on any density
- * @param resources
- * @return the {@link Bitmap} or <code>null</code>
- */
- public static Bitmap getUnscaledBitmap(Resources resources, int resId) {
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inScaled = false;
- return BitmapFactory.decodeResource(resources, resId, options);
- }
-
- /**
- * Retrieve a dithered bitmap that can be used for comparison on any density
- * @param resources
- * @param config the preferred config for the returning bitmap
- * @return the {@link Bitmap} or <code>null</code>
- */
- public static Bitmap getUnscaledAndDitheredBitmap(Resources resources,
- int resId, Bitmap.Config config) {
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inDither = true;
- options.inScaled = false;
- options.inPreferredConfig = config;
- return BitmapFactory.decodeResource(resources, resId, options);
- }
-}
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/CameraTestUtils.java b/tests/tests/hardware/src/android/hardware/camera2/cts/CameraTestUtils.java
index eef99a2..0c36832 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/CameraTestUtils.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/CameraTestUtils.java
@@ -413,7 +413,13 @@
int offset = 0;
data = new byte[width * height * ImageFormat.getBitsPerPixel(format) / 8];
- byte[] rowData = new byte[planes[0].getRowStride()];
+ int maxRowSize = planes[0].getRowStride();
+ for (int i = 0; i < planes.length; i++) {
+ if (maxRowSize < planes[i].getRowStride()) {
+ maxRowSize = planes[i].getRowStride();
+ }
+ }
+ byte[] rowData = new byte[maxRowSize];
if(VERBOSE) Log.v(TAG, "get data from " + planes.length + " planes");
for (int i = 0; i < planes.length; i++) {
buffer = planes[i].getBuffer();
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/CaptureRequestTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/CaptureRequestTest.java
index 00dd24d..5346ae1 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/CaptureRequestTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/CaptureRequestTest.java
@@ -1494,17 +1494,19 @@
verifyCaptureResultForKey(CaptureResult.CONTROL_AWB_MODE, mode, listener,
NUM_FRAMES_VERIFIED);
- // Verify color correction transform and gains stay unchanged after a lock.
- requestBuilder.set(CaptureRequest.CONTROL_AWB_LOCK, true);
- listener = new SimpleCaptureCallback();
- mSession.setRepeatingRequest(requestBuilder.build(), listener, mHandler);
- waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
+ if (mode == CameraMetadata.CONTROL_AWB_MODE_AUTO) {
+ // Verify color correction transform and gains stay unchanged after a lock.
+ requestBuilder.set(CaptureRequest.CONTROL_AWB_LOCK, true);
+ listener = new SimpleCaptureCallback();
+ mSession.setRepeatingRequest(requestBuilder.build(), listener, mHandler);
+ waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
- if (mStaticInfo.areKeysAvailable(CaptureResult.CONTROL_AWB_STATE)) {
- waitForResultValue(listener, CaptureResult.CONTROL_AWB_STATE,
- CaptureResult.CONTROL_AWB_STATE_LOCKED, NUM_RESULTS_WAIT_TIMEOUT);
+ if (mStaticInfo.areKeysAvailable(CaptureResult.CONTROL_AWB_STATE)) {
+ waitForResultValue(listener, CaptureResult.CONTROL_AWB_STATE,
+ CaptureResult.CONTROL_AWB_STATE_LOCKED, NUM_RESULTS_WAIT_TIMEOUT);
+ }
+
}
-
verifyAwbCaptureResultUnchanged(listener, NUM_FRAMES_VERIFIED);
}
}
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/ImageReaderTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/ImageReaderTest.java
index a68f78d..61f25fb 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/ImageReaderTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/ImageReaderTest.java
@@ -88,6 +88,10 @@
try {
Log.v(TAG, "Testing jpeg capture for Camera " + id);
openDevice(id);
+ if (mStaticInfo.isHardwareLevelLegacy()) {
+ Log.i(TAG, "Skipping test on legacy devices");
+ continue;
+ }
bufferFormatTestByCamera(ImageFormat.JPEG, /*repeating*/false);
} finally {
closeDevice(id);
@@ -113,6 +117,10 @@
try {
Log.v(TAG, "Testing repeating jpeg capture for Camera " + id);
openDevice(id);
+ if (mStaticInfo.isHardwareLevelLegacy()) {
+ Log.i(TAG, "Skipping test on legacy devices");
+ continue;
+ }
bufferFormatTestByCamera(ImageFormat.JPEG, /*repeating*/true);
} finally {
closeDevice(id);
@@ -148,7 +156,10 @@
try {
Log.v(TAG, "YUV and JPEG testing for camera " + id);
openDevice(id);
-
+ if (mStaticInfo.isHardwareLevelLegacy()) {
+ Log.i(TAG, "Skipping test on legacy devices");
+ continue;
+ }
bufferFormatWithYuvTestByCamera(ImageFormat.JPEG);
} finally {
closeDevice(id);
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java
index 7a6e088..ea15c19 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java
@@ -497,6 +497,11 @@
openDevice(id);
+ if (mStaticInfo.isHardwareLevelLegacy()) {
+ Log.i(TAG, "Skipping test on legacy devices");
+ continue;
+ }
+
initSupportedVideoSize(id);
videoSnapshotTestByCamera(burstTest);
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/RobustnessTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/RobustnessTest.java
index 11ba02c..7960200 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/RobustnessTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/RobustnessTest.java
@@ -185,6 +185,11 @@
final StaticMetadata staticInfo = new StaticMetadata(cc);
+ if (staticInfo.isHardwareLevelLegacy()) {
+ Log.i(TAG, "Skipping test on legacy devices");
+ continue;
+ }
+
openDevice(id);
// Always run legacy-level tests
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/helpers/StaticMetadata.java b/tests/tests/hardware/src/android/hardware/camera2/cts/helpers/StaticMetadata.java
index 11d7ac0..fb2001f 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/helpers/StaticMetadata.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/helpers/StaticMetadata.java
@@ -1282,7 +1282,7 @@
if (isHardwareLevelLimitedOrBetter()) {
float compensationStepF =
(float) compensationStep.getNumerator() / compensationStep.getDenominator();
- checkTrueForKey(key, " value must be no more than 1/2", compensationStepF < 0.5f);
+ checkTrueForKey(key, " value must be no more than 1/2", compensationStepF <= 0.5f);
}
return compensationStep;
diff --git a/tests/tests/jni/Android.mk b/tests/tests/jni/Android.mk
index 8b3edd2..1aeb8b7 100644
--- a/tests/tests/jni/Android.mk
+++ b/tests/tests/jni/Android.mk
@@ -21,6 +21,9 @@
# Don't include this package in any target.
LOCAL_MODULE_TAGS := optional
+# Include both the 32 and 64 bit versions
+LOCAL_MULTILIB := both
+
# When built, explicitly put it in the data partition.
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
diff --git a/tests/tests/media/Android.mk b/tests/tests/media/Android.mk
index 936a35e..15237a8 100644
--- a/tests/tests/media/Android.mk
+++ b/tests/tests/media/Android.mk
@@ -21,6 +21,9 @@
# and when built explicitly put it in the data partition
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+# include both the 32 and 64 bit versions
+LOCAL_MULTILIB := both
+
LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestserver ctstestrunner
LOCAL_JNI_SHARED_LIBRARIES := libctsmediacodec_jni
diff --git a/tests/tests/media/src/android/media/cts/AudioManagerStub.java b/tests/tests/media/src/android/media/cts/AudioManagerStub.java
index baae5fc..290b866 100644
--- a/tests/tests/media/src/android/media/cts/AudioManagerStub.java
+++ b/tests/tests/media/src/android/media/cts/AudioManagerStub.java
@@ -19,7 +19,7 @@
import com.android.cts.media.R;
import android.app.Activity;
-import android.app.cts.CTSResult;
+import android.cts.util.CTSResult;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
diff --git a/tests/tests/media/src/android/media/cts/ImageReaderDecoderTest.java b/tests/tests/media/src/android/media/cts/ImageReaderDecoderTest.java
index f115b63..d620995 100644
--- a/tests/tests/media/src/android/media/cts/ImageReaderDecoderTest.java
+++ b/tests/tests/media/src/android/media/cts/ImageReaderDecoderTest.java
@@ -27,6 +27,7 @@
import android.media.ImageReader;
import android.media.MediaCodec;
import android.media.MediaCodecInfo;
+import android.media.MediaCodecInfo.CodecCapabilities;
import android.media.MediaCodecList;
import android.media.MediaExtractor;
import android.media.MediaFormat;
@@ -166,6 +167,8 @@
vidFD.getLength());
MediaFormat mediaFmt = extractor.getTrackFormat(0);
+ mediaFmt.setInteger(MediaFormat.KEY_COLOR_FORMAT,
+ CodecCapabilities.COLOR_FormatYUV420Flexible);
String mime = mediaFmt.getString(MediaFormat.KEY_MIME);
try {
// Create decoder
@@ -191,10 +194,10 @@
throws Exception, InterruptedException {
ByteBuffer[] decoderInputBuffers;
ByteBuffer[] decoderOutputBuffers;
- // Get decoder output ImageFormat, will be used to create ImageReader
- int codecImageFormat = getImageFormatFromCodecType(mime);
- assertEquals("Codec image format should match image reader format",
- imageFormat, codecImageFormat);
+ if (!imageFormatSupported(decoder, imageFormat, mime)) {
+ // TODO: SKIPPING TEST
+ return;
+ }
createImageReader(width, height, imageFormat, MAX_NUM_IMAGES, mImageListener);
// Configure decoder.
@@ -293,74 +296,19 @@
}
}
- private int getImageFormatFromCodecType(String mimeType) {
- // TODO: Need pick a codec first, then get the codec info, will revisit for future.
- MediaCodecInfo codecInfo = getCodecInfoByType(mimeType);
- if (VERBOSE) Log.v(TAG, "found decoder: " + codecInfo.getName());
-
- int colorFormat = selectDecoderOutputColorFormat(codecInfo, mimeType);
- if (VERBOSE) Log.v(TAG, "found decoder output color format: " + colorFormat);
- switch (colorFormat) {
- case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar:
- // TODO: This is fishy, OMX YUV420P is not identical as YV12, U and V planes are
- // swapped actually. It should give YV12 if producer is setup first, that is, after
- // Configuring the Surface (provided by ImageReader object) into codec, but this
- // is Chicken-egg issue, do the translation on behalf of driver here:)
- return ImageFormat.YV12;
- case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar:
- // same as above.
- return ImageFormat.NV21;
- default:
- return colorFormat;
+ private boolean imageFormatSupported(MediaCodec decoder, int imageFormat, String mime) {
+ MediaCodecInfo codecInfo = decoder.getCodecInfo();
+ if (codecInfo == null) {
+ return false;
}
- }
-
- private static MediaCodecInfo getCodecInfoByType(String mimeType) {
- int numCodecs = MediaCodecList.getCodecCount();
- for (int i = 0; i < numCodecs; i++) {
- MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
-
- if (codecInfo.isEncoder()) {
- continue;
- }
-
- String[] types = codecInfo.getSupportedTypes();
- for (int j = 0; j < types.length; j++) {
- if (types[j].equalsIgnoreCase(mimeType)) {
- return codecInfo;
- }
- }
- }
- return null;
- }
-
- private static int selectDecoderOutputColorFormat(MediaCodecInfo codecInfo, String mimeType) {
- MediaCodecInfo.CodecCapabilities capabilities = codecInfo.getCapabilitiesForType(mimeType);
- for (int i = 0; i < capabilities.colorFormats.length; i++) {
- int colorFormat = capabilities.colorFormats[i];
- if (isRecognizedFormat(colorFormat)) {
- return colorFormat;
- }
- }
- fail("couldn't find a good color format for " + codecInfo.getName() + " / " + mimeType);
- return 0; // not reached
- }
-
- // Need make this function simple, may be merge into above functions.
- private static boolean isRecognizedFormat(int colorFormat) {
- if (VERBOSE) Log.v(TAG, "colorformat: " + colorFormat);
- switch (colorFormat) {
- // these are the formats we know how to handle for this test
- case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar:
- case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420PackedPlanar:
- case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar:
- case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420PackedSemiPlanar:
- case MediaCodecInfo.CodecCapabilities.COLOR_TI_FormatYUV420PackedSemiPlanar:
- case ImageFormat.YUV_420_888:
+ MediaCodecInfo.CodecCapabilities capabilities = codecInfo.getCapabilitiesForType(mime);
+ for (int colorFormat : capabilities.colorFormats) {
+ if (colorFormat == CodecCapabilities.COLOR_FormatYUV420Flexible
+ && imageFormat == ImageFormat.YUV_420_888) {
return true;
- default:
- return false;
+ }
}
+ return false;
}
private MediaCodec createDecoder(String mime, boolean useHw) throws Exception {
@@ -404,7 +352,7 @@
private static void validateYuvData(byte[] yuvData, int width, int height, int format,
long ts, String fileName) {
- assertTrue("YUV format must be one of the YUV420_888, NV21, or YV12",
+ assertTrue("YUV format must be one of the YUV_420_888, NV21, or YV12",
format == ImageFormat.YUV_420_888 ||
format == ImageFormat.NV21 ||
format == ImageFormat.YV12);
diff --git a/tests/tests/media/src/android/media/cts/MediaScannerConnectionTest.java b/tests/tests/media/src/android/media/cts/MediaScannerConnectionTest.java
index 4234a5b..ddf87b8 100644
--- a/tests/tests/media/src/android/media/cts/MediaScannerConnectionTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaScannerConnectionTest.java
@@ -21,12 +21,12 @@
import android.content.ComponentName;
import android.content.Context;
+import android.cts.util.FileCopyHelper;
import android.cts.util.PollingCheck;
import android.media.MediaScannerConnection;
import android.media.MediaScannerConnection.MediaScannerConnectionClient;
import android.net.Uri;
import android.os.IBinder;
-import android.provider.cts.FileCopyHelper;
import android.test.AndroidTestCase;
import java.io.File;
diff --git a/tests/tests/media/src/android/media/cts/MediaScannerTest.java b/tests/tests/media/src/android/media/cts/MediaScannerTest.java
index b537467..4b42690 100644
--- a/tests/tests/media/src/android/media/cts/MediaScannerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaScannerTest.java
@@ -26,6 +26,7 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.AssetFileDescriptor;
+import android.cts.util.FileCopyHelper;
import android.cts.util.PollingCheck;
import android.database.Cursor;
import android.media.MediaMetadataRetriever;
@@ -38,7 +39,6 @@
import android.os.IBinder;
import android.os.SystemClock;
import android.provider.MediaStore;
-import android.provider.cts.FileCopyHelper;
import android.test.AndroidTestCase;
import android.util.Log;
diff --git a/tests/tests/mediastress/Android.mk b/tests/tests/mediastress/Android.mk
index 5c4930b..5bb23d0 100644
--- a/tests/tests/mediastress/Android.mk
+++ b/tests/tests/mediastress/Android.mk
@@ -20,6 +20,9 @@
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+# Include both the 32 and 64 bit versions
+LOCAL_MULTILIB := both
+
LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner ctsdeviceutil
LOCAL_JNI_SHARED_LIBRARIES := libctsmediastress_jni
diff --git a/tests/tests/nativeopengl/Android.mk b/tests/tests/nativeopengl/Android.mk
index 672eb5c..d2192ad 100644
--- a/tests/tests/nativeopengl/Android.mk
+++ b/tests/tests/nativeopengl/Android.mk
@@ -24,6 +24,9 @@
# When built, explicitly put it in the data partition.
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+# Include both the 32 and 64 bit versions
+LOCAL_MULTILIB := both
+
LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner ctswrappedgtest
LOCAL_JNI_SHARED_LIBRARIES := libnativeopengltests
diff --git a/tests/tests/net/Android.mk b/tests/tests/net/Android.mk
index da19a4d..46d4d81 100644
--- a/tests/tests/net/Android.mk
+++ b/tests/tests/net/Android.mk
@@ -21,6 +21,9 @@
# and when built explicitly put it in the data partition
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+# Include both the 32 and 64 bit versions
+LOCAL_MULTILIB := both
+
LOCAL_JAVA_LIBRARIES := voip-common conscrypt
LOCAL_JNI_SHARED_LIBRARIES := libnativedns_jni
diff --git a/tests/tests/opengl/Android.mk b/tests/tests/opengl/Android.mk
index a14ee7a..3844807 100644
--- a/tests/tests/opengl/Android.mk
+++ b/tests/tests/opengl/Android.mk
@@ -21,6 +21,9 @@
# Don't include this package in any target.
LOCAL_MODULE_TAGS := optional
+# Include both the 32 and 64 bit versions
+LOCAL_MULTILIB := both
+
# When built, explicitly put it in the data partition.
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
diff --git a/tests/tests/openglperf/Android.mk b/tests/tests/openglperf/Android.mk
index 1d57263..7be16e8 100644
--- a/tests/tests/openglperf/Android.mk
+++ b/tests/tests/openglperf/Android.mk
@@ -21,6 +21,9 @@
# and when built explicitly put it in the data partition
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+# Include both the 32 and 64 bit versions
+LOCAL_MULTILIB := both
+
LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner ctsdeviceutil
LOCAL_JNI_SHARED_LIBRARIES := libctsopenglperf_jni
diff --git a/tests/tests/os/Android.mk b/tests/tests/os/Android.mk
index f0fb88a..9dfb86e 100644
--- a/tests/tests/os/Android.mk
+++ b/tests/tests/os/Android.mk
@@ -21,11 +21,12 @@
# and when built explicitly put it in the data partition
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-LOCAL_PROGUARD_ENABLED := disabled
+# Include both the 32 and 64 bit versions
+LOCAL_MULTILIB := both
LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner guava
-LOCAL_JNI_SHARED_LIBRARIES := libctsos_jni
+LOCAL_JNI_SHARED_LIBRARIES := libcts_jni libctsos_jni
LOCAL_SRC_FILES := $(call all-java-files-under, src) \
src/android/os/cts/IParcelFileDescriptorPeer.aidl \
diff --git a/tests/tests/os/jni/Android.mk b/tests/tests/os/jni/Android.mk
index a39b5d1..3d3bc33 100644
--- a/tests/tests/os/jni/Android.mk
+++ b/tests/tests/os/jni/Android.mk
@@ -25,8 +25,7 @@
CtsOsJniOnLoad.cpp \
android_os_cts_CpuInstructions.cpp.arm \
android_os_cts_TaggedPointer.cpp \
- android_os_cts_OSFeatures.cpp \
- android_os_cts_FileUtils.cpp \
+ android_os_cts_OSFeatures.cpp
LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
diff --git a/tests/tests/os/jni/CtsOsJniOnLoad.cpp b/tests/tests/os/jni/CtsOsJniOnLoad.cpp
index ef69732..c6b88f5 100644
--- a/tests/tests/os/jni/CtsOsJniOnLoad.cpp
+++ b/tests/tests/os/jni/CtsOsJniOnLoad.cpp
@@ -25,8 +25,6 @@
extern int register_android_os_cts_OSFeatures(JNIEnv*);
-extern int register_android_os_cts_FileUtils(JNIEnv*);
-
jint JNI_OnLoad(JavaVM *vm, void *reserved) {
JNIEnv *env = NULL;
@@ -50,9 +48,5 @@
return JNI_ERR;
}
- if (register_android_os_cts_FileUtils(env)) {
- return JNI_ERR;
- }
-
return JNI_VERSION_1_4;
}
diff --git a/tests/tests/os/jni/android_os_cts_FileUtils.cpp b/tests/tests/os/jni/android_os_cts_FileUtils.cpp
deleted file mode 100644
index 2b7e282..0000000
--- a/tests/tests/os/jni/android_os_cts_FileUtils.cpp
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (C) 2011 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 <grp.h>
-#include <jni.h>
-#include <pwd.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <assert.h>
-
-static jclass gFileStatusClass;
-static jfieldID gFileStatusDevFieldID;
-static jfieldID gFileStatusInoFieldID;
-static jfieldID gFileStatusModeFieldID;
-static jfieldID gFileStatusNlinkFieldID;
-static jfieldID gFileStatusUidFieldID;
-static jfieldID gFileStatusGidFieldID;
-static jfieldID gFileStatusSizeFieldID;
-static jfieldID gFileStatusBlksizeFieldID;
-static jfieldID gFileStatusBlocksFieldID;
-static jfieldID gFileStatusAtimeFieldID;
-static jfieldID gFileStatusMtimeFieldID;
-static jfieldID gFileStatusCtimeFieldID;
-
-/*
- * Native methods used by
- * cts/tests/src/android/os/cts/FileUtils.java
- *
- * Copied from hidden API: frameworks/base/core/jni/android_os_FileUtils.cpp
- */
-
-jboolean android_os_cts_FileUtils_getFileStatus(JNIEnv* env, jobject thiz,
- jstring path, jobject fileStatus, jboolean statLinks)
-{
- const char* pathStr = env->GetStringUTFChars(path, NULL);
- jboolean ret = false;
- struct stat s;
-
- int res = statLinks == true ? lstat(pathStr, &s) : stat(pathStr, &s);
-
- if (res == 0) {
- ret = true;
- if (fileStatus != NULL) {
- env->SetIntField(fileStatus, gFileStatusDevFieldID, s.st_dev);
- env->SetIntField(fileStatus, gFileStatusInoFieldID, s.st_ino);
- env->SetIntField(fileStatus, gFileStatusModeFieldID, s.st_mode);
- env->SetIntField(fileStatus, gFileStatusNlinkFieldID, s.st_nlink);
- env->SetIntField(fileStatus, gFileStatusUidFieldID, s.st_uid);
- env->SetIntField(fileStatus, gFileStatusGidFieldID, s.st_gid);
- env->SetLongField(fileStatus, gFileStatusSizeFieldID, s.st_size);
- env->SetIntField(fileStatus, gFileStatusBlksizeFieldID, s.st_blksize);
- env->SetLongField(fileStatus, gFileStatusBlocksFieldID, s.st_blocks);
- env->SetLongField(fileStatus, gFileStatusAtimeFieldID, s.st_atime);
- env->SetLongField(fileStatus, gFileStatusMtimeFieldID, s.st_mtime);
- env->SetLongField(fileStatus, gFileStatusCtimeFieldID, s.st_ctime);
- }
- }
-
- env->ReleaseStringUTFChars(path, pathStr);
-
- return ret;
-}
-
-jstring android_os_cts_FileUtils_getUserName(JNIEnv* env, jobject thiz,
- jint uid)
-{
- struct passwd *pwd = getpwuid(uid);
- return env->NewStringUTF(pwd->pw_name);
-}
-
-jstring android_os_cts_FileUtils_getGroupName(JNIEnv* env, jobject thiz,
- jint gid)
-{
- struct group *grp = getgrgid(gid);
- return env->NewStringUTF(grp->gr_name);
-}
-
-jint android_os_cts_FileUtils_setPermissions(JNIEnv* env, jobject clazz,
- jstring file, jint mode)
-{
- const char *fileStr = env->GetStringUTFChars(file, NULL);
- if (fileStr == NULL) {
- return -1;
- }
-
- if (strlen(fileStr) <= 0) {
- env->ReleaseStringUTFChars(file, fileStr);
- return ENOENT;
- }
-
- jint returnValue = chmod(fileStr, mode) == 0 ? 0 : errno;
- env->ReleaseStringUTFChars(file, fileStr);
- return returnValue;
-}
-
-static JNINativeMethod gMethods[] = {
- { "getFileStatus", "(Ljava/lang/String;Landroid/os/cts/FileUtils$FileStatus;Z)Z",
- (void *) android_os_cts_FileUtils_getFileStatus },
- { "getUserName", "(I)Ljava/lang/String;",
- (void *) android_os_cts_FileUtils_getUserName },
- { "getGroupName", "(I)Ljava/lang/String;",
- (void *) android_os_cts_FileUtils_getGroupName },
- { "setPermissions", "(Ljava/lang/String;I)I",
- (void *) android_os_cts_FileUtils_setPermissions },
-};
-
-int register_android_os_cts_FileUtils(JNIEnv* env)
-{
- jclass clazz = env->FindClass("android/os/cts/FileUtils");
- assert(clazz != null);
-
- gFileStatusClass = env->FindClass("android/os/cts/FileUtils$FileStatus");
- assert(gFileStatusClass != null);
- gFileStatusDevFieldID = env->GetFieldID(gFileStatusClass, "dev", "I");
- gFileStatusInoFieldID = env->GetFieldID(gFileStatusClass, "ino", "I");
- gFileStatusModeFieldID = env->GetFieldID(gFileStatusClass, "mode", "I");
- gFileStatusNlinkFieldID = env->GetFieldID(gFileStatusClass, "nlink", "I");
- gFileStatusUidFieldID = env->GetFieldID(gFileStatusClass, "uid", "I");
- gFileStatusGidFieldID = env->GetFieldID(gFileStatusClass, "gid", "I");
- gFileStatusSizeFieldID = env->GetFieldID(gFileStatusClass, "size", "J");
- gFileStatusBlksizeFieldID = env->GetFieldID(gFileStatusClass, "blksize", "I");
- gFileStatusBlocksFieldID = env->GetFieldID(gFileStatusClass, "blocks", "J");
- gFileStatusAtimeFieldID = env->GetFieldID(gFileStatusClass, "atime", "J");
- gFileStatusMtimeFieldID = env->GetFieldID(gFileStatusClass, "mtime", "J");
- gFileStatusCtimeFieldID = env->GetFieldID(gFileStatusClass, "ctime", "J");
-
- return env->RegisterNatives(clazz, gMethods,
- sizeof(gMethods) / sizeof(JNINativeMethod));
-}
diff --git a/tests/tests/os/src/android/os/cts/AbiTest.java b/tests/tests/os/src/android/os/cts/AbiTest.java
index a342669..ee2c168 100644
--- a/tests/tests/os/src/android/os/cts/AbiTest.java
+++ b/tests/tests/os/src/android/os/cts/AbiTest.java
@@ -16,7 +16,7 @@
package android.os.cts;
-import android.os.cts.ReadElf;
+import android.cts.util.ReadElf;
import java.io.File;
diff --git a/tests/tests/os/src/android/os/cts/BuildVersionTest.java b/tests/tests/os/src/android/os/cts/BuildVersionTest.java
index e7ad28e..6069ee6 100644
--- a/tests/tests/os/src/android/os/cts/BuildVersionTest.java
+++ b/tests/tests/os/src/android/os/cts/BuildVersionTest.java
@@ -28,9 +28,8 @@
public class BuildVersionTest extends TestCase {
private static final String LOG_TAG = "BuildVersionTest";
- private static final Set<String> EXPECTED_RELEASES =
- new HashSet<String>(Arrays.asList("4.4W.1", "4.4W", "4.4", "4.4.1", "4.4.2", "4.4.3"));
- private static final int EXPECTED_SDK = 20;
+ private static final Set<String> EXPECTED_RELEASES = new HashSet<String>(Arrays.asList("5.0"));
+ private static final int EXPECTED_SDK = 21;
private static final String EXPECTED_BUILD_VARIANT = "user";
private static final String EXPECTED_TAG = "release-keys";
@@ -38,8 +37,8 @@
public void testReleaseVersion() {
// Applications may rely on the exact release version
assertAnyOf("BUILD.VERSION.RELEASE", Build.VERSION.RELEASE, EXPECTED_RELEASES);
- assertEquals("" + EXPECTED_SDK, Build.VERSION.SDK);
- assertEquals(EXPECTED_SDK, Build.VERSION.SDK_INT);
+ assertEquals("Build.VERSION.SDK", "" + EXPECTED_SDK, Build.VERSION.SDK);
+ assertEquals("Build.VERSION.SDK_INT", EXPECTED_SDK, Build.VERSION.SDK_INT);
}
public void testIncremental() {
diff --git a/tests/tests/os/src/android/os/cts/ConditionVariableTest.java b/tests/tests/os/src/android/os/cts/ConditionVariableTest.java
index 559f890..cad9dec 100644
--- a/tests/tests/os/src/android/os/cts/ConditionVariableTest.java
+++ b/tests/tests/os/src/android/os/cts/ConditionVariableTest.java
@@ -16,6 +16,7 @@
package android.os.cts;
import junit.framework.TestCase;
+import android.cts.util.TestThread;
import android.os.ConditionVariable;
public class ConditionVariableTest extends TestCase {
diff --git a/tests/tests/os/src/android/os/cts/DebugTest.java b/tests/tests/os/src/android/os/cts/DebugTest.java
index c05c78a..c097240 100644
--- a/tests/tests/os/src/android/os/cts/DebugTest.java
+++ b/tests/tests/os/src/android/os/cts/DebugTest.java
@@ -22,6 +22,7 @@
import java.util.logging.Logger;
import android.content.Context;
+import android.cts.util.TestThread;
import android.os.Debug;
import android.test.AndroidTestCase;
import dalvik.system.VMDebug;
diff --git a/tests/tests/os/src/android/os/cts/HandlerTest.java b/tests/tests/os/src/android/os/cts/HandlerTest.java
index fc775e4..7183d7e 100644
--- a/tests/tests/os/src/android/os/cts/HandlerTest.java
+++ b/tests/tests/os/src/android/os/cts/HandlerTest.java
@@ -17,6 +17,7 @@
package android.os.cts;
import junit.framework.TestCase;
+import android.cts.util.TestThread;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
diff --git a/tests/tests/os/src/android/os/cts/LocalService.java b/tests/tests/os/src/android/os/cts/LocalService.java
index 0353c23..cc427f8 100644
--- a/tests/tests/os/src/android/os/cts/LocalService.java
+++ b/tests/tests/os/src/android/os/cts/LocalService.java
@@ -18,6 +18,7 @@
import android.app.Service;
import android.content.Intent;
+import android.cts.util.IBinderParcelable;
import android.os.Binder;
import android.os.IBinder;
import android.os.Parcel;
diff --git a/tests/tests/os/src/android/os/cts/LooperTest.java b/tests/tests/os/src/android/os/cts/LooperTest.java
index e71b752..79a55c6 100644
--- a/tests/tests/os/src/android/os/cts/LooperTest.java
+++ b/tests/tests/os/src/android/os/cts/LooperTest.java
@@ -16,6 +16,7 @@
package android.os.cts;
+import android.cts.util.TestThread;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
diff --git a/tests/tests/os/src/android/os/cts/SeccompTest.java b/tests/tests/os/src/android/os/cts/SeccompTest.java
index e2ddcc2..6c49337 100644
--- a/tests/tests/os/src/android/os/cts/SeccompTest.java
+++ b/tests/tests/os/src/android/os/cts/SeccompTest.java
@@ -21,8 +21,8 @@
public class SeccompTest extends TestCase {
public void testSeccomp() {
- if (CpuFeatures.isArm64Cpu()) {
- return; // seccomp not supported on arm64
+ if (CpuFeatures.isArm64Cpu() || CpuFeatures.isArm64CpuIn32BitMode()) {
+ return; // seccomp not yet supported on arm64
}
if (OSFeatures.needsSeccompSupport()) {
assertTrue("Please enable seccomp support "
diff --git a/tests/tests/os/src/android/os/cts/TestThread.java b/tests/tests/os/src/android/os/cts/TestThread.java
deleted file mode 100644
index 1a28a20..0000000
--- a/tests/tests/os/src/android/os/cts/TestThread.java
+++ /dev/null
@@ -1,93 +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.os.cts;
-
-/**
- * Thread class for executing a Runnable containing assertions in a separate thread.
- * Uncaught exceptions in the Runnable are rethrown in the context of the the thread
- * calling the <code>runTest()</code> method.
- */
-public final class TestThread extends Thread {
- private Throwable mThrowable;
- private Runnable mTarget;
-
- public TestThread(Runnable target) {
- mTarget = target;
- }
-
- @Override
- public final void run() {
- try {
- mTarget.run();
- } catch (Throwable t) {
- mThrowable = t;
- }
- }
-
- /**
- * Run the target Runnable object and wait until the test finish or throw
- * out Exception if test fail.
- *
- * @param runTime
- * @throws Throwable
- */
- public void runTest(long runTime) throws Throwable {
- start();
- joinAndCheck(runTime);
- }
-
- /**
- * Get the Throwable object which is thrown when test running
- * @return The Throwable object
- */
- public Throwable getThrowable() {
- return mThrowable;
- }
-
- /**
- * Set the Throwable object which is thrown when test running
- * @param t The Throwable object
- */
- public void setThrowable(Throwable t) {
- mThrowable = t;
- }
-
- /**
- * Wait for the test thread to complete and throw the stored exception if there is one.
- *
- * @param runTime The time to wait for the test thread to complete.
- * @throws Throwable
- */
- public void joinAndCheck(long runTime) throws Throwable {
- this.join(runTime);
- if (this.isAlive()) {
- this.interrupt();
- this.join(runTime);
- throw new Exception("Thread did not finish within allotted time.");
- }
- checkException();
- }
-
- /**
- * Check whether there is an exception when running Runnable object.
- * @throws Throwable
- */
- public void checkException() throws Throwable {
- if (mThrowable != null) {
- throw mThrowable;
- }
- }
-}
diff --git a/tests/tests/os/src/android/os/storage/cts/StorageManagerTest.java b/tests/tests/os/src/android/os/storage/cts/StorageManagerTest.java
index 7d2d4ff..a8e8e64 100644
--- a/tests/tests/os/src/android/os/storage/cts/StorageManagerTest.java
+++ b/tests/tests/os/src/android/os/storage/cts/StorageManagerTest.java
@@ -22,7 +22,7 @@
import android.content.res.Resources;
import android.content.res.Resources.NotFoundException;
import android.os.Environment;
-import android.os.cts.FileUtils;
+import android.cts.util.FileUtils;
import android.os.storage.OnObbStateChangeListener;
import android.os.storage.StorageManager;
import android.test.AndroidTestCase;
diff --git a/tests/tests/permission/Android.mk b/tests/tests/permission/Android.mk
index 6d60499..6a7da5f 100644
--- a/tests/tests/permission/Android.mk
+++ b/tests/tests/permission/Android.mk
@@ -19,6 +19,9 @@
LOCAL_MODULE_TAGS := tests
+# Include both the 32 and 64 bit versions
+LOCAL_MULTILIB := both
+
LOCAL_JAVA_LIBRARIES := telephony-common
LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner guava android-ex-camera2
diff --git a/tests/tests/permission/src/android/permission/cts/NoLocationPermissionTest.java b/tests/tests/permission/src/android/permission/cts/NoLocationPermissionTest.java
index 93e26ac..8fd4a59 100644
--- a/tests/tests/permission/src/android/permission/cts/NoLocationPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/NoLocationPermissionTest.java
@@ -23,7 +23,6 @@
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
-import android.os.Build;
import android.os.Bundle;
import android.os.Looper;
import android.telephony.PhoneStateListener;
@@ -288,7 +287,7 @@
* {@link LocationManager#isProviderEnabled(String)} with given
* provider completes without an exception. (Note that under the conditions
* of these tests, that method threw SecurityException on OS levels before
- * {@link android.os.Build.VERSION_CODES#L}. See the method's javadoc for
+ * {@link android.os.Build.VERSION_CODES#LOLLIPOP}. See the method's javadoc for
* details.)
*
* @param provider the String provider name.
diff --git a/tests/tests/provider/Android.mk b/tests/tests/provider/Android.mk
index 81ff9ee..58a7516 100644
--- a/tests/tests/provider/Android.mk
+++ b/tests/tests/provider/Android.mk
@@ -18,6 +18,10 @@
# don't include this package in any target
LOCAL_MODULE_TAGS := optional
+
+# Include both the 32 and 64 bit versions of libs
+LOCAL_MULTILIB := both
+
# and when built explicitly put it in the data partition
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
@@ -25,6 +29,8 @@
LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner
+LOCAL_JNI_SHARED_LIBRARIES := libcts_jni
+
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_PACKAGE_NAME := CtsProviderTestCases
diff --git a/tests/tests/provider/src/android/provider/cts/ContactsContract_PhotoTest.java b/tests/tests/provider/src/android/provider/cts/ContactsContract_PhotoTest.java
index 45ba8b8..8c97c22 100644
--- a/tests/tests/provider/src/android/provider/cts/ContactsContract_PhotoTest.java
+++ b/tests/tests/provider/src/android/provider/cts/ContactsContract_PhotoTest.java
@@ -19,6 +19,7 @@
import android.content.ContentProviderClient;
import android.content.ContentResolver;
import android.content.Context;
+import android.cts.util.FileUtils;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Photo;
import android.provider.ContactsContract.Contacts;
diff --git a/tests/tests/provider/src/android/provider/cts/FileUtils.java b/tests/tests/provider/src/android/provider/cts/FileUtils.java
deleted file mode 100644
index 0766e6d..0000000
--- a/tests/tests/provider/src/android/provider/cts/FileUtils.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2011 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 java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-/** Bits and pieces copied from hidden API of android.os.FileUtils. */
-public class FileUtils {
-
- /**
- * Copy data from a source stream to destFile.
- * Return true if succeed, return false if failed.
- */
- public static boolean copyToFile(InputStream inputStream, File destFile) {
- try {
- if (destFile.exists()) {
- destFile.delete();
- }
- FileOutputStream out = new FileOutputStream(destFile);
- try {
- byte[] buffer = new byte[4096];
- int bytesRead;
- while ((bytesRead = inputStream.read(buffer)) >= 0) {
- out.write(buffer, 0, bytesRead);
- }
- } finally {
- out.flush();
- try {
- out.getFD().sync();
- } catch (IOException e) {
- }
- out.close();
- }
- return true;
- } catch (IOException e) {
- return false;
- }
- }
-
- public static void createFile(File file, int numBytes) throws IOException {
- File parentFile = file.getParentFile();
- if (parentFile != null) {
- parentFile.mkdirs();
- }
- byte[] buffer = new byte[numBytes];
- FileOutputStream output = new FileOutputStream(file);
- try {
- output.write(buffer);
- } finally {
- output.close();
- }
- }
-
- public static byte[] readInputStreamFully(InputStream is) {
- ByteArrayOutputStream os = new ByteArrayOutputStream();
- byte[] buffer = new byte[32768];
- int count;
- try {
- while ((count = is.read(buffer)) != -1) {
- os.write(buffer, 0, count);
- }
- is.close();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- return os.toByteArray();
- }
-}
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_AlbumsTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_AlbumsTest.java
index bad1108..84da62a 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_AlbumsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_AlbumsTest.java
@@ -21,6 +21,7 @@
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.res.AssetFileDescriptor;
+import android.cts.util.FileCopyHelper;
import android.database.Cursor;
import android.net.Uri;
import android.os.Environment;
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_FilesTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_FilesTest.java
index 67396d4..0eae82b 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_FilesTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_FilesTest.java
@@ -22,6 +22,7 @@
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
+import android.cts.util.FileCopyHelper;
import android.database.Cursor;
import android.net.Uri;
import android.os.Environment;
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 bc86b0a..7469f8e 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
@@ -21,6 +21,8 @@
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
+import android.cts.util.FileCopyHelper;
+import android.cts.util.FileUtils;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Images_ThumbnailsTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Images_ThumbnailsTest.java
index f161407..ec9db8b 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Images_ThumbnailsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Images_ThumbnailsTest.java
@@ -22,6 +22,7 @@
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
+import android.cts.util.FileCopyHelper;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_VideoTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_VideoTest.java
index 2c9ebd1..89de9c6 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_VideoTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_VideoTest.java
@@ -21,6 +21,7 @@
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
+import android.cts.util.FileCopyHelper;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore.Video;
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Video_MediaTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Video_MediaTest.java
index c3f5070..f84b75c 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Video_MediaTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Video_MediaTest.java
@@ -22,6 +22,8 @@
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
+import android.cts.util.FileCopyHelper;
+import android.cts.util.FileUtils;
import android.database.Cursor;
import android.net.Uri;
import android.os.Environment;
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Video_ThumbnailsTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Video_ThumbnailsTest.java
index e74cce4..b6175be 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Video_ThumbnailsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Video_ThumbnailsTest.java
@@ -21,6 +21,7 @@
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
+import android.cts.util.FileCopyHelper;
import android.database.Cursor;
import android.media.MediaCodecInfo;
import android.media.MediaCodecList;
diff --git a/tests/tests/provider/src/android/provider/cts/PhotoUtil.java b/tests/tests/provider/src/android/provider/cts/PhotoUtil.java
index 3f5f873..ec4fdef 100644
--- a/tests/tests/provider/src/android/provider/cts/PhotoUtil.java
+++ b/tests/tests/provider/src/android/provider/cts/PhotoUtil.java
@@ -19,6 +19,7 @@
import com.android.cts.provider.R;
import android.content.Context;
+import android.cts.util.FileUtils;
import java.io.InputStream;
diff --git a/tests/tests/renderscript/Android.mk b/tests/tests/renderscript/Android.mk
index 81434ee..245c5b9 100644
--- a/tests/tests/renderscript/Android.mk
+++ b/tests/tests/renderscript/Android.mk
@@ -22,6 +22,9 @@
# Don't include this package in any target.
LOCAL_MODULE_TAGS := optional
+# Include both the 32 and 64 bit versions
+LOCAL_MULTILIB := both
+
# When built, explicitly put it in the data partition.
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
diff --git a/tests/tests/rscpp/Android.mk b/tests/tests/rscpp/Android.mk
index f7d586f..60adc05 100644
--- a/tests/tests/rscpp/Android.mk
+++ b/tests/tests/rscpp/Android.mk
@@ -22,6 +22,9 @@
# Don't include this package in any target.
LOCAL_MODULE_TAGS := optional
+# Include both the 32 and 64 bit versions
+LOCAL_MULTILIB := both
+
# When built, explicitly put it in the data partition.
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
diff --git a/tests/tests/security/Android.mk b/tests/tests/security/Android.mk
index 10ad5f8..de58783 100644
--- a/tests/tests/security/Android.mk
+++ b/tests/tests/security/Android.mk
@@ -18,11 +18,14 @@
LOCAL_MODULE_TAGS := tests
+# Include both the 32 and 64 bit versions
+LOCAL_MULTILIB := both
+
LOCAL_STATIC_JAVA_LIBRARIES := ctstestserver ctstestrunner ctsdeviceutil guava
LOCAL_JAVA_LIBRARIES := android.test.runner
-LOCAL_JNI_SHARED_LIBRARIES := libctssecurity_jni
+LOCAL_JNI_SHARED_LIBRARIES := libctssecurity_jni libcts_jni
LOCAL_SRC_FILES := $(call all-java-files-under, src)\
src/android/security/cts/activity/ISecureRandomService.aidl
diff --git a/tests/tests/security/jni/Android.mk b/tests/tests/security/jni/Android.mk
index 84f62c0..fa862c1 100644
--- a/tests/tests/security/jni/Android.mk
+++ b/tests/tests/security/jni/Android.mk
@@ -31,7 +31,6 @@
android_security_cts_SeccompDeathTestService.cpp \
android_security_cts_SELinuxTest.cpp \
android_security_cts_MMapExecutableTest.cpp \
- android_security_cts_FileUtils.cpp \
android_security_cts_NetlinkSocket.cpp
LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
diff --git a/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp b/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp
index d9a5f28..0e91b4e 100644
--- a/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp
+++ b/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp
@@ -26,7 +26,6 @@
extern int register_android_security_cts_SeccompDeathTestService(JNIEnv*);
extern int register_android_security_cts_SELinuxTest(JNIEnv*);
extern int register_android_security_cts_MMapExecutableTest(JNIEnv* env);
-extern int register_android_security_cts_FileUtils(JNIEnv*);
jint JNI_OnLoad(JavaVM *vm, void *reserved) {
JNIEnv *env = NULL;
@@ -67,10 +66,6 @@
return JNI_ERR;
}
- if (register_android_security_cts_FileUtils(env)) {
- return JNI_ERR;
- }
-
if (register_android_security_cts_NetlinkSocket(env)) {
return JNI_ERR;
}
diff --git a/tests/tests/security/src/android/security/cts/AslrTest.java b/tests/tests/security/src/android/security/cts/AslrTest.java
index f1552f6..913b49b 100644
--- a/tests/tests/security/src/android/security/cts/AslrTest.java
+++ b/tests/tests/security/src/android/security/cts/AslrTest.java
@@ -24,7 +24,7 @@
import java.io.FileReader;
import java.io.IOException;
-import android.security.cts.ReadElf;
+import android.cts.util.ReadElf;
/**
* Verify that ASLR is properly enabled on Android Compatible devices.
diff --git a/tests/tests/security/src/android/security/cts/BannedFilesTest.java b/tests/tests/security/src/android/security/cts/BannedFilesTest.java
index a71dcce..8076f8e 100644
--- a/tests/tests/security/src/android/security/cts/BannedFilesTest.java
+++ b/tests/tests/security/src/android/security/cts/BannedFilesTest.java
@@ -16,7 +16,7 @@
package android.security.cts;
-import android.security.cts.FileUtils;
+import android.cts.util.FileUtils;
import junit.framework.TestCase;
diff --git a/tests/tests/security/src/android/security/cts/FileUtils.java b/tests/tests/security/src/android/security/cts/FileUtils.java
deleted file mode 100644
index 3708f68..0000000
--- a/tests/tests/security/src/android/security/cts/FileUtils.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (C) 2014 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.security.cts;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-/** Bits and pieces copied from hidden API of android.os.FileUtils. */
-public class FileUtils {
-
- public static final int S_IFMT = 0170000;
- public static final int S_IFSOCK = 0140000;
- public static final int S_IFLNK = 0120000;
- public static final int S_IFREG = 0100000;
- public static final int S_IFBLK = 0060000;
- public static final int S_IFDIR = 0040000;
- public static final int S_IFCHR = 0020000;
- public static final int S_IFIFO = 0010000;
-
- public static final int S_ISUID = 0004000;
- public static final int S_ISGID = 0002000;
- public static final int S_ISVTX = 0001000;
-
- public static final int S_IRWXU = 00700;
- public static final int S_IRUSR = 00400;
- public static final int S_IWUSR = 00200;
- public static final int S_IXUSR = 00100;
-
- public static final int S_IRWXG = 00070;
- public static final int S_IRGRP = 00040;
- public static final int S_IWGRP = 00020;
- public static final int S_IXGRP = 00010;
-
- public static final int S_IRWXO = 00007;
- public static final int S_IROTH = 00004;
- public static final int S_IWOTH = 00002;
- public static final int S_IXOTH = 00001;
-
- static {
- System.loadLibrary("ctssecurity_jni");
- }
-
- public static class FileStatus {
-
- public int dev;
- public int ino;
- public int mode;
- public int nlink;
- public int uid;
- public int gid;
- public int rdev;
- public long size;
- public int blksize;
- public long blocks;
- public long atime;
- public long mtime;
- public long ctime;
-
- public boolean hasModeFlag(int flag) {
- if (((S_IRWXU | S_IRWXG | S_IRWXO) & flag) != flag) {
- throw new IllegalArgumentException("Inappropriate flag " + flag);
- }
- return (mode & flag) == flag;
- }
-
- public boolean isOfType(int type) {
- if ((type & S_IFMT) != type) {
- throw new IllegalArgumentException("Unknown type " + type);
- }
- return (mode & S_IFMT) == type;
- }
- }
-
- /**
- * @param path of the file to stat
- * @param status object to set the fields on
- * @param statLinks or don't stat links (lstat vs stat)
- * @return whether or not we were able to stat the file
- */
- public native static boolean getFileStatus(String path, FileStatus status, boolean statLinks);
-
- public native static String getUserName(int uid);
-
- public native static String getGroupName(int gid);
-
- public native static int setPermissions(String file, int mode);
-
- /**
- * Copy data from a source stream to destFile.
- * Return true if succeed, return false if failed.
- */
- public static boolean copyToFile(InputStream inputStream, File destFile) {
- try {
- if (destFile.exists()) {
- destFile.delete();
- }
- FileOutputStream out = new FileOutputStream(destFile);
- try {
- byte[] buffer = new byte[4096];
- int bytesRead;
- while ((bytesRead = inputStream.read(buffer)) >= 0) {
- out.write(buffer, 0, bytesRead);
- }
- } finally {
- out.flush();
- try {
- out.getFD().sync();
- } catch (IOException e) {
- }
- out.close();
- }
- return true;
- } catch (IOException e) {
- return false;
- }
- }
-
- public static void createFile(File file, int numBytes) throws IOException {
- File parentFile = file.getParentFile();
- if (parentFile != null) {
- parentFile.mkdirs();
- }
- byte[] buffer = new byte[numBytes];
- FileOutputStream output = new FileOutputStream(file);
- try {
- output.write(buffer);
- } finally {
- output.close();
- }
- }
-
- public static byte[] readInputStreamFully(InputStream is) {
- ByteArrayOutputStream os = new ByteArrayOutputStream();
- byte[] buffer = new byte[32768];
- int count;
- try {
- while ((count = is.read(buffer)) != -1) {
- os.write(buffer, 0, count);
- }
- is.close();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- return os.toByteArray();
- }
-}
diff --git a/tests/tests/security/src/android/security/cts/ReadElf.java b/tests/tests/security/src/android/security/cts/ReadElf.java
deleted file mode 100644
index a9a4e3c..0000000
--- a/tests/tests/security/src/android/security/cts/ReadElf.java
+++ /dev/null
@@ -1,523 +0,0 @@
-/*
- * Copyright (C) 2014 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.security.cts;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * A poor man's implementation of the readelf command. This program is
- * designed to parse ELF (Executable and Linkable Format) files.
- */
-public class ReadElf implements AutoCloseable {
- /** The magic values for the ELF identification. */
- private static final byte[] ELF_IDENT = {
- (byte) 0x7F, (byte) 'E', (byte) 'L', (byte) 'F',
- };
-
- private static final int EI_CLASS = 4;
- private static final int EI_DATA = 5;
-
- private static final int EM_386 = 3;
- private static final int EM_MIPS = 8;
- private static final int EM_ARM = 40;
- // http://en.wikipedia.org/wiki/Qualcomm_Hexagon
- private static final int EM_QDSP6 = 164;
-
- /** Size of the e_ident[] structure in the ELF header. */
- private static final int EI_NIDENT = 16;
-
- /** Offset from end of ident structure in half-word sizes. */
- private static final int OFFSET_TYPE = 0;
-
- /** Machine type. */
- private static final int OFFSET_MACHINE = 1;
-
- /** ELF version. */
- private static final int OFFSET_VERSION = 2;
-
- /**
- * The offset to which the system transfers control. e.g., the first thing
- * executed.
- */
- private static final int OFFSET_ENTRY = 4;
-
- /** Program header offset in bytes. */
- private static final int OFFSET_PHOFF = 6;
-
- /** Segment header offset in bytes. */
- private static final int OFFSET_SHOFF = 8;
-
- /** Processor-specific flags for binary. */
- private static final int OFFSET_FLAGS = 10;
-
- /** ELF header size in bytes. */
- private static final int OFFSET_EHSIZE = 12;
-
- /** All program headers entry size in bytes. */
- private static final int OFFSET_PHENTSIZE = 13;
-
- /** Number of program headers in ELF. */
- private static final int OFFSET_PHNUM = 14;
-
- /** All segment headers entry size in bytes. */
- private static final int OFFSET_SHENTSIZE = 15;
-
- /** Number of segment headers in ELF. */
- private static final int OFFSET_SHNUM = 16;
-
- /** The section header index that refers to string table. */
- private static final int OFFSET_SHSTRNDX = 17;
-
- /** Program header offset for type of this program header. */
- private static final int PHOFF_TYPE = 0;
-
- /** Program header offset for absolute offset in file. */
- private static final int PHOFF_OFFSET = 2;
-
- /** Program header offset for virtual address. */
- private static final int PHOFF_VADDR = 4;
-
- /** Program header offset for physical address. */
- private static final int PHOFF_PADDR = 6;
-
- /** Program header offset for file size in bytes. */
- private static final int PHOFF_FILESZ = 8;
-
- /** Program header offset for memory size in bytes. */
- private static final int PHOFF_MEMSZ = 10;
-
- /** Program header offset for flags. */
- private static final int PHOFF_FLAGS = 12;
-
- /**
- * Program header offset for required alignment. 0 or 1 means no alignment
- * necessary.
- */
- private static final int PHOFF_ALIGN = 14;
-
- /** Index into string pool for segment name. */
- private static final long SHOFF_NAME = 0;
-
- /** Segment header offset for type (half-words) */
- private static final long SHOFF_TYPE = 2;
-
- /** Segment header offset for offset (meta!) (half-words) */
- private static final long SHOFF_OFFSET = 8;
-
- /** Segment header offset for size (half-words) */
- private static final long SHOFF_SIZE = 10;
-
- /** Data is presented in LSB format. */
- private static final int ELFDATA2LSB = 1;
-
- /** Date is presented in MSB format. */
- private static final int ELFDATA2MSB = 2;
-
- private static final int ELFCLASS32 = 1;
-
- private static final int ELFCLASS64 = 2;
-
- private static final long PT_LOAD = 1;
-
- /** Section Type: Symbol Table */
- private static final int SHT_SYMTAB = 2;
-
- /** Section Type: String Table */
- private static final int SHT_STRTAB = 3;
-
- /** Section Type: Dynamic **/
- private static final int SHT_DYNAMIC = 6;
-
- /** Section Type: Dynamic Symbol Table */
- private static final int SHT_DYNSYM = 11;
-
- /** Symbol Table Entry: Name offset */
- private static final int SYMTAB_NAME = 0;
-
- /** Symbol Table Entry: SymTab Info */
- private static final int SYMTAB_ST_INFO = 6;
-
- /** Symbol Table Entry size (half-words) */
- private static final int SYMTAB_ENTRY_HALFWORD_SIZE = 7;
-
- /**
- * Symbol Table Entry size (extra in bytes) to cover "st_info" and
- * "st_other"
- */
- private static final int SYMTAB_ENTRY_BYTE_EXTRA_SIZE = 2;
-
- public static class Symbol {
- public static final int STB_LOCAL = 0;
-
- public static final int STB_GLOBAL = 1;
-
- public static final int STB_WEAK = 2;
-
- public static final int STB_LOPROC = 13;
-
- public static final int STB_HIPROC = 15;
-
- public final String name;
-
- public final int bind;
-
- public final int type;
-
- Symbol(String name, int st_info) {
- this.name = name;
- this.bind = (st_info >> 4) & 0x0F;
- this.type = st_info & 0x0F;
- }
- };
-
- private final String mPath;
- private final RandomAccessFile mFile;
- private final byte[] mBuffer = new byte[512];
- private int mEndian;
- private boolean mIsDynamic;
- private boolean mIsPIE;
- private int mType;
- private int mWordSize;
- private int mHalfWordSize;
-
- /** Symbol Table offset */
- private long mSymTabOffset;
-
- /** Symbol Table size */
- private long mSymTabSize;
-
- /** Dynamic Symbol Table offset */
- private long mDynSymOffset;
-
- /** Dynamic Symbol Table size */
- private long mDynSymSize;
-
- /** Section Header String Table offset */
- private long mShStrTabOffset;
-
- /** Section Header String Table size */
- private long mShStrTabSize;
-
- /** String Table offset */
- private long mStrTabOffset;
-
- /** String Table size */
- private long mStrTabSize;
-
- /** Dynamic String Table offset */
- private long mDynStrOffset;
-
- /** Dynamic String Table size */
- private long mDynStrSize;
-
- /** Symbol Table symbol names */
- private Map<String, Symbol> mSymbols;
-
- /** Dynamic Symbol Table symbol names */
- private Map<String, Symbol> mDynamicSymbols;
-
- public static ReadElf read(File file) throws IOException {
- return new ReadElf(file);
- }
-
- public boolean isDynamic() {
- return mIsDynamic;
- }
-
- public int getType() {
- return mType;
- }
-
- public boolean isPIE() {
- return mIsPIE;
- }
-
- private ReadElf(File file) throws IOException {
- mPath = file.getPath();
- mFile = new RandomAccessFile(file, "r");
-
- if (mFile.length() < EI_NIDENT) {
- throw new IllegalArgumentException("Too small to be an ELF file: " + file);
- }
-
- readIdent();
- readHeader();
- }
-
- public void close() {
- try {
- mFile.close();
- } catch (IOException ignored) {
- }
- }
-
- protected void finalize() throws Throwable {
- try {
- close();
- } finally {
- super.finalize();
- }
- }
-
- private void readHeader() throws IOException {
- mType = readHalf(getHeaderOffset(OFFSET_TYPE));
- int e_machine = readHalf(getHeaderOffset(OFFSET_MACHINE));
- if (e_machine != EM_386 && e_machine != EM_MIPS && e_machine != EM_ARM &&
- e_machine != EM_QDSP6) {
- throw new IOException("Invalid ELF e_machine: " + e_machine + ": " + mPath);
- }
-
- final long shOffset = readWord(getHeaderOffset(OFFSET_SHOFF));
- final int shNumber = readHalf(getHeaderOffset(OFFSET_SHNUM));
- final int shSize = readHalf(getHeaderOffset(OFFSET_SHENTSIZE));
- final int shStrIndex = readHalf(getHeaderOffset(OFFSET_SHSTRNDX));
-
- readSectionHeaders(shOffset, shNumber, shSize, shStrIndex);
-
- final long phOffset = readWord(getHeaderOffset(OFFSET_PHOFF));
- final int phNumber = readHalf(getHeaderOffset(OFFSET_PHNUM));
- final int phSize = readHalf(getHeaderOffset(OFFSET_PHENTSIZE));
-
- readProgramHeaders(phOffset, phNumber, phSize);
- }
-
- private void readSectionHeaders(long tableOffset, int shNumber, int shSize, int shStrIndex)
- throws IOException {
- // Read the Section Header String Table offset first.
- {
- final long shStrTabShOffset = tableOffset + shStrIndex * shSize;
- final long type = readWord(shStrTabShOffset + mHalfWordSize * SHOFF_TYPE);
-
- if (type == SHT_STRTAB) {
- mShStrTabOffset = readWord(shStrTabShOffset + mHalfWordSize * SHOFF_OFFSET);
- mShStrTabSize = readWord(shStrTabShOffset + mHalfWordSize * SHOFF_SIZE);
- }
- }
-
- for (int i = 0; i < shNumber; i++) {
- // Don't bother to re-read the Section Header StrTab.
- if (i == shStrIndex) {
- continue;
- }
-
- final long shOffset = tableOffset + i * shSize;
-
- final long type = readWord(shOffset + mHalfWordSize * SHOFF_TYPE);
- if ((type == SHT_SYMTAB) || (type == SHT_DYNSYM)) {
- final long nameOffset = readWord(shOffset + mHalfWordSize * SHOFF_NAME);
- final long offset = readWord(shOffset + mHalfWordSize * SHOFF_OFFSET);
- final long size = readWord(shOffset + mHalfWordSize * SHOFF_SIZE);
-
- final String symTabName = readShStrTabEntry(nameOffset);
- if (".symtab".equals(symTabName)) {
- mSymTabOffset = offset;
- mSymTabSize = size;
- } else if (".dynsym".equals(symTabName)) {
- mDynSymOffset = offset;
- mDynSymSize = size;
- }
- } else if (type == SHT_STRTAB) {
- final long nameOffset = readWord(shOffset + mHalfWordSize * SHOFF_NAME);
- final long offset = readWord(shOffset + mHalfWordSize * SHOFF_OFFSET);
- final long size = readWord(shOffset + mHalfWordSize * SHOFF_SIZE);
-
- final String strTabName = readShStrTabEntry(nameOffset);
- if (".strtab".equals(strTabName)) {
- mStrTabOffset = offset;
- mStrTabSize = size;
- } else if (".dynstr".equals(strTabName)) {
- mDynStrOffset = offset;
- mDynStrSize = size;
- }
- } else if (type == SHT_DYNAMIC) {
- mIsDynamic = true;
- }
- }
- }
-
- private void readProgramHeaders(long phOffset, int phNumber, int phSize) throws IOException {
- for (int i = 0; i < phNumber; i++) {
- final long baseOffset = phOffset + i * phSize;
- final long type = readWord(baseOffset);
- if (type == PT_LOAD) {
- final long virtAddress = readWord(baseOffset + mHalfWordSize * PHOFF_VADDR);
- if (virtAddress == 0) {
- mIsPIE = true;
- }
- }
- }
- }
-
- private void readSymbolTable(Map<String, Symbol> symbolMap, long symStrOffset, long symStrSize,
- long symOffset, long symSize) throws IOException {
- final long symEnd = symOffset + symSize;
- for (long off = symOffset; off < symEnd; off += SYMTAB_ENTRY_HALFWORD_SIZE * mHalfWordSize
- + SYMTAB_ENTRY_BYTE_EXTRA_SIZE) {
- long strOffset = readWord(off + SYMTAB_NAME);
- if (strOffset == 0) {
- continue;
- }
-
- final String symName = readStrTabEntry(symStrOffset, symStrSize, strOffset);
- if (symName != null) {
- final int st_info = readByte(off + SYMTAB_ST_INFO);
- symbolMap.put(symName, new Symbol(symName, st_info));
- }
- }
- }
-
- private String readShStrTabEntry(long strOffset) throws IOException {
- if ((mShStrTabOffset == 0) || (strOffset < 0) || (strOffset >= mShStrTabSize)) {
- return null;
- }
-
- return readString(mShStrTabOffset + strOffset);
- }
-
- private String readStrTabEntry(long tableOffset, long tableSize, long strOffset)
- throws IOException {
- if ((tableOffset == 0) || (strOffset < 0) || (strOffset >= tableSize)) {
- return null;
- }
-
- return readString(tableOffset + strOffset);
- }
-
- private int getHeaderOffset(int halfWorldOffset) {
- return EI_NIDENT + halfWorldOffset * mHalfWordSize;
- }
-
- private int readByte(long offset) throws IOException {
- mFile.seek(offset);
- mFile.readFully(mBuffer, 0, 1);
-
- return mBuffer[0] & 0xff;
- }
-
- private int readHalf(long offset) throws IOException {
- mFile.seek(offset);
- mFile.readFully(mBuffer, 0, mWordSize);
-
- final int answer;
- if (mEndian == ELFDATA2LSB) {
- answer = mBuffer[1] << 8 | (mBuffer[0] & 0xff);
- } else {
- answer = mBuffer[0] << 8 | (mBuffer[1] & 0xff);
- }
-
- return answer;
- }
-
- private long readWord(long offset) throws IOException {
- mFile.seek(offset);
- mFile.readFully(mBuffer, 0, mWordSize);
-
- int answer = 0;
- if (mEndian == ELFDATA2LSB) {
- for (int i = mWordSize - 1; i >= 0; i--) {
- answer = (answer << 8) | (mBuffer[i] & 0xff);
- }
- } else {
- final int N = mWordSize - 1;
- for (int i = 0; i <= N; i++) {
- answer = (answer << 8) | (mBuffer[i] & 0xff);
- }
- }
-
- return answer;
- }
-
- private String readString(long offset) throws IOException {
- mFile.seek(offset);
- mFile.readFully(mBuffer, 0, (int) Math.min(mBuffer.length, mFile.length() - offset));
-
- for (int i = 0; i < mBuffer.length; i++) {
- if (mBuffer[i] == 0) {
- return new String(mBuffer, 0, i);
- }
- }
-
- return null;
- }
-
- private void readIdent() throws IOException {
- mFile.seek(0);
- mFile.readFully(mBuffer, 0, EI_NIDENT);
-
- if ((mBuffer[0] != ELF_IDENT[0]) || (mBuffer[1] != ELF_IDENT[1])
- || (mBuffer[2] != ELF_IDENT[2]) || (mBuffer[3] != ELF_IDENT[3])) {
- throw new IllegalArgumentException("Invalid ELF file: " + mPath);
- }
-
- int elfClass = mBuffer[EI_CLASS];
- if (elfClass == ELFCLASS32) {
- mWordSize = 4;
- mHalfWordSize = 2;
- } else if (elfClass == ELFCLASS64) {
- throw new IOException("Unsupported ELFCLASS64 file: " + mPath);
- } else {
- throw new IOException("Invalid ELF EI_CLASS: " + elfClass + ": " + mPath);
- }
-
- mEndian = mBuffer[EI_DATA];
- if (mEndian == ELFDATA2LSB) {
- } else if (mEndian == ELFDATA2MSB) {
- throw new IOException("Unsupported ELFDATA2MSB file: " + mPath);
- } else {
- throw new IOException("Invalid ELF EI_DATA: " + mEndian + ": " + mPath);
- }
- }
-
- public Symbol getSymbol(String name) {
- if ((mSymTabOffset == 0) && (mSymTabSize == 0)) {
- return null;
- }
-
- if (mSymbols == null) {
- mSymbols = new HashMap<String, Symbol>();
- try {
- readSymbolTable(mSymbols, mStrTabOffset, mStrTabSize, mSymTabOffset, mSymTabSize);
- } catch (IOException e) {
- return null;
- }
- }
-
- return mSymbols.get(name);
- }
-
- public Symbol getDynamicSymbol(String name) {
- if ((mDynSymOffset == 0) && (mDynSymSize == 0)) {
- return null;
- }
-
- if (mDynamicSymbols == null) {
- mDynamicSymbols = new HashMap<String, Symbol>();
- try {
- readSymbolTable(mDynamicSymbols, mDynStrOffset, mDynStrSize, mDynSymOffset,
- mDynSymSize);
- } catch (IOException e) {
- return null;
- }
- }
-
- return mDynamicSymbols.get(name);
- }
-}
diff --git a/tests/tests/telephony/Android.mk b/tests/tests/telephony/Android.mk
index e15d0d5..85864f9 100644
--- a/tests/tests/telephony/Android.mk
+++ b/tests/tests/telephony/Android.mk
@@ -24,7 +24,7 @@
LOCAL_JAVA_LIBRARIES := telephony-common
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner ctsdeviceutil
LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/tests/tests/telephony/src/android/telephony/cts/CellLocationTest.java b/tests/tests/telephony/src/android/telephony/cts/CellLocationTest.java
index 00c9844..c1f5757 100644
--- a/tests/tests/telephony/src/android/telephony/cts/CellLocationTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/CellLocationTest.java
@@ -17,6 +17,8 @@
import android.content.Context;
+import android.cts.util.ReadElf;
+import android.cts.util.TestThread;
import android.os.Looper;
import android.net.ConnectivityManager;
import android.telephony.CellLocation;
diff --git a/tests/tests/telephony/src/android/telephony/cts/PhoneStateListenerTest.java b/tests/tests/telephony/src/android/telephony/cts/PhoneStateListenerTest.java
index 9d8f842..f0f977a 100644
--- a/tests/tests/telephony/src/android/telephony/cts/PhoneStateListenerTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/PhoneStateListenerTest.java
@@ -16,6 +16,8 @@
package android.telephony.cts;
import android.content.Context;
+import android.cts.util.ReadElf;
+import android.cts.util.TestThread;
import android.os.Looper;
import android.telephony.CellLocation;
import android.telephony.PhoneStateListener;
diff --git a/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java b/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java
index b9c720c..8575c32 100644
--- a/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java
@@ -19,6 +19,8 @@
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.content.pm.PackageManager;
+import android.cts.util.ReadElf;
+import android.cts.util.TestThread;
import android.net.ConnectivityManager;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
@@ -86,13 +88,11 @@
}
};
mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_CELL_LOCATION);
-
+ CellLocation.requestLocationUpdate();
Looper.loop();
}
});
t.start();
-
- CellLocation.requestLocationUpdate();
synchronized (mLock) {
while (!mOnCellLocationChangedCalled) {
mLock.wait();
@@ -104,24 +104,21 @@
t = new TestThread(new Runnable() {
public void run() {
Looper.prepare();
-
// unregister the listener
mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_NONE);
mOnCellLocationChangedCalled = false;
// unregister again, to make sure doing so does not call the listener
mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_NONE);
-
+ CellLocation.requestLocationUpdate();
Looper.loop();
}
});
- t.start();
- CellLocation.requestLocationUpdate();
+ t.start();
synchronized (mLock) {
mLock.wait(TOLERANCE);
}
- //Fix me: unregister for listener is not support today. Will be added soon
- //assertFalse(mOnCellLocationChangedCalled);
+ assertFalse(mOnCellLocationChangedCalled);
}
/**
diff --git a/tests/tests/text/Android.mk b/tests/tests/text/Android.mk
index df2d324..7b2def1 100644
--- a/tests/tests/text/Android.mk
+++ b/tests/tests/text/Android.mk
@@ -23,7 +23,7 @@
LOCAL_JAVA_LIBRARIES := android.test.runner
-LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner
+LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctsdeviceutillegacy ctstestrunner
LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/tests/tests/text/AndroidManifest.xml b/tests/tests/text/AndroidManifest.xml
index f247f82..99a6ad5 100644
--- a/tests/tests/text/AndroidManifest.xml
+++ b/tests/tests/text/AndroidManifest.xml
@@ -64,14 +64,6 @@
</intent-filter>
</activity>
- <activity android:name="android.text.method.cts.CtsActivity"
- android:label="CtsActivity">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
- </intent-filter>
- </activity>
-
</application>
<instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
diff --git a/tests/tests/text/src/android/text/cts/EmojiCtsActivity.java b/tests/tests/text/src/android/text/cts/EmojiCtsActivity.java
index eb88426..195bdf1 100644
--- a/tests/tests/text/src/android/text/cts/EmojiCtsActivity.java
+++ b/tests/tests/text/src/android/text/cts/EmojiCtsActivity.java
@@ -20,6 +20,7 @@
import android.app.Activity;
import android.os.Bundle;
+import android.cts.util.NullWebViewUtils;
import android.webkit.WebView;
public class EmojiCtsActivity extends Activity {
diff --git a/tests/tests/text/src/android/text/cts/EmojiTest.java b/tests/tests/text/src/android/text/cts/EmojiTest.java
index b753739..e1249f3 100644
--- a/tests/tests/text/src/android/text/cts/EmojiTest.java
+++ b/tests/tests/text/src/android/text/cts/EmojiTest.java
@@ -17,6 +17,7 @@
package android.text.cts;
import android.content.Context;
+import android.cts.util.NullWebViewUtils;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
@@ -27,6 +28,7 @@
import android.view.View;
import android.widget.TextView;
import android.widget.EditText;
+import android.webkit.cts.WebViewOnUiThread;
public class EmojiTest extends ActivityInstrumentationTestCase2<EmojiCtsActivity> {
diff --git a/tests/tests/text/src/android/text/cts/NullWebViewUtils.java b/tests/tests/text/src/android/text/cts/NullWebViewUtils.java
deleted file mode 100644
index 86d0843..0000000
--- a/tests/tests/text/src/android/text/cts/NullWebViewUtils.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2010 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.cts;
-
-import android.content.Context;
-import android.content.pm.PackageManager;
-
-/**
- * Utilities to enable the android.webkit.* CTS tests (and others that rely on a functioning
- * android.webkit.WebView implementation) to determine whether a functioning WebView is present
- * on the device or not.
- *
- * Test cases that require android.webkit.* classes should wrap their first usage of WebView in a
- * try catch block, and pass any exception that is thrown to
- * NullWebViewUtils.determineIfWebViewAvailable. The return value of
- * NullWebViewUtils.isWebViewAvailable will then determine if the test should expect to be able to
- * use a WebView.
- */
-public class NullWebViewUtils {
-
- private static boolean sWebViewUnavailable;
-
- /**
- * @param context Current Activity context, used to query the PackageManager.
- * @param t An exception thrown by trying to invoke android.webkit.* APIs.
- */
- public static void determineIfWebViewAvailable(Context context, Throwable t) {
- sWebViewUnavailable = !hasWebViewFeature(context) && checkCauseWasUnsupportedOperation(t);
- }
-
- /**
- * After calling determineIfWebViewAvailable, this returns whether a WebView is available on the
- * device and wheter the test can rely on it.
- * @return True iff. PackageManager determined that there is no WebView on the device and the
- * exception thrown from android.webkit.* was UnsupportedOperationException.
- */
- public static boolean isWebViewAvailable() {
- return !sWebViewUnavailable;
- }
-
- private static boolean hasWebViewFeature(Context context) {
- // Query the system property that determins if there is a functional WebView on the device.
- PackageManager pm = context.getPackageManager();
- return pm.hasSystemFeature(PackageManager.FEATURE_WEBVIEW);
- }
-
- private static boolean checkCauseWasUnsupportedOperation(Throwable t) {
- if (t == null) return false;
- while (t.getCause() != null) {
- t = t.getCause();
- }
- return t instanceof UnsupportedOperationException;
- }
-
- /**
- * Some CTS tests (by design) first use android.webkit.* from a background thread. This helper
- * allows the test to catch the UnsupportedOperationException from that background thread, and
- * then query the result from the test main thread.
- */
- public static class NullWebViewFromThreadExceptionHandler
- implements Thread.UncaughtExceptionHandler {
- private Throwable mPendingException;
-
- @Override
- public void uncaughtException(Thread t, Throwable e) {
- mPendingException = e;
- }
-
- public boolean isWebViewAvailable(Context context) {
- return hasWebViewFeature(context) ||
- !checkCauseWasUnsupportedOperation(mPendingException);
- }
- }
-}
\ No newline at end of file
diff --git a/tests/tests/text/src/android/text/cts/WebViewOnUiThread.java b/tests/tests/text/src/android/text/cts/WebViewOnUiThread.java
deleted file mode 100644
index 3d62ce4..0000000
--- a/tests/tests/text/src/android/text/cts/WebViewOnUiThread.java
+++ /dev/null
@@ -1,980 +0,0 @@
-/*
- * Copyright (C) 2011 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.cts;
-
-import android.cts.util.PollingCheck;
-import android.graphics.Bitmap;
-import android.graphics.Picture;
-import android.graphics.Rect;
-import android.os.Bundle;
-import android.os.Looper;
-import android.os.Message;
-import android.os.SystemClock;
-import android.print.PrintDocumentAdapter;
-import android.test.InstrumentationTestCase;
-import android.util.DisplayMetrics;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewParent;
-import android.webkit.DownloadListener;
-import android.webkit.CookieManager;
-import android.webkit.ValueCallback;
-import android.webkit.WebBackForwardList;
-import android.webkit.WebChromeClient;
-import android.webkit.WebSettings;
-import android.webkit.WebView.HitTestResult;
-import android.webkit.WebView.PictureListener;
-import android.webkit.WebView;
-import android.webkit.WebViewClient;
-
-import junit.framework.Assert;
-
-import java.io.File;
-import java.util.concurrent.Callable;
-import java.util.Map;
-
-/**
- * Many tests need to run WebView code in the UI thread. This class
- * wraps a WebView so that calls are ensured to arrive on the UI thread.
- *
- * All methods may be run on either the UI thread or test thread.
- */
-public class WebViewOnUiThread {
- /**
- * The maximum time, in milliseconds (10 seconds) to wait for a load
- * to be triggered.
- */
- private static final long LOAD_TIMEOUT = 10000;
-
- /**
- * Set to true after onPageFinished is called.
- */
- private boolean mLoaded;
-
- /**
- * Set to true after onNewPicture is called. Reset when onPageStarted
- * is called.
- */
- private boolean mNewPicture;
-
- /**
- * The progress, in percentage, of the page load. Valid values are between
- * 0 and 100.
- */
- private int mProgress;
-
- /**
- * The test that this class is being used in. Used for runTestOnUiThread.
- */
- private InstrumentationTestCase mTest;
-
- /**
- * The WebView that calls will be made on.
- */
- private WebView mWebView;
-
- /**
- * Initializes the webView with a WebViewClient, WebChromeClient,
- * and PictureListener to prepare for loadUrlAndWaitForCompletion.
- *
- * A new WebViewOnUiThread should be called during setUp so as to
- * reinitialize between calls.
- *
- * @param test The test in which this is being run.
- * @param webView The webView that the methods should call.
- * @see loadUrlAndWaitForCompletion
- */
- public WebViewOnUiThread(InstrumentationTestCase test, WebView webView) {
- mTest = test;
- mWebView = webView;
- final WebViewClient webViewClient = new WaitForLoadedClient(this);
- final WebChromeClient webChromeClient = new WaitForProgressClient(this);
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.setWebViewClient(webViewClient);
- mWebView.setWebChromeClient(webChromeClient);
- mWebView.setPictureListener(new WaitForNewPicture());
- }
- });
- }
-
- /**
- * Called after a test is complete and the WebView should be disengaged from
- * the tests.
- */
- public void cleanUp() {
- clearHistory();
- clearCache(true);
- setPictureListener(null);
- setWebChromeClient(null);
- setWebViewClient(null);
- }
-
- /**
- * Called from WaitForNewPicture, this is used to indicate that
- * the page has been drawn.
- */
- synchronized public void onNewPicture() {
- mNewPicture = true;
- this.notifyAll();
- }
-
- /**
- * Called from WaitForLoadedClient, this is used to clear the picture
- * draw state so that draws before the URL begins loading don't count.
- */
- synchronized public void onPageStarted() {
- mNewPicture = false; // Earlier paints won't count.
- }
-
- /**
- * Called from WaitForLoadedClient, this is used to indicate that
- * the page is loaded, but not drawn yet.
- */
- synchronized public void onPageFinished() {
- mLoaded = true;
- this.notifyAll();
- }
-
- /**
- * Called from the WebChrome client, this sets the current progress
- * for a page.
- * @param progress The progress made so far between 0 and 100.
- */
- synchronized public void onProgressChanged(int progress) {
- mProgress = progress;
- this.notifyAll();
- }
-
- public void setWebViewClient(final WebViewClient webViewClient) {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.setWebViewClient(webViewClient);
- }
- });
- }
-
- public void setWebChromeClient(final WebChromeClient webChromeClient) {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.setWebChromeClient(webChromeClient);
- }
- });
- }
-
- public void setPictureListener(final PictureListener pictureListener) {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.setPictureListener(pictureListener);
- }
- });
- }
-
- public void setNetworkAvailable(final boolean available) {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.setNetworkAvailable(available);
- }
- });
- }
-
- public void setDownloadListener(final DownloadListener listener) {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.setDownloadListener(listener);
- }
- });
- }
-
- public void setBackgroundColor(final int color) {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.setBackgroundColor(color);
- }
- });
- }
-
- public void clearCache(final boolean includeDiskFiles) {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.clearCache(includeDiskFiles);
- }
- });
- }
-
- public void clearHistory() {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.clearHistory();
- }
- });
- }
-
- public void requestFocus() {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.requestFocus();
- }
- });
- }
-
- public boolean canZoomIn() {
- return getValue(new ValueGetter<Boolean>() {
- @Override
- public Boolean capture() {
- return mWebView.canZoomIn();
- }
- });
- }
-
- public boolean zoomIn() {
- return getValue(new ValueGetter<Boolean>() {
- @Override
- public Boolean capture() {
- return mWebView.zoomIn();
- }
- });
- }
-
- public boolean zoomOut() {
- return getValue(new ValueGetter<Boolean>() {
- @Override
- public Boolean capture() {
- return mWebView.zoomOut();
- }
- });
- }
-
- public void setFindListener(final WebView.FindListener listener) {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.setFindListener(listener);
- }
- });
- }
-
- public void removeJavascriptInterface(final String interfaceName) {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.removeJavascriptInterface(interfaceName);
- }
- });
- }
-
- public void addJavascriptInterface(final Object object, final String name) {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.addJavascriptInterface(object, name);
- }
- });
- }
-
- public void flingScroll(final int vx, final int vy) {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.flingScroll(vx, vy);
- }
- });
- }
-
- public void requestFocusNodeHref(final Message hrefMsg) {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.requestFocusNodeHref(hrefMsg);
- }
- });
- }
-
- public void requestImageRef(final Message msg) {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.requestImageRef(msg);
- }
- });
- }
-
- public void setInitialScale(final int scaleInPercent) {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.setInitialScale(scaleInPercent);
- }
- });
- }
-
- public void clearSslPreferences() {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.clearSslPreferences();
- }
- });
- }
-
- public void clearClientCertPreferences(final Runnable onCleared) {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- WebView.clearClientCertPreferences(onCleared);
- }
- });
- }
-
- public void resumeTimers() {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.resumeTimers();
- }
- });
- }
-
- public void findNext(final boolean forward) {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.findNext(forward);
- }
- });
- }
-
- public void clearMatches() {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.clearMatches();
- }
- });
- }
-
- /**
- * Calls loadUrl on the WebView and then waits onPageFinished,
- * onNewPicture and onProgressChange to reach 100.
- * Test fails if the load timeout elapses.
- * @param url The URL to load.
- */
- public void loadUrlAndWaitForCompletion(final String url) {
- callAndWait(new Runnable() {
- @Override
- public void run() {
- mWebView.loadUrl(url);
- }
- });
- }
-
- /**
- * Calls loadUrl on the WebView and then waits onPageFinished,
- * onNewPicture and onProgressChange to reach 100.
- * Test fails if the load timeout elapses.
- * @param url The URL to load.
- * @param extraHeaders The additional headers to be used in the HTTP request.
- */
- public void loadUrlAndWaitForCompletion(final String url,
- final Map<String, String> extraHeaders) {
- callAndWait(new Runnable() {
- @Override
- public void run() {
- mWebView.loadUrl(url, extraHeaders);
- }
- });
- }
-
- public void loadUrl(final String url) {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.loadUrl(url);
- }
- });
- }
-
- public void stopLoading() {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.stopLoading();
- }
- });
- }
-
- public void postUrlAndWaitForCompletion(final String url, final byte[] postData) {
- callAndWait(new Runnable() {
- @Override
- public void run() {
- mWebView.postUrl(url, postData);
- }
- });
- }
-
- public void loadDataAndWaitForCompletion(final String data,
- final String mimeType, final String encoding) {
- callAndWait(new Runnable() {
- @Override
- public void run() {
- mWebView.loadData(data, mimeType, encoding);
- }
- });
- }
-
- public void loadDataWithBaseURLAndWaitForCompletion(final String baseUrl,
- final String data, final String mimeType, final String encoding,
- final String historyUrl) {
- callAndWait(new Runnable() {
- @Override
- public void run() {
- mWebView.loadDataWithBaseURL(baseUrl, data, mimeType, encoding,
- historyUrl);
- }
- });
- }
-
- /**
- * Reloads a page and waits for it to complete reloading. Use reload
- * if it is a form resubmission and the onFormResubmission responds
- * by telling WebView not to resubmit it.
- */
- public void reloadAndWaitForCompletion() {
- callAndWait(new Runnable() {
- @Override
- public void run() {
- mWebView.reload();
- }
- });
- }
-
- /**
- * Reload the previous URL. Use reloadAndWaitForCompletion unless
- * it is a form resubmission and the onFormResubmission responds
- * by telling WebView not to resubmit it.
- */
- public void reload() {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.reload();
- }
- });
- }
-
- /**
- * Use this only when JavaScript causes a page load to wait for the
- * page load to complete. Otherwise use loadUrlAndWaitForCompletion or
- * similar functions.
- */
- public void waitForLoadCompletion() {
- waitForCriteria(LOAD_TIMEOUT,
- new Callable<Boolean>() {
- @Override
- public Boolean call() {
- return isLoaded();
- }
- });
- clearLoad();
- }
-
- private void waitForCriteria(long timeout, Callable<Boolean> doneCriteria) {
- if (isUiThread()) {
- waitOnUiThread(timeout, doneCriteria);
- } else {
- waitOnTestThread(timeout, doneCriteria);
- }
- }
-
- public String getTitle() {
- return getValue(new ValueGetter<String>() {
- @Override
- public String capture() {
- return mWebView.getTitle();
- }
- });
- }
-
- public WebSettings getSettings() {
- return getValue(new ValueGetter<WebSettings>() {
- @Override
- public WebSettings capture() {
- return mWebView.getSettings();
- }
- });
- }
-
- public WebBackForwardList copyBackForwardList() {
- return getValue(new ValueGetter<WebBackForwardList>() {
- @Override
- public WebBackForwardList capture() {
- return mWebView.copyBackForwardList();
- }
- });
- }
-
- public Bitmap getFavicon() {
- return getValue(new ValueGetter<Bitmap>() {
- @Override
- public Bitmap capture() {
- return mWebView.getFavicon();
- }
- });
- }
-
- public String getUrl() {
- return getValue(new ValueGetter<String>() {
- @Override
- public String capture() {
- return mWebView.getUrl();
- }
- });
- }
-
- public int getProgress() {
- return getValue(new ValueGetter<Integer>() {
- @Override
- public Integer capture() {
- return mWebView.getProgress();
- }
- });
- }
-
- public int getHeight() {
- return getValue(new ValueGetter<Integer>() {
- @Override
- public Integer capture() {
- return mWebView.getHeight();
- }
- });
- }
-
- public int getContentHeight() {
- return getValue(new ValueGetter<Integer>() {
- @Override
- public Integer capture() {
- return mWebView.getContentHeight();
- }
- });
- }
-
- public boolean savePicture(final Bundle b, final File dest) {
- return getValue(new ValueGetter<Boolean>() {
- @Override
- public Boolean capture() {
- return mWebView.savePicture(b, dest);
- }
- });
- }
-
- public boolean pageUp(final boolean top) {
- return getValue(new ValueGetter<Boolean>() {
- @Override
- public Boolean capture() {
- return mWebView.pageUp(top);
- }
- });
- }
-
- public boolean pageDown(final boolean bottom) {
- return getValue(new ValueGetter<Boolean>() {
- @Override
- public Boolean capture() {
- return mWebView.pageDown(bottom);
- }
- });
- }
-
- public int[] getLocationOnScreen() {
- final int[] location = new int[2];
- return getValue(new ValueGetter<int[]>() {
- @Override
- public int[] capture() {
- mWebView.getLocationOnScreen(location);
- return location;
- }
- });
- }
-
- public float getScale() {
- return getValue(new ValueGetter<Float>() {
- @Override
- public Float capture() {
- return mWebView.getScale();
- }
- });
- }
-
- public boolean requestFocus(final int direction,
- final Rect previouslyFocusedRect) {
- return getValue(new ValueGetter<Boolean>() {
- @Override
- public Boolean capture() {
- return mWebView.requestFocus(direction, previouslyFocusedRect);
- }
- });
- }
-
- public HitTestResult getHitTestResult() {
- return getValue(new ValueGetter<HitTestResult>() {
- @Override
- public HitTestResult capture() {
- return mWebView.getHitTestResult();
- }
- });
- }
-
- public int getScrollX() {
- return getValue(new ValueGetter<Integer>() {
- @Override
- public Integer capture() {
- return mWebView.getScrollX();
- }
- });
- }
-
- public int getScrollY() {
- return getValue(new ValueGetter<Integer>() {
- @Override
- public Integer capture() {
- return mWebView.getScrollY();
- }
- });
- }
-
- public final DisplayMetrics getDisplayMetrics() {
- return getValue(new ValueGetter<DisplayMetrics>() {
- @Override
- public DisplayMetrics capture() {
- return mWebView.getContext().getResources().getDisplayMetrics();
- }
- });
- }
-
- public boolean requestChildRectangleOnScreen(final View child,
- final Rect rect,
- final boolean immediate) {
- return getValue(new ValueGetter<Boolean>() {
- @Override
- public Boolean capture() {
- return mWebView.requestChildRectangleOnScreen(child, rect,
- immediate);
- }
- });
- }
-
- public int findAll(final String find) {
- return getValue(new ValueGetter<Integer>() {
- @Override
- public Integer capture() {
- return mWebView.findAll(find);
- }
- });
- }
-
- public Picture capturePicture() {
- return getValue(new ValueGetter<Picture>() {
- @Override
- public Picture capture() {
- return mWebView.capturePicture();
- }
- });
- }
-
- public void evaluateJavascript(final String script, final ValueCallback<String> result) {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.evaluateJavascript(script, result);
- }
- });
- }
-
- public WebView createWebView() {
- return getValue(new ValueGetter<WebView>() {
- @Override
- public WebView capture() {
- return new WebView(mWebView.getContext());
- }
- });
- }
-
- public PrintDocumentAdapter createPrintDocumentAdapter() {
- return getValue(new ValueGetter<PrintDocumentAdapter>() {
- @Override
- public PrintDocumentAdapter capture() {
- return mWebView.createPrintDocumentAdapter();
- }
- });
- }
-
- public void setLayoutHeightToMatchParent() {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- ViewParent parent = mWebView.getParent();
- if (parent instanceof ViewGroup) {
- ((ViewGroup) parent).getLayoutParams().height =
- ViewGroup.LayoutParams.MATCH_PARENT;
- }
- mWebView.getLayoutParams().height = ViewGroup.LayoutParams.MATCH_PARENT;
- mWebView.requestLayout();
- }
- });
- }
-
- public void setAcceptThirdPartyCookies(final boolean accept) {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- CookieManager.getInstance().setAcceptThirdPartyCookies(mWebView, accept);
- }
- });
- }
-
- public boolean acceptThirdPartyCookies() {
- return getValue(new ValueGetter<Boolean>() {
- @Override
- public Boolean capture() {
- return CookieManager.getInstance().acceptThirdPartyCookies(mWebView);
- }
- });
- }
-
- /**
- * Helper for running code on the UI thread where an exception is
- * a test failure. If this is already the UI thread then it runs
- * the code immediately.
- *
- * @see runTestOnUiThread
- * @param r The code to run in the UI thread
- */
- public void runOnUiThread(Runnable r) {
- try {
- if (isUiThread()) {
- r.run();
- } else {
- mTest.runTestOnUiThread(r);
- }
- } catch (Throwable t) {
- Assert.fail("Unexpected error while running on UI thread: "
- + t.getMessage());
- }
- }
-
- /**
- * Accessor for underlying WebView.
- * @return The WebView being wrapped by this class.
- */
- public WebView getWebView() {
- return mWebView;
- }
-
- private<T> T getValue(ValueGetter<T> getter) {
- runOnUiThread(getter);
- return getter.getValue();
- }
-
- private abstract class ValueGetter<T> implements Runnable {
- private T mValue;
-
- @Override
- public void run() {
- mValue = capture();
- }
-
- protected abstract T capture();
-
- public T getValue() {
- return mValue;
- }
- }
-
- /**
- * Returns true if the current thread is the UI thread based on the
- * Looper.
- */
- private static boolean isUiThread() {
- return (Looper.myLooper() == Looper.getMainLooper());
- }
-
- /**
- * @return Whether or not the load has finished.
- */
- private synchronized boolean isLoaded() {
- return mLoaded && mNewPicture && mProgress == 100;
- }
-
- /**
- * Makes a WebView call, waits for completion and then resets the
- * load state in preparation for the next load call.
- * @param call The call to make on the UI thread prior to waiting.
- */
- private void callAndWait(Runnable call) {
- Assert.assertTrue("WebViewOnUiThread.load*AndWaitForCompletion calls "
- + "may not be mixed with load* calls directly on WebView "
- + "without calling waitForLoadCompletion after the load",
- !isLoaded());
- clearLoad(); // clear any extraneous signals from a previous load.
- runOnUiThread(call);
- waitForLoadCompletion();
- }
-
- /**
- * Called whenever a load has been completed so that a subsequent call to
- * waitForLoadCompletion doesn't return immediately.
- */
- synchronized private void clearLoad() {
- mLoaded = false;
- mNewPicture = false;
- mProgress = 0;
- }
-
- /**
- * Uses a polling mechanism, while pumping messages to check when the
- * criteria is met.
- */
- private void waitOnUiThread(long timeout, final Callable<Boolean> doneCriteria) {
- new PollingCheck(timeout) {
- @Override
- protected boolean check() {
- pumpMessages();
- try {
- return doneCriteria.call();
- } catch (Exception e) {
- Assert.fail("Unexpected error while checking the criteria: "
- + e.getMessage());
- return true;
- }
- }
- }.run();
- }
-
- /**
- * Uses a wait/notify to check when the criteria is met.
- */
- private synchronized void waitOnTestThread(long timeout, Callable<Boolean> doneCriteria) {
- try {
- long waitEnd = SystemClock.uptimeMillis() + timeout;
- long timeRemaining = timeout;
- while (!doneCriteria.call() && timeRemaining > 0) {
- this.wait(timeRemaining);
- timeRemaining = waitEnd - SystemClock.uptimeMillis();
- }
- Assert.assertTrue("Action failed to complete before timeout", doneCriteria.call());
- } catch (InterruptedException e) {
- // We'll just drop out of the loop and fail
- } catch (Exception e) {
- Assert.fail("Unexpected error while checking the criteria: "
- + e.getMessage());
- }
- }
-
- /**
- * Pumps all currently-queued messages in the UI thread and then exits.
- * This is useful to force processing while running tests in the UI thread.
- */
- private void pumpMessages() {
- class ExitLoopException extends RuntimeException {
- }
-
- // Force loop to exit when processing this. Loop.quit() doesn't
- // work because this is the main Loop.
- mWebView.getHandler().post(new Runnable() {
- @Override
- public void run() {
- throw new ExitLoopException(); // exit loop!
- }
- });
- try {
- // Pump messages until our message gets through.
- Looper.loop();
- } catch (ExitLoopException e) {
- }
- }
-
- /**
- * A WebChromeClient used to capture the onProgressChanged for use
- * in waitFor functions. If a test must override the WebChromeClient,
- * it can derive from this class or call onProgressChanged
- * directly.
- */
- public static class WaitForProgressClient extends WebChromeClient {
- private WebViewOnUiThread mOnUiThread;
-
- public WaitForProgressClient(WebViewOnUiThread onUiThread) {
- mOnUiThread = onUiThread;
- }
-
- @Override
- public void onProgressChanged(WebView view, int newProgress) {
- super.onProgressChanged(view, newProgress);
- mOnUiThread.onProgressChanged(newProgress);
- }
- }
-
- /**
- * A WebViewClient that captures the onPageFinished for use in
- * waitFor functions. Using initializeWebView sets the WaitForLoadedClient
- * into the WebView. If a test needs to set a specific WebViewClient and
- * needs the waitForCompletion capability then it should derive from
- * WaitForLoadedClient or call WebViewOnUiThread.onPageFinished.
- */
- public static class WaitForLoadedClient extends WebViewClient {
- private WebViewOnUiThread mOnUiThread;
-
- public WaitForLoadedClient(WebViewOnUiThread onUiThread) {
- mOnUiThread = onUiThread;
- }
-
- @Override
- public void onPageFinished(WebView view, String url) {
- super.onPageFinished(view, url);
- mOnUiThread.onPageFinished();
- }
-
- @Override
- public void onPageStarted(WebView view, String url, Bitmap favicon) {
- super.onPageStarted(view, url, favicon);
- mOnUiThread.onPageStarted();
- }
- }
-
- /**
- * A PictureListener that captures the onNewPicture for use in
- * waitForLoadCompletion. Using initializeWebView sets the PictureListener
- * into the WebView. If a test needs to set a specific PictureListener and
- * needs the waitForCompletion capability then it should call
- * WebViewOnUiThread.onNewPicture.
- */
- private class WaitForNewPicture implements PictureListener {
- @Override
- public void onNewPicture(WebView view, Picture picture) {
- WebViewOnUiThread.this.onNewPicture();
- }
- }
-}
diff --git a/tests/tests/text/src/android/text/cts/WidgetTestUtils.java b/tests/tests/text/src/android/text/cts/WidgetTestUtils.java
deleted file mode 100644
index d41b242..0000000
--- a/tests/tests/text/src/android/text/cts/WidgetTestUtils.java
+++ /dev/null
@@ -1,138 +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.text.cts;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-
-import java.io.IOException;
-
-import junit.framework.Assert;
-
-/**
- * The useful methods for widget test.
- */
-public class WidgetTestUtils {
- /**
- * Assert that two bitmaps are equal.
- *
- * @param Bitmap b1 the first bitmap which needs to compare.
- * @param Bitmap b2 the second bitmap which needs to compare.
- */
- public static void assertEquals(Bitmap b1, Bitmap b2) {
- if (b1 == b2) {
- return;
- }
-
- if (b1 == null || b2 == null) {
- Assert.fail("the bitmaps are not equal");
- }
-
- // b1 and b2 are all not null.
- if (b1.getWidth() != b2.getWidth() || b1.getHeight() != b2.getHeight()
- || b1.getConfig() != b2.getConfig()) {
- Assert.fail("the bitmaps are not equal");
- }
-
- int w = b1.getWidth();
- int h = b1.getHeight();
- int s = w * h;
- int[] pixels1 = new int[s];
- int[] pixels2 = new int[s];
-
- b1.getPixels(pixels1, 0, w, 0, 0, w, h);
- b2.getPixels(pixels2, 0, w, 0, 0, w, h);
-
- for (int i = 0; i < s; i++) {
- if (pixels1[i] != pixels2[i]) {
- Assert.fail("the bitmaps are not equal");
- }
- }
- }
-
- /**
- * Find beginning of the special element.
- * @param parser XmlPullParser will be parsed.
- * @param firstElementName the target element name.
- *
- * @throws XmlPullParserException if XML Pull Parser related faults occur.
- * @throws IOException if I/O-related error occur when parsing.
- */
- public static final void beginDocument(XmlPullParser parser, String firstElementName)
- throws XmlPullParserException, IOException {
- Assert.assertNotNull(parser);
- Assert.assertNotNull(firstElementName);
-
- int type;
- while ((type = parser.next()) != XmlPullParser.START_TAG
- && type != XmlPullParser.END_DOCUMENT) {
- ;
- }
-
- if (!parser.getName().equals(firstElementName)) {
- throw new XmlPullParserException("Unexpected start tag: found " + parser.getName()
- + ", expected " + firstElementName);
- }
- }
-
- /**
- * Compare the expected pixels with actual, scaling for the target context density
- *
- * @throws AssertionFailedError
- */
- public static void assertScaledPixels(int expected, int actual, Context context) {
- Assert.assertEquals(expected * context.getResources().getDisplayMetrics().density,
- actual, 3);
- }
-
- /** Converts dips into pixels using the {@link Context}'s density. */
- public static int convertDipToPixels(Context context, int dip) {
- float density = context.getResources().getDisplayMetrics().density;
- return Math.round(density * dip);
- }
-
- /**
- * Retrieve a bitmap that can be used for comparison on any density
- * @param resources
- * @return the {@link Bitmap} or <code>null</code>
- */
- public static Bitmap getUnscaledBitmap(Resources resources, int resId) {
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inScaled = false;
- return BitmapFactory.decodeResource(resources, resId, options);
- }
-
- /**
- * Retrieve a dithered bitmap that can be used for comparison on any density
- * @param resources
- * @param config the preferred config for the returning bitmap
- * @return the {@link Bitmap} or <code>null</code>
- */
- public static Bitmap getUnscaledAndDitheredBitmap(Resources resources,
- int resId, Bitmap.Config config) {
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inDither = true;
- options.inScaled = false;
- options.inPreferredConfig = config;
- return BitmapFactory.decodeResource(resources, resId, options);
- }
-}
diff --git a/tests/tests/text/src/android/text/method/cts/ScrollingMovementMethodTest.java b/tests/tests/text/src/android/text/method/cts/ScrollingMovementMethodTest.java
index c186cde..73fd763 100644
--- a/tests/tests/text/src/android/text/method/cts/ScrollingMovementMethodTest.java
+++ b/tests/tests/text/src/android/text/method/cts/ScrollingMovementMethodTest.java
@@ -18,6 +18,7 @@
import dalvik.annotation.KnownFailure;
+import android.cts.util.WidgetTestUtils;
import android.os.SystemClock;
import android.test.ActivityInstrumentationTestCase2;
import android.text.Layout;
@@ -33,7 +34,6 @@
import android.view.ViewGroup.LayoutParams;
import android.widget.TextView;
import android.widget.TextView.BufferType;
-import android.text.cts.WidgetTestUtils;
/**
* Test {@link ScrollingMovementMethod}. The class is an implementation of interface
diff --git a/tests/tests/text/src/android/text/style/cts/ImageSpanTest.java b/tests/tests/text/src/android/text/style/cts/ImageSpanTest.java
index a98c748..6f056d0 100644
--- a/tests/tests/text/src/android/text/style/cts/ImageSpanTest.java
+++ b/tests/tests/text/src/android/text/style/cts/ImageSpanTest.java
@@ -20,6 +20,7 @@
import android.content.Context;
+import android.cts.util.WidgetTestUtils;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
@@ -27,7 +28,6 @@
import android.test.AndroidTestCase;
import android.text.style.DynamicDrawableSpan;
import android.text.style.ImageSpan;
-import android.text.cts.WidgetTestUtils;
public class ImageSpanTest extends AndroidTestCase {
public void testConstructor() {
diff --git a/tests/tests/usage/Android.mk b/tests/tests/usage/Android.mk
new file mode 100644
index 0000000..f245e5f
--- /dev/null
+++ b/tests/tests/usage/Android.mk
@@ -0,0 +1,33 @@
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsUsageStatsTestCases
+
+# don't include this package in any target
+LOCAL_MODULE_TAGS := optional
+
+# and when built explicitly put it in the data partition
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/usage/AndroidManifest.xml b/tests/tests/usage/AndroidManifest.xml
new file mode 100644
index 0000000..11065d4
--- /dev/null
+++ b/tests/tests/usage/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.app.usage.cts">
+
+ <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+ <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
+ <uses-permission android:name="android.permission.SET_TIME" />
+
+ <application>
+ <uses-library android:name="android.test.runner" />
+
+ <activity android:name=".Activities$ActivityOne" />
+ <activity android:name=".Activities$ActivityTwo" />
+ <activity android:name=".Activities$ActivityThree" />
+ <activity android:name=".Activities$ActivityFour" />
+ </application>
+
+ <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.app.usage.cts"
+ android:label="CTS tests of android.app.usage">
+ <meta-data android:name="listener"
+ android:value="com.android.cts.runner.CtsTestRunListener" />
+ </instrumentation>
+
+</manifest>
+
diff --git a/tests/tests/usage/src/android/app/usage/cts/Activities.java b/tests/tests/usage/src/android/app/usage/cts/Activities.java
new file mode 100644
index 0000000..35c7904
--- /dev/null
+++ b/tests/tests/usage/src/android/app/usage/cts/Activities.java
@@ -0,0 +1,38 @@
+/**
+ * Copyright (C) 2014 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.app.usage.cts;
+
+import android.annotation.Nullable;
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.WindowManager;
+
+public final class Activities {
+ private static class KeepScreenOnActivity extends Activity {
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+ }
+ }
+
+ public static class ActivityOne extends KeepScreenOnActivity {}
+ public static class ActivityTwo extends KeepScreenOnActivity {}
+ public static class ActivityThree extends KeepScreenOnActivity {}
+ public static class ActivityFour extends KeepScreenOnActivity {}
+
+ private Activities() {}
+}
diff --git a/tests/tests/usage/src/android/app/usage/cts/UsageStatsTest.java b/tests/tests/usage/src/android/app/usage/cts/UsageStatsTest.java
new file mode 100644
index 0000000..5b1909a
--- /dev/null
+++ b/tests/tests/usage/src/android/app/usage/cts/UsageStatsTest.java
@@ -0,0 +1,304 @@
+/**
+ * Copyright (C) 2014 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.app.usage.cts;
+
+import android.app.Activity;
+import android.app.AppOpsManager;
+import android.app.Instrumentation;
+import android.app.usage.UsageEvents;
+import android.app.usage.UsageStats;
+import android.app.usage.UsageStatsManager;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Parcel;
+import android.os.ParcelFileDescriptor;
+import android.os.SystemClock;
+import android.test.InstrumentationTestCase;
+
+import java.io.FileInputStream;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import android.util.SparseLongArray;
+import junit.framework.AssertionFailedError;
+import libcore.io.IoUtils;
+import libcore.io.Streams;
+import org.junit.Ignore;
+
+/**
+ * Test the UsageStats API. It is difficult to test the entire surface area
+ * of the API, as a lot of the testing depends on what data is already present
+ * on the device and for how long that data has been aggregating.
+ *
+ * These tests perform simple checks that each interval is of the correct duration,
+ * and that events do appear in the event log.
+ *
+ * Tests to add that are difficult to add now:
+ * - Invoking a device configuration change and then watching for it in the event log.
+ * - Changing the system time and verifying that all data has been correctly shifted
+ * along with the new time.
+ * - Proper eviction of old data.
+ */
+public class UsageStatsTest extends InstrumentationTestCase {
+ private static final String APPOPS_SET_SHELL_COMMAND = "appops set {0} " +
+ AppOpsManager.OPSTR_GET_USAGE_STATS + " {1}";
+
+ private static final long MINUTE = 1000 * 60;
+ private static final long DAY = MINUTE * 60 * 24;
+ private static final long WEEK = 7 * DAY;
+ private static final long MONTH = 30 * DAY;
+ private static final long YEAR = 365 * DAY;
+ private static final long TIME_DIFF_THRESHOLD = 200;
+
+ private UsageStatsManager mUsageStatsManager;
+ private String mTargetPackage;
+ private ArrayList<Activity> mStartedActivities = new ArrayList<>();
+
+ @Override
+ protected void setUp() throws Exception {
+ mUsageStatsManager = (UsageStatsManager) getInstrumentation().getContext()
+ .getSystemService(Context.USAGE_STATS_SERVICE);
+ mTargetPackage = getInstrumentation().getContext().getPackageName();
+
+ setAppOpsMode("allow");
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ for (Activity activity : mStartedActivities) {
+ activity.finish();
+ }
+ }
+
+ private static void assertLessThan(long left, long right) {
+ if (left >= right) {
+ throw new AssertionFailedError("Expected " + left + " to be less than " + right);
+ }
+ }
+
+ private static void assertLessThanOrEqual(long left, long right) {
+ if (left > right) {
+ throw new AssertionFailedError("Expected " + left + " to be less than or equal to " + right);
+ }
+ }
+
+ private void setAppOpsMode(String mode) throws Exception {
+ final String command = MessageFormat.format(APPOPS_SET_SHELL_COMMAND,
+ getInstrumentation().getContext().getPackageName(), mode);
+ ParcelFileDescriptor pfd = getInstrumentation().getUiAutomation()
+ .executeShellCommand(command);
+ try {
+ Streams.readFully(new FileInputStream(pfd.getFileDescriptor()));
+ } finally {
+ IoUtils.closeQuietly(pfd.getFileDescriptor());
+ }
+ }
+
+ private void launchSubActivity(Class<? extends Activity> clazz) {
+ final Instrumentation.ActivityResult result = new Instrumentation.ActivityResult(0, new Intent());
+ final Instrumentation.ActivityMonitor monitor = new Instrumentation.ActivityMonitor(clazz.getName(), result, false);
+ getInstrumentation().addMonitor(monitor);
+ launchActivity(mTargetPackage, clazz, null);
+ mStartedActivities.add(monitor.waitForActivity());
+ }
+
+ private void launchSubActivities(Class<? extends Activity>[] activityClasses) {
+ for (Class<? extends Activity> clazz : activityClasses) {
+ launchSubActivity(clazz);
+ }
+ }
+
+ public void testOrderedActivityLaunchSequenceInEventLog() throws Exception {
+ @SuppressWarnings("unchecked")
+ Class<? extends Activity>[] activitySequence = new Class[] {
+ Activities.ActivityOne.class,
+ Activities.ActivityTwo.class,
+ Activities.ActivityThree.class,
+ };
+
+ // Launch the series of Activities.
+ launchSubActivities(activitySequence);
+
+ final long endTime = System.currentTimeMillis();
+ final long startTime = endTime - DAY;
+ UsageEvents events = mUsageStatsManager.queryEvents(startTime, endTime);
+
+ // Consume all the events.
+ ArrayList<UsageEvents.Event> eventList = new ArrayList<>();
+ while (events.hasNextEvent()) {
+ UsageEvents.Event event = new UsageEvents.Event();
+ assertTrue(events.getNextEvent(event));
+ eventList.add(event);
+ }
+
+ // We expect 2 events per Activity launched (foreground + background)
+ // except for the last Activity, which was in the foreground when
+ // we queried the event log.
+ assertTrue(eventList.size() >= (activitySequence.length * 2) - 1);
+ final int offset = eventList.size() - ((activitySequence.length * 2) - 1);
+
+ final int activityCount = activitySequence.length;
+ for (int i = 0; i < activityCount; i++) {
+ int index = offset + (i * 2);
+
+ // Check for foreground event.
+ UsageEvents.Event event = eventList.get(index);
+ assertEquals(mTargetPackage, event.getPackageName());
+ assertEquals(activitySequence[i].getName(), event.getClassName());
+ assertEquals(UsageEvents.Event.MOVE_TO_FOREGROUND, event.getEventType());
+
+ index += 1;
+ if (i < activityCount - 1) {
+ // Check for background event.
+ event = eventList.get(index);
+ assertEquals(mTargetPackage, event.getPackageName());
+ assertEquals(activitySequence[i].getName(), event.getClassName());
+ assertEquals(UsageEvents.Event.MOVE_TO_BACKGROUND, event.getEventType());
+ }
+ }
+ }
+
+ /**
+ * We can't run this test because we are unable to change the system time.
+ * It would be nice to add a shell command or other to allow the shell user
+ * to set the time, thereby allowing this test to set the time using the UIAutomator.
+ */
+ @Ignore
+ public void ignore_testStatsAreShiftedInTimeWhenSystemTimeChanges() throws Exception {
+ launchSubActivity(Activities.ActivityOne.class);
+
+ long endTime = System.currentTimeMillis();
+ long startTime = endTime - MINUTE;
+ Map<String, UsageStats> statsMap = mUsageStatsManager.queryAndAggregateUsageStats(startTime, endTime);
+ assertFalse(statsMap.isEmpty());
+ assertTrue(statsMap.containsKey(mTargetPackage));
+ final UsageStats before = statsMap.get(mTargetPackage);
+
+ SystemClock.setCurrentTimeMillis(System.currentTimeMillis() - (DAY / 2));
+ try {
+ endTime = System.currentTimeMillis();
+ startTime = endTime - MINUTE;
+ statsMap = mUsageStatsManager.queryAndAggregateUsageStats(startTime, endTime);
+ assertFalse(statsMap.isEmpty());
+ assertTrue(statsMap.containsKey(mTargetPackage));
+ final UsageStats after = statsMap.get(mTargetPackage);
+ assertEquals(before.getPackageName(), after.getPackageName());
+
+ long diff = before.getFirstTimeStamp() - after.getFirstTimeStamp();
+ assertLessThan(Math.abs(diff - (DAY / 2)), TIME_DIFF_THRESHOLD);
+
+ assertEquals(before.getLastTimeStamp() - before.getFirstTimeStamp(),
+ after.getLastTimeStamp() - after.getFirstTimeStamp());
+ assertEquals(before.getLastTimeUsed() - before.getFirstTimeStamp(),
+ after.getLastTimeUsed() - after.getFirstTimeStamp());
+ assertEquals(before.getTotalTimeInForeground(), after.getTotalTimeInForeground());
+ } finally {
+ SystemClock.setCurrentTimeMillis(System.currentTimeMillis() + (DAY / 2));
+ }
+ }
+
+ public void testUsageEventsParceling() throws Exception {
+ final long startTime = System.currentTimeMillis();
+
+ @SuppressWarnings("unchecked")
+ Class<? extends Activity>[] activityClasses = new Class[] {
+ Activities.ActivityOne.class,
+ Activities.ActivityThree.class,
+ Activities.ActivityTwo.class,
+ };
+ launchSubActivities(activityClasses);
+
+ final long endTime = System.currentTimeMillis();
+ UsageEvents events = mUsageStatsManager.queryEvents(startTime - TIME_DIFF_THRESHOLD, endTime);
+ assertTrue(events.getNextEvent(new UsageEvents.Event()));
+
+ Parcel p = Parcel.obtain();
+ p.setDataPosition(0);
+ events.writeToParcel(p, 0);
+ p.setDataPosition(0);
+
+ UsageEvents reparceledEvents = UsageEvents.CREATOR.createFromParcel(p);
+
+ UsageEvents.Event e1 = new UsageEvents.Event();
+ UsageEvents.Event e2 = new UsageEvents.Event();
+ while (events.hasNextEvent() && reparceledEvents.hasNextEvent()) {
+ events.getNextEvent(e1);
+ reparceledEvents.getNextEvent(e2);
+ assertEquals(e1.getPackageName(), e2.getPackageName());
+ assertEquals(e1.getClassName(), e2.getClassName());
+ assertEquals(e1.getConfiguration(), e2.getConfiguration());
+ assertEquals(e1.getEventType(), e2.getEventType());
+ assertEquals(e1.getTimeStamp(), e2.getTimeStamp());
+ }
+
+ assertEquals(events.hasNextEvent(), reparceledEvents.hasNextEvent());
+ }
+
+ public void testPackageUsageStatsIntervals() throws Exception {
+ final long beforeTime = System.currentTimeMillis();
+
+ // Launch an Activity.
+ launchSubActivity(Activities.ActivityFour.class);
+
+ final long endTime = System.currentTimeMillis();
+
+ final SparseLongArray intervalLengths = new SparseLongArray();
+ intervalLengths.put(UsageStatsManager.INTERVAL_DAILY, DAY);
+ intervalLengths.put(UsageStatsManager.INTERVAL_WEEKLY, WEEK);
+ intervalLengths.put(UsageStatsManager.INTERVAL_MONTHLY, MONTH);
+ intervalLengths.put(UsageStatsManager.INTERVAL_YEARLY, YEAR);
+
+ final int intervalCount = intervalLengths.size();
+ for (int i = 0; i < intervalCount; i++) {
+ final int intervalType = intervalLengths.keyAt(i);
+ final long intervalDuration = intervalLengths.valueAt(i);
+ final long startTime = endTime - (2 * intervalDuration);
+ final List<UsageStats> statsList = mUsageStatsManager.queryUsageStats(intervalType, startTime, endTime);
+ assertFalse(statsList.isEmpty());
+
+ boolean foundPackage = false;
+ for (UsageStats stats : statsList) {
+ // Verify that each period is a day long.
+ assertLessThanOrEqual(stats.getLastTimeStamp() - stats.getFirstTimeStamp(), intervalDuration);
+ if (stats.getPackageName().equals(mTargetPackage) &&
+ stats.getLastTimeUsed() >= beforeTime - TIME_DIFF_THRESHOLD) {
+ foundPackage = true;
+ }
+ }
+
+ assertTrue("Did not find package " + mTargetPackage + " in interval " + intervalType, foundPackage);
+ }
+ }
+
+ public void testNoAccessSilentlyFails() throws Exception {
+ launchSubActivity(Activities.ActivityOne.class);
+
+ final long endTime = System.currentTimeMillis();
+ final long startTime = endTime - MINUTE;
+ List<UsageStats> stats = mUsageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_BEST,
+ startTime, endTime);
+ assertFalse(stats.isEmpty());
+
+ setAppOpsMode("default");
+
+ stats = mUsageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_BEST,
+ startTime, endTime);
+ assertTrue(stats.isEmpty());
+ }
+}
diff --git a/tests/tests/view/src/android/view/cts/ChoreographerTest.java b/tests/tests/view/src/android/view/cts/ChoreographerTest.java
index 3a34b2c..6862fac 100644
--- a/tests/tests/view/src/android/view/cts/ChoreographerTest.java
+++ b/tests/tests/view/src/android/view/cts/ChoreographerTest.java
@@ -16,16 +16,27 @@
package android.view.cts;
-import android.test.AndroidTestCase;
+import android.test.InstrumentationTestCase;
import android.view.Choreographer;
-public class ChoreographerTest extends AndroidTestCase {
+public class ChoreographerTest extends InstrumentationTestCase {
private static final long NOMINAL_VSYNC_PERIOD = 16;
private static final long DELAY_PERIOD = NOMINAL_VSYNC_PERIOD * 5;
private static final long NANOS_PER_MS = 1000000;
private static final Object TOKEN = new Object();
- private Choreographer mChoreographer = Choreographer.getInstance();
+ private Choreographer mChoreographer;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ getInstrumentation().runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ mChoreographer = Choreographer.getInstance();
+ }
+ });
+ }
public void testFrameDelay() {
assertTrue(Choreographer.getFrameDelay() > 0);
diff --git a/tests/tests/view/src/android/view/cts/MenuInflaterTest.java b/tests/tests/view/src/android/view/cts/MenuInflaterTest.java
index bd483f9..40d1d3d 100644
--- a/tests/tests/view/src/android/view/cts/MenuInflaterTest.java
+++ b/tests/tests/view/src/android/view/cts/MenuInflaterTest.java
@@ -23,6 +23,7 @@
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
+import android.cts.util.WidgetTestUtils;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
diff --git a/tests/tests/view/src/android/view/cts/ViewGroupCtsActivity.java b/tests/tests/view/src/android/view/cts/ViewGroupCtsActivity.java
index 71bb28c..880a450 100644
--- a/tests/tests/view/src/android/view/cts/ViewGroupCtsActivity.java
+++ b/tests/tests/view/src/android/view/cts/ViewGroupCtsActivity.java
@@ -17,7 +17,7 @@
package android.view.cts;
import android.app.Activity;
-import android.app.cts.CTSResult;
+import android.cts.util.CTSResult;
import android.os.Bundle;
import android.os.Handler;
import android.widget.TextView;
diff --git a/tests/tests/view/src/android/view/cts/ViewGroupTest.java b/tests/tests/view/src/android/view/cts/ViewGroupTest.java
index 55428de..f1064a7 100644
--- a/tests/tests/view/src/android/view/cts/ViewGroupTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewGroupTest.java
@@ -19,9 +19,9 @@
import com.android.internal.util.XmlUtils;
-import android.app.cts.CTSResult;
import android.content.Context;
import android.content.Intent;
+import android.cts.util.CTSResult;
import android.content.res.XmlResourceParser;
import android.graphics.Bitmap;
import android.graphics.Canvas;
diff --git a/tests/tests/webkit/Android.mk b/tests/tests/webkit/Android.mk
index 1d593df..c2d8c3c 100644
--- a/tests/tests/webkit/Android.mk
+++ b/tests/tests/webkit/Android.mk
@@ -23,7 +23,7 @@
LOCAL_JAVA_LIBRARIES := android.test.runner
-LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestserver ctstestrunner
+LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctsdeviceutillegacy ctstestserver ctstestrunner
LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/tests/tests/webkit/src/android/webkit/cts/CookieManagerTest.java b/tests/tests/webkit/src/android/webkit/cts/CookieManagerTest.java
index 9db7c21..c612886 100644
--- a/tests/tests/webkit/src/android/webkit/cts/CookieManagerTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/CookieManagerTest.java
@@ -16,6 +16,7 @@
package android.webkit.cts;
+import android.cts.util.NullWebViewUtils;
import android.cts.util.PollingCheck;
import android.test.ActivityInstrumentationTestCase2;
import android.webkit.CookieManager;
diff --git a/tests/tests/webkit/src/android/webkit/cts/CookieSyncManagerCtsActivity.java b/tests/tests/webkit/src/android/webkit/cts/CookieSyncManagerCtsActivity.java
index 51eeed3..e623405 100644
--- a/tests/tests/webkit/src/android/webkit/cts/CookieSyncManagerCtsActivity.java
+++ b/tests/tests/webkit/src/android/webkit/cts/CookieSyncManagerCtsActivity.java
@@ -17,6 +17,7 @@
package android.webkit.cts;
import android.app.Activity;
+import android.cts.util.NullWebViewUtils;
import android.os.Bundle;
import android.webkit.CookieSyncManager;
import android.webkit.WebView;
diff --git a/tests/tests/webkit/src/android/webkit/cts/CookieTest.java b/tests/tests/webkit/src/android/webkit/cts/CookieTest.java
index bc5e3b0..555266b 100644
--- a/tests/tests/webkit/src/android/webkit/cts/CookieTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/CookieTest.java
@@ -16,6 +16,7 @@
package android.webkit.cts;
+import android.cts.util.NullWebViewUtils;
import android.test.ActivityInstrumentationTestCase2;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
diff --git a/tests/tests/webkit/src/android/webkit/cts/GeolocationTest.java b/tests/tests/webkit/src/android/webkit/cts/GeolocationTest.java
index 63990bf..ba0e0e9 100644
--- a/tests/tests/webkit/src/android/webkit/cts/GeolocationTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/GeolocationTest.java
@@ -17,6 +17,7 @@
package android.webkit.cts;
import android.content.Context;
+import android.cts.util.NullWebViewUtils;
import android.cts.util.PollingCheck;
import android.graphics.Bitmap;
import android.location.Criteria;
diff --git a/tests/tests/webkit/src/android/webkit/cts/HttpAuthHandlerTest.java b/tests/tests/webkit/src/android/webkit/cts/HttpAuthHandlerTest.java
index fbda04b..5c86987 100644
--- a/tests/tests/webkit/src/android/webkit/cts/HttpAuthHandlerTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/HttpAuthHandlerTest.java
@@ -16,6 +16,7 @@
package android.webkit.cts;
+import android.cts.util.NullWebViewUtils;
import android.test.ActivityInstrumentationTestCase2;
import android.webkit.HttpAuthHandler;
import android.webkit.WebView;
diff --git a/tests/tests/webkit/src/android/webkit/cts/NullWebViewUtils.java b/tests/tests/webkit/src/android/webkit/cts/NullWebViewUtils.java
deleted file mode 100644
index c52219f..0000000
--- a/tests/tests/webkit/src/android/webkit/cts/NullWebViewUtils.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2010 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.webkit.cts;
-
-import android.content.Context;
-import android.content.pm.PackageManager;
-
-/**
- * Utilities to enable the android.webkit.* CTS tests (and others that rely on a functioning
- * android.webkit.WebView implementation) to determine whether a functioning WebView is present
- * on the device or not.
- *
- * Test cases that require android.webkit.* classes should wrap their first usage of WebView in a
- * try catch block, and pass any exception that is thrown to
- * NullWebViewUtils.determineIfWebViewAvailable. The return value of
- * NullWebViewUtils.isWebViewAvailable will then determine if the test should expect to be able to
- * use a WebView.
- */
-public class NullWebViewUtils {
-
- private static boolean sWebViewUnavailable;
-
- /**
- * @param context Current Activity context, used to query the PackageManager.
- * @param t An exception thrown by trying to invoke android.webkit.* APIs.
- */
- public static void determineIfWebViewAvailable(Context context, Throwable t) {
- sWebViewUnavailable = !hasWebViewFeature(context) && checkCauseWasUnsupportedOperation(t);
- }
-
- /**
- * After calling determineIfWebViewAvailable, this returns whether a WebView is available on the
- * device and wheter the test can rely on it.
- * @return True iff. PackageManager determined that there is no WebView on the device and the
- * exception thrown from android.webkit.* was UnsupportedOperationException.
- */
- public static boolean isWebViewAvailable() {
- return !sWebViewUnavailable;
- }
-
- private static boolean hasWebViewFeature(Context context) {
- // Query the system property that determins if there is a functional WebView on the device.
- PackageManager pm = context.getPackageManager();
- return pm.hasSystemFeature(PackageManager.FEATURE_WEBVIEW);
- }
-
- private static boolean checkCauseWasUnsupportedOperation(Throwable t) {
- if (t == null) return false;
- while (t.getCause() != null) {
- t = t.getCause();
- }
- return t instanceof UnsupportedOperationException;
- }
-
- /**
- * Some CTS tests (by design) first use android.webkit.* from a background thread. This helper
- * allows the test to catch the UnsupportedOperationException from that background thread, and
- * then query the result from the test main thread.
- */
- public static class NullWebViewFromThreadExceptionHandler
- implements Thread.UncaughtExceptionHandler {
- private Throwable mPendingException;
-
- @Override
- public void uncaughtException(Thread t, Throwable e) {
- mPendingException = e;
- }
-
- public boolean isWebViewAvailable(Context context) {
- return hasWebViewFeature(context) ||
- !checkCauseWasUnsupportedOperation(mPendingException);
- }
- }
-}
\ No newline at end of file
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebBackForwardListTest.java b/tests/tests/webkit/src/android/webkit/cts/WebBackForwardListTest.java
index 21a5b98..7d25b84 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebBackForwardListTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebBackForwardListTest.java
@@ -16,6 +16,7 @@
package android.webkit.cts;
+import android.cts.util.NullWebViewUtils;
import android.cts.util.PollingCheck;
import android.test.ActivityInstrumentationTestCase2;
import android.webkit.WebBackForwardList;
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebChromeClientTest.java b/tests/tests/webkit/src/android/webkit/cts/WebChromeClientTest.java
index 6a94a99..150fd86 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebChromeClientTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebChromeClientTest.java
@@ -16,6 +16,7 @@
package android.webkit.cts;
+import android.cts.util.NullWebViewUtils;
import android.cts.util.PollingCheck;
import android.graphics.Bitmap;
import android.os.Message;
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebHistoryItemTest.java b/tests/tests/webkit/src/android/webkit/cts/WebHistoryItemTest.java
index d4f326b..a6b647d 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebHistoryItemTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebHistoryItemTest.java
@@ -16,6 +16,7 @@
package android.webkit.cts;
+import android.cts.util.NullWebViewUtils;
import android.cts.util.PollingCheck;
import android.graphics.Bitmap;
import android.test.ActivityInstrumentationTestCase2;
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java b/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
index 3e7a592..33a9cee 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
@@ -16,6 +16,7 @@
package android.webkit.cts;
import android.content.Context;
+import android.cts.util.NullWebViewUtils;
import android.cts.util.PollingCheck;
import android.graphics.Bitmap;
import android.net.http.SslError;
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java
index 2430c8c..5b906ba 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java
@@ -17,6 +17,7 @@
package android.webkit.cts;
import android.cts.util.EvaluateJsResultPollingCheck;
+import android.cts.util.NullWebViewUtils;
import android.cts.util.PollingCheck;
import android.graphics.Bitmap;
import android.os.Message;
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewCtsActivity.java b/tests/tests/webkit/src/android/webkit/cts/WebViewCtsActivity.java
index d809a42..9af7266 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewCtsActivity.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewCtsActivity.java
@@ -19,6 +19,7 @@
import com.android.cts.webkit.R;
import android.app.Activity;
+import android.cts.util.NullWebViewUtils;
import android.os.Bundle;
import android.view.ViewGroup;
import android.view.ViewParent;
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewSslTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewSslTest.java
index 8aa0145..378bf6e 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewSslTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewSslTest.java
@@ -16,6 +16,7 @@
package android.webkit.cts;
+import android.cts.util.NullWebViewUtils;
import android.cts.util.PollingCheck;
import android.net.Uri;
import android.net.http.SslCertificate;
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewStartupTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewStartupTest.java
index 8f4dcc2..776cfab 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewStartupTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewStartupTest.java
@@ -18,6 +18,7 @@
import android.content.Context;
+import android.cts.util.NullWebViewUtils;
import android.cts.util.PollingCheck;
import android.test.ActivityInstrumentationTestCase2;
import android.test.UiThreadTest;
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
index 1d8a02a..ef64f4d 100755
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
@@ -20,6 +20,7 @@
import android.content.Context;
import android.content.res.AssetManager;
import android.cts.util.EvaluateJsResultPollingCheck;
+import android.cts.util.NullWebViewUtils;
import android.cts.util.PollingCheck;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebView_WebViewTransportTest.java b/tests/tests/webkit/src/android/webkit/cts/WebView_WebViewTransportTest.java
index 0c04706..1db7fca 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebView_WebViewTransportTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebView_WebViewTransportTest.java
@@ -16,6 +16,7 @@
package android.webkit.cts;
+import android.cts.util.NullWebViewUtils;
import android.test.ActivityInstrumentationTestCase2;
import android.test.UiThreadTest;
import android.webkit.WebView;
diff --git a/tests/tests/widget/res/layout/autocompletetextview_layout.xml b/tests/tests/widget/res/layout/autocompletetextview_layout.xml
index 7fd183c..25a8541 100644
--- a/tests/tests/widget/res/layout/autocompletetextview_layout.xml
+++ b/tests/tests/widget/res/layout/autocompletetextview_layout.xml
@@ -28,5 +28,6 @@
android:completionThreshold="1"
android:completionHint="@string/tabs_1"
android:layout_width="match_parent"
- android:layout_height="wrap_content" />
+ android:layout_height="wrap_content"
+ android:inputType="none"/>
</LinearLayout>
diff --git a/tests/tests/widget/res/layout/popupwindow.xml b/tests/tests/widget/res/layout/popupwindow.xml
index e6b0aed..2508115 100644
--- a/tests/tests/widget/res/layout/popupwindow.xml
+++ b/tests/tests/widget/res/layout/popupwindow.xml
@@ -16,17 +16,16 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
+ android:layout_height="match_parent"
android:orientation="vertical">
<TextView android:id="@+id/anchor_upper"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="@string/text_view_hint"
- android:layout_weight="1"/>
+ android:text="@string/text_view_hint" />
<LinearLayout android:layout_width="match_parent"
- android:layout_height="wrap_content"
+ android:layout_height="0dp"
android:layout_weight="1">
<TextView android:id="@+id/anchor_middle_left"
@@ -46,7 +45,6 @@
<TextView android:id="@+id/anchor_lower"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="@string/text_view_hint"
- android:layout_weight="1"/>
+ android:text="@string/text_view_hint" />
</LinearLayout>
diff --git a/tests/tests/widget/src/android/widget/cts/AbsListViewTest.java b/tests/tests/widget/src/android/widget/cts/AbsListViewTest.java
index b6a96fb..9d8c7d2 100644
--- a/tests/tests/widget/src/android/widget/cts/AbsListViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/AbsListViewTest.java
@@ -25,6 +25,7 @@
import android.app.Instrumentation;
import android.content.Context;
import android.cts.util.PollingCheck;
+import android.cts.util.WidgetTestUtils;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Rect;
diff --git a/tests/tests/widget/src/android/widget/cts/AbsListView_LayoutParamsTest.java b/tests/tests/widget/src/android/widget/cts/AbsListView_LayoutParamsTest.java
index 413bc2a..305a9e2 100644
--- a/tests/tests/widget/src/android/widget/cts/AbsListView_LayoutParamsTest.java
+++ b/tests/tests/widget/src/android/widget/cts/AbsListView_LayoutParamsTest.java
@@ -21,6 +21,7 @@
import org.xmlpull.v1.XmlPullParser;
+import android.cts.util.WidgetTestUtils;
import android.test.AndroidTestCase;
import android.util.AttributeSet;
import android.util.Xml;
diff --git a/tests/tests/widget/src/android/widget/cts/AbsoluteLayoutTest.java b/tests/tests/widget/src/android/widget/cts/AbsoluteLayoutTest.java
index 053f42b..bac2479 100644
--- a/tests/tests/widget/src/android/widget/cts/AbsoluteLayoutTest.java
+++ b/tests/tests/widget/src/android/widget/cts/AbsoluteLayoutTest.java
@@ -24,6 +24,7 @@
import android.app.Activity;
import android.content.Context;
+import android.cts.util.WidgetTestUtils;
import android.test.ActivityInstrumentationTestCase2;
import android.util.AttributeSet;
import android.util.Xml;
diff --git a/tests/tests/widget/src/android/widget/cts/AbsoluteLayout_LayoutParamsTest.java b/tests/tests/widget/src/android/widget/cts/AbsoluteLayout_LayoutParamsTest.java
index 685f2d3..ebc4e74 100644
--- a/tests/tests/widget/src/android/widget/cts/AbsoluteLayout_LayoutParamsTest.java
+++ b/tests/tests/widget/src/android/widget/cts/AbsoluteLayout_LayoutParamsTest.java
@@ -22,6 +22,7 @@
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
+import android.cts.util.WidgetTestUtils;
import android.test.AndroidTestCase;
import android.util.AttributeSet;
import android.util.Xml;
diff --git a/tests/tests/widget/src/android/widget/cts/CursorAdapterTest.java b/tests/tests/widget/src/android/widget/cts/CursorAdapterTest.java
index 8cc0754..0916e59 100644
--- a/tests/tests/widget/src/android/widget/cts/CursorAdapterTest.java
+++ b/tests/tests/widget/src/android/widget/cts/CursorAdapterTest.java
@@ -20,6 +20,8 @@
import android.content.Context;
import android.cts.util.PollingCheck;
+import android.cts.util.ReadElf;
+import android.cts.util.TestThread;
import android.database.ContentObserver;
import android.database.Cursor;
import android.database.DataSetObserver;
diff --git a/tests/tests/widget/src/android/widget/cts/FilterTest.java b/tests/tests/widget/src/android/widget/cts/FilterTest.java
index 76de481..2c598dd 100644
--- a/tests/tests/widget/src/android/widget/cts/FilterTest.java
+++ b/tests/tests/widget/src/android/widget/cts/FilterTest.java
@@ -18,6 +18,8 @@
import android.cts.util.PollingCheck;
+import android.cts.util.ReadElf;
+import android.cts.util.TestThread;
import android.os.Looper;
import android.test.ActivityInstrumentationTestCase2;
import android.widget.Filter;
diff --git a/tests/tests/widget/src/android/widget/cts/FrameLayoutTest.java b/tests/tests/widget/src/android/widget/cts/FrameLayoutTest.java
index dcab088..31d9fff 100644
--- a/tests/tests/widget/src/android/widget/cts/FrameLayoutTest.java
+++ b/tests/tests/widget/src/android/widget/cts/FrameLayoutTest.java
@@ -17,6 +17,7 @@
package android.widget.cts;
import android.content.res.ColorStateList;
+import android.cts.util.WidgetTestUtils;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
diff --git a/tests/tests/widget/src/android/widget/cts/FrameLayout_LayoutParamsTest.java b/tests/tests/widget/src/android/widget/cts/FrameLayout_LayoutParamsTest.java
index d8f1296..1e7082f 100644
--- a/tests/tests/widget/src/android/widget/cts/FrameLayout_LayoutParamsTest.java
+++ b/tests/tests/widget/src/android/widget/cts/FrameLayout_LayoutParamsTest.java
@@ -22,6 +22,7 @@
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
+import android.cts.util.WidgetTestUtils;
import android.test.AndroidTestCase;
import android.util.AttributeSet;
import android.util.Xml;
diff --git a/tests/tests/widget/src/android/widget/cts/GalleryTest.java b/tests/tests/widget/src/android/widget/cts/GalleryTest.java
index a2deab9..2813965 100644
--- a/tests/tests/widget/src/android/widget/cts/GalleryTest.java
+++ b/tests/tests/widget/src/android/widget/cts/GalleryTest.java
@@ -26,6 +26,7 @@
import android.app.Activity;
import android.app.Instrumentation;
import android.content.Context;
+import android.cts.util.WidgetTestUtils;
import android.os.SystemClock;
import android.test.ActivityInstrumentationTestCase2;
import android.test.UiThreadTest;
diff --git a/tests/tests/widget/src/android/widget/cts/Gallery_LayoutParamsTest.java b/tests/tests/widget/src/android/widget/cts/Gallery_LayoutParamsTest.java
index de90ed3..0502e38 100644
--- a/tests/tests/widget/src/android/widget/cts/Gallery_LayoutParamsTest.java
+++ b/tests/tests/widget/src/android/widget/cts/Gallery_LayoutParamsTest.java
@@ -22,6 +22,7 @@
import org.xmlpull.v1.XmlPullParserException;
import android.content.res.XmlResourceParser;
+import android.cts.util.WidgetTestUtils;
import android.test.AndroidTestCase;
import android.widget.Gallery.LayoutParams;
diff --git a/tests/tests/widget/src/android/widget/cts/HorizontalScrollViewTest.java b/tests/tests/widget/src/android/widget/cts/HorizontalScrollViewTest.java
index 2862865..36398c3 100644
--- a/tests/tests/widget/src/android/widget/cts/HorizontalScrollViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/HorizontalScrollViewTest.java
@@ -24,6 +24,7 @@
import android.app.Activity;
import android.content.Context;
import android.cts.util.PollingCheck;
+import android.cts.util.WidgetTestUtils;
import android.graphics.Rect;
import android.test.ActivityInstrumentationTestCase2;
import android.test.UiThreadTest;
diff --git a/tests/tests/widget/src/android/widget/cts/ImageSwitcherTest.java b/tests/tests/widget/src/android/widget/cts/ImageSwitcherTest.java
index c0e606c..eb75557 100644
--- a/tests/tests/widget/src/android/widget/cts/ImageSwitcherTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ImageSwitcherTest.java
@@ -23,6 +23,7 @@
import android.content.Context;
import android.content.res.Resources;
+import android.cts.util.WidgetTestUtils;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
diff --git a/tests/tests/widget/src/android/widget/cts/ImageViewTest.java b/tests/tests/widget/src/android/widget/cts/ImageViewTest.java
index 7b0b65a..c93d4a1 100644
--- a/tests/tests/widget/src/android/widget/cts/ImageViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ImageViewTest.java
@@ -29,6 +29,7 @@
import android.app.Activity;
import android.content.Context;
+import android.cts.util.WidgetTestUtils;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
diff --git a/tests/tests/widget/src/android/widget/cts/RemoteViewsActivityTest.java b/tests/tests/widget/src/android/widget/cts/RemoteViewsActivityTest.java
index a03edce..ab109b1 100644
--- a/tests/tests/widget/src/android/widget/cts/RemoteViewsActivityTest.java
+++ b/tests/tests/widget/src/android/widget/cts/RemoteViewsActivityTest.java
@@ -17,6 +17,7 @@
package android.widget.cts;
import android.app.Activity;
+import android.cts.util.NullWebViewUtils;
import android.os.Parcel;
import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.MediumTest;
diff --git a/tests/tests/widget/src/android/widget/cts/RemoteViewsCtsActivity.java b/tests/tests/widget/src/android/widget/cts/RemoteViewsCtsActivity.java
index 6826eb3..4da5aa2 100644
--- a/tests/tests/widget/src/android/widget/cts/RemoteViewsCtsActivity.java
+++ b/tests/tests/widget/src/android/widget/cts/RemoteViewsCtsActivity.java
@@ -19,6 +19,7 @@
import com.android.cts.widget.R;
import android.app.Activity;
+import android.cts.util.NullWebViewUtils;
import android.os.Bundle;
import android.widget.RemoteViews;
diff --git a/tests/tests/widget/src/android/widget/cts/RemoteViewsTest.java b/tests/tests/widget/src/android/widget/cts/RemoteViewsTest.java
index 8d1cddf..328f9f3 100644
--- a/tests/tests/widget/src/android/widget/cts/RemoteViewsTest.java
+++ b/tests/tests/widget/src/android/widget/cts/RemoteViewsTest.java
@@ -26,6 +26,7 @@
import android.app.Instrumentation.ActivityMonitor;
import android.content.Intent;
import android.content.res.ColorStateList;
+import android.cts.util.WidgetTestUtils;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
diff --git a/tests/tests/widget/src/android/widget/cts/SimpleAdapterTest.java b/tests/tests/widget/src/android/widget/cts/SimpleAdapterTest.java
index 90ff617..c530293 100644
--- a/tests/tests/widget/src/android/widget/cts/SimpleAdapterTest.java
+++ b/tests/tests/widget/src/android/widget/cts/SimpleAdapterTest.java
@@ -20,6 +20,7 @@
import android.content.Context;
+import android.cts.util.WidgetTestUtils;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.test.InstrumentationTestCase;
diff --git a/tests/tests/widget/src/android/widget/cts/SimpleCursorAdapterTest.java b/tests/tests/widget/src/android/widget/cts/SimpleCursorAdapterTest.java
index f19dce7..13184de 100644
--- a/tests/tests/widget/src/android/widget/cts/SimpleCursorAdapterTest.java
+++ b/tests/tests/widget/src/android/widget/cts/SimpleCursorAdapterTest.java
@@ -20,6 +20,7 @@
import android.content.Context;
+import android.cts.util.WidgetTestUtils;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.graphics.Bitmap;
diff --git a/tests/tests/widget/src/android/widget/cts/SimpleCursorTreeAdapterTest.java b/tests/tests/widget/src/android/widget/cts/SimpleCursorTreeAdapterTest.java
index 0db5322..c9fdbc3 100644
--- a/tests/tests/widget/src/android/widget/cts/SimpleCursorTreeAdapterTest.java
+++ b/tests/tests/widget/src/android/widget/cts/SimpleCursorTreeAdapterTest.java
@@ -20,6 +20,7 @@
import android.content.Context;
+import android.cts.util.WidgetTestUtils;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.graphics.Bitmap;
diff --git a/tests/tests/widget/src/android/widget/cts/TabHostTest.java b/tests/tests/widget/src/android/widget/cts/TabHostTest.java
index 3af8d9c..00ecd40 100644
--- a/tests/tests/widget/src/android/widget/cts/TabHostTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TabHostTest.java
@@ -22,6 +22,7 @@
import android.app.Activity;
import android.app.ActivityGroup;
import android.content.Intent;
+import android.cts.util.WidgetTestUtils;
import android.test.ActivityInstrumentationTestCase2;
import android.test.UiThreadTest;
import android.view.View;
diff --git a/tests/tests/widget/src/android/widget/cts/TestThread.java b/tests/tests/widget/src/android/widget/cts/TestThread.java
deleted file mode 100644
index 78295b9..0000000
--- a/tests/tests/widget/src/android/widget/cts/TestThread.java
+++ /dev/null
@@ -1,93 +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.widget.cts;
-
-/**
- * Thread class for executing a Runnable containing assertions in a separate thread.
- * Uncaught exceptions in the Runnable are rethrown in the context of the the thread
- * calling the <code>runTest()</code> method.
- */
-public final class TestThread extends Thread {
- private Throwable mThrowable;
- private Runnable mTarget;
-
- public TestThread(Runnable target) {
- mTarget = target;
- }
-
- @Override
- public final void run() {
- try {
- mTarget.run();
- } catch (Throwable t) {
- mThrowable = t;
- }
- }
-
- /**
- * Run the target Runnable object and wait until the test finish or throw
- * out Exception if test fail.
- *
- * @param runTime
- * @throws Throwable
- */
- public void runTest(long runTime) throws Throwable {
- start();
- joinAndCheck(runTime);
- }
-
- /**
- * Get the Throwable object which is thrown when test running
- * @return The Throwable object
- */
- public Throwable getThrowable() {
- return mThrowable;
- }
-
- /**
- * Set the Throwable object which is thrown when test running
- * @param t The Throwable object
- */
- public void setThrowable(Throwable t) {
- mThrowable = t;
- }
-
- /**
- * Wait for the test thread to complete and throw the stored exception if there is one.
- *
- * @param runTime The time to wait for the test thread to complete.
- * @throws Throwable
- */
- public void joinAndCheck(long runTime) throws Throwable {
- this.join(runTime);
- if (this.isAlive()) {
- this.interrupt();
- this.join(runTime);
- throw new Exception("Thread did not finish within allotted time.");
- }
- checkException();
- }
-
- /**
- * Check whether there is an exception when running Runnable object.
- * @throws Throwable
- */
- public void checkException() throws Throwable {
- if (mThrowable != null) {
- throw mThrowable;
- }
- }
-}
diff --git a/tests/tests/widget/src/android/widget/cts/TextViewTest.java b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
index c5d9985..72193e7 100644
--- a/tests/tests/widget/src/android/widget/cts/TextViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
@@ -28,6 +28,7 @@
import android.content.res.ColorStateList;
import android.content.res.Resources.NotFoundException;
import android.cts.util.PollingCheck;
+import android.cts.util.WidgetTestUtils;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Paint;
diff --git a/tests/tests/widget/src/android/widget/cts/ViewGroupCtsActivity.java b/tests/tests/widget/src/android/widget/cts/ViewGroupCtsActivity.java
index 378395e..4e14fc2 100644
--- a/tests/tests/widget/src/android/widget/cts/ViewGroupCtsActivity.java
+++ b/tests/tests/widget/src/android/widget/cts/ViewGroupCtsActivity.java
@@ -17,7 +17,7 @@
package android.widget.cts;
import android.app.Activity;
-import android.app.cts.CTSResult;
+import android.cts.util.CTSResult;
import android.os.Bundle;
import android.os.Handler;
import android.widget.TextView;
diff --git a/tests/tests/widget/src/android/widget/cts/WidgetTestUtils.java b/tests/tests/widget/src/android/widget/cts/WidgetTestUtils.java
deleted file mode 100644
index 2df6629..0000000
--- a/tests/tests/widget/src/android/widget/cts/WidgetTestUtils.java
+++ /dev/null
@@ -1,138 +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.widget.cts;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-
-import java.io.IOException;
-
-import junit.framework.Assert;
-
-/**
- * The useful methods for widget test.
- */
-public class WidgetTestUtils {
- /**
- * Assert that two bitmaps are equal.
- *
- * @param Bitmap b1 the first bitmap which needs to compare.
- * @param Bitmap b2 the second bitmap which needs to compare.
- */
- public static void assertEquals(Bitmap b1, Bitmap b2) {
- if (b1 == b2) {
- return;
- }
-
- if (b1 == null || b2 == null) {
- Assert.fail("the bitmaps are not equal");
- }
-
- // b1 and b2 are all not null.
- if (b1.getWidth() != b2.getWidth() || b1.getHeight() != b2.getHeight()
- || b1.getConfig() != b2.getConfig()) {
- Assert.fail("the bitmaps are not equal");
- }
-
- int w = b1.getWidth();
- int h = b1.getHeight();
- int s = w * h;
- int[] pixels1 = new int[s];
- int[] pixels2 = new int[s];
-
- b1.getPixels(pixels1, 0, w, 0, 0, w, h);
- b2.getPixels(pixels2, 0, w, 0, 0, w, h);
-
- for (int i = 0; i < s; i++) {
- if (pixels1[i] != pixels2[i]) {
- Assert.fail("the bitmaps are not equal");
- }
- }
- }
-
- /**
- * Find beginning of the special element.
- * @param parser XmlPullParser will be parsed.
- * @param firstElementName the target element name.
- *
- * @throws XmlPullParserException if XML Pull Parser related faults occur.
- * @throws IOException if I/O-related error occur when parsing.
- */
- public static final void beginDocument(XmlPullParser parser, String firstElementName)
- throws XmlPullParserException, IOException {
- Assert.assertNotNull(parser);
- Assert.assertNotNull(firstElementName);
-
- int type;
- while ((type = parser.next()) != XmlPullParser.START_TAG
- && type != XmlPullParser.END_DOCUMENT) {
- ;
- }
-
- if (!parser.getName().equals(firstElementName)) {
- throw new XmlPullParserException("Unexpected start tag: found " + parser.getName()
- + ", expected " + firstElementName);
- }
- }
-
- /**
- * Compare the expected pixels with actual, scaling for the target context density
- *
- * @throws AssertionFailedError
- */
- public static void assertScaledPixels(int expected, int actual, Context context) {
- Assert.assertEquals(expected * context.getResources().getDisplayMetrics().density,
- actual, 3);
- }
-
- /** Converts dips into pixels using the {@link Context}'s density. */
- public static int convertDipToPixels(Context context, int dip) {
- float density = context.getResources().getDisplayMetrics().density;
- return Math.round(density * dip);
- }
-
- /**
- * Retrieve a bitmap that can be used for comparison on any density
- * @param resources
- * @return the {@link Bitmap} or <code>null</code>
- */
- public static Bitmap getUnscaledBitmap(Resources resources, int resId) {
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inScaled = false;
- return BitmapFactory.decodeResource(resources, resId, options);
- }
-
- /**
- * Retrieve a dithered bitmap that can be used for comparison on any density
- * @param resources
- * @param config the preferred config for the returning bitmap
- * @return the {@link Bitmap} or <code>null</code>
- */
- public static Bitmap getUnscaledAndDitheredBitmap(Resources resources,
- int resId, Bitmap.Config config) {
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inDither = true;
- options.inScaled = false;
- options.inPreferredConfig = config;
- return BitmapFactory.decodeResource(resources, resId, options);
- }
-}
diff --git a/tests/webgl/src/android/webgl/WebGLActivity.java b/tests/webgl/src/android/webgl/WebGLActivity.java
index e88de16..3f911c4 100644
--- a/tests/webgl/src/android/webgl/WebGLActivity.java
+++ b/tests/webgl/src/android/webgl/WebGLActivity.java
@@ -19,9 +19,9 @@
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
+import android.cts.util.NullWebViewUtils;
import android.os.Bundle;
import android.util.Log;
-import android.webgl.cts.NullWebViewUtils;
import android.webgl.cts.R;
import android.webkit.WebView;
import android.webkit.JavascriptInterface;
diff --git a/tests/webgl/src/android/webgl/cts/NullWebViewUtils.java b/tests/webgl/src/android/webgl/cts/NullWebViewUtils.java
deleted file mode 100644
index 861cc22..0000000
--- a/tests/webgl/src/android/webgl/cts/NullWebViewUtils.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2010 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.webgl.cts;
-
-import android.content.Context;
-import android.content.pm.PackageManager;
-
-/**
- * Utilities to enable the android.webkit.* CTS tests (and others that rely on a functioning
- * android.webkit.WebView implementation) to determine whether a functioning WebView is present
- * on the device or not.
- *
- * Test cases that require android.webkit.* classes should wrap their first usage of WebView in a
- * try catch block, and pass any exception that is thrown to
- * NullWebViewUtils.determineIfWebViewAvailable. The return value of
- * NullWebViewUtils.isWebViewAvailable will then determine if the test should expect to be able to
- * use a WebView.
- */
-public class NullWebViewUtils {
-
- private static boolean sWebViewUnavailable;
-
- /**
- * @param context Current Activity context, used to query the PackageManager.
- * @param t An exception thrown by trying to invoke android.webkit.* APIs.
- */
- public static void determineIfWebViewAvailable(Context context, Throwable t) {
- sWebViewUnavailable = !hasWebViewFeature(context) && checkCauseWasUnsupportedOperation(t);
- }
-
- /**
- * After calling determineIfWebViewAvailable, this returns whether a WebView is available on the
- * device and wheter the test can rely on it.
- * @return True iff. PackageManager determined that there is no WebView on the device and the
- * exception thrown from android.webkit.* was UnsupportedOperationException.
- */
- public static boolean isWebViewAvailable() {
- return !sWebViewUnavailable;
- }
-
- private static boolean hasWebViewFeature(Context context) {
- // Query the system property that determins if there is a functional WebView on the device.
- PackageManager pm = context.getPackageManager();
- return pm.hasSystemFeature(PackageManager.FEATURE_WEBVIEW);
- }
-
- private static boolean checkCauseWasUnsupportedOperation(Throwable t) {
- if (t == null) return false;
- while (t.getCause() != null) {
- t = t.getCause();
- }
- return t instanceof UnsupportedOperationException;
- }
-
- /**
- * Some CTS tests (by design) first use android.webkit.* from a background thread. This helper
- * allows the test to catch the UnsupportedOperationException from that background thread, and
- * then query the result from the test main thread.
- */
- public static class NullWebViewFromThreadExceptionHandler
- implements Thread.UncaughtExceptionHandler {
- private Throwable mPendingException;
-
- @Override
- public void uncaughtException(Thread t, Throwable e) {
- mPendingException = e;
- }
-
- public boolean isWebViewAvailable(Context context) {
- return hasWebViewFeature(context) ||
- !checkCauseWasUnsupportedOperation(mPendingException);
- }
- }
-}
diff --git a/tools/cts-api-coverage/src/com/android/cts/apicoverage/CtsApiCoverage.java b/tools/cts-api-coverage/src/com/android/cts/apicoverage/CtsApiCoverage.java
index 2109bbf..d596cba 100644
--- a/tools/cts-api-coverage/src/com/android/cts/apicoverage/CtsApiCoverage.java
+++ b/tools/cts-api-coverage/src/com/android/cts/apicoverage/CtsApiCoverage.java
@@ -176,8 +176,15 @@
DexDepsXmlHandler dexDepsXmlHandler = new DexDepsXmlHandler(apiCoverage);
xmlReader.setContentHandler(dexDepsXmlHandler);
- Process process = new ProcessBuilder(dexdeps, "--format=xml", testApk.getPath()).start();
- xmlReader.parse(new InputSource(process.getInputStream()));
+ String apkPath = testApk.getPath();
+ Process process = new ProcessBuilder(dexdeps, "--format=xml", apkPath).start();
+ try {
+ xmlReader.parse(new InputSource(process.getInputStream()));
+ } catch (SAXException e) {
+ // Catch this exception, but continue. SAXException is acceptable in cases
+ // where the apk does not contain a classes.dex and therefore parsing won't work.
+ System.err.println("warning: dexdeps failed for: " + apkPath);
+ }
}
private static void outputCoverageReport(ApiCoverage apiCoverage, List<File> testApks,
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildProvider.java b/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildProvider.java
index e7b72ac..27f9135 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildProvider.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildProvider.java
@@ -31,7 +31,7 @@
@Option(name="cts-install-path", description="the path to the cts installation to use")
private String mCtsRootDirPath = System.getProperty("CTS_ROOT");
- public static final String CTS_BUILD_VERSION = "L_r0";
+ public static final String CTS_BUILD_VERSION = "5.0_r0.5";
/**
* {@inheritDoc}
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/DeqpTestRunner.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/DeqpTestRunner.java
index 35b8a66..8eb1621 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/DeqpTestRunner.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/DeqpTestRunner.java
@@ -77,6 +77,17 @@
}
/**
+ * Set the CTS build container.
+ * <p/>
+ * Exposed so unit tests can mock the provided build.
+ *
+ * @param buildHelper
+ */
+ public void setBuildHelper(CtsBuildHelper buildHelper) {
+ mCtsBuild = buildHelper;
+ }
+
+ /**
* Enable or disable raw dEQP test log collection.
*/
public void setCollectLogs(boolean logData) {
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/WrappedGTest.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/WrappedGTest.java
index a5c3e4c..e3ff825 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/WrappedGTest.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/WrappedGTest.java
@@ -113,7 +113,7 @@
WrappedGTestResultParser resultParser = new WrappedGTestResultParser(id, listener);
resultParser.setFakePackagePrefix(mPackageName + ".");
try {
- String options = mAbi == null ? "" : String.format("--abi %s ", mAbi);
+ String options = mAbi == null ? "" : String.format("--abi %s ", mAbi.getName());
String command = String.format("am instrument -w %s%s/.%s", options, mAppNameSpace, mRunner);
mDevice.executeShellCommand(command, resultParser, mMaxTestTimeMs, 0);
} catch (DeviceNotAvailableException e) {
diff --git a/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/DeqpTestRunnerTest.java b/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/DeqpTestRunnerTest.java
index cd9c738..c41793f 100644
--- a/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/DeqpTestRunnerTest.java
+++ b/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/DeqpTestRunnerTest.java
@@ -15,6 +15,7 @@
*/
package com.android.cts.tradefed.testtype;
+import com.android.cts.tradefed.build.StubCtsBuildHelper;
import com.android.cts.tradefed.UnitTests;
import com.android.cts.util.AbiUtils;
import com.android.ddmlib.IShellOutputReceiver;
@@ -29,6 +30,7 @@
import org.easymock.EasyMock;
import org.easymock.IAnswer;
+import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
@@ -43,6 +45,8 @@
private static final String LOG_FILE_NAME = "/sdcard/TestLog.qpa";
private static final String INSTRUMENTATION_NAME =
"com.drawelements.deqp/com.drawelements.deqp.testercore.DeqpInstrumentation";
+ private static final String DEQP_ONDEVICE_APK = "com.drawelements.deqp.apk";
+ private static final String DEQP_ONDEVICE_PKG = "com.drawelements.deqp";
/**
* {@inheritDoc}
@@ -118,6 +122,13 @@
if (majorVersion > requiredMajorVersion
|| (majorVersion == requiredMajorVersion && minorVersion >= requiredMinorVersion)) {
+ EasyMock.expect(mockDevice.uninstallPackage(EasyMock.eq(DEQP_ONDEVICE_PKG)))
+ .andReturn("").once();
+ EasyMock.expect(mockDevice.installPackage(EasyMock.<File>anyObject(),
+ EasyMock.eq(true),
+ EasyMock.eq(AbiUtils.createAbiFlag(UnitTests.ABI.getName()))))
+ .andReturn(null).once();
+
EasyMock.expect(mockDevice.executeShellCommand(
EasyMock.eq("rm " + CASE_LIST_FILE_NAME))).andReturn("").once();
@@ -129,7 +140,7 @@
String command = String.format(
"am instrument %s -w -e deqpLogFileName \"%s\" -e deqpCmdLine \""
- + "--deqp-caselist-file=%s --deqp-gl-config-name=rgba8888d24s8\""
+ + "--deqp-caselist-file=%s --deqp-gl-config-name=rgba8888d24s8\" "
+ "-e deqpLogData \"%s\" %s",
AbiUtils.createAbiFlag(UnitTests.ABI.getName()), LOG_FILE_NAME,
CASE_LIST_FILE_NAME, false, INSTRUMENTATION_NAME);
@@ -149,6 +160,9 @@
return null;
}
});
+
+ EasyMock.expect(mockDevice.uninstallPackage(EasyMock.eq(DEQP_ONDEVICE_PKG)))
+ .andReturn("").once();
}
mockListener.testRunStarted(ID, 1);
@@ -167,6 +181,7 @@
EasyMock.replay(mockListener);
deqpTest.setDevice(mockDevice);
+ deqpTest.setBuildHelper(new StubCtsBuildHelper());
deqpTest.run(mockListener);
EasyMock.verify(mockListener);
@@ -223,6 +238,13 @@
EasyMock.expect(mockDevice.getProperty("ro.opengles.version"))
.andReturn(Integer.toString(version)).atLeastOnce();
+ EasyMock.expect(mockDevice.uninstallPackage(EasyMock.eq(DEQP_ONDEVICE_PKG))).andReturn("")
+ .once();
+
+ EasyMock.expect(mockDevice.installPackage(EasyMock.<File>anyObject(),
+ EasyMock.eq(true), EasyMock.eq(AbiUtils.createAbiFlag(UnitTests.ABI.getName()))))
+ .andReturn(null).once();
+
EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("rm " + CASE_LIST_FILE_NAME)))
.andReturn("").once();
@@ -234,7 +256,7 @@
String command = String.format(
"am instrument %s -w -e deqpLogFileName \"%s\" -e deqpCmdLine \""
- + "--deqp-caselist-file=%s --deqp-gl-config-name=rgba8888d24s8\""
+ + "--deqp-caselist-file=%s --deqp-gl-config-name=rgba8888d24s8\" "
+ "-e deqpLogData \"%s\" %s",
AbiUtils.createAbiFlag(UnitTests.ABI.getName()), LOG_FILE_NAME,
CASE_LIST_FILE_NAME, false, INSTRUMENTATION_NAME);
@@ -263,7 +285,7 @@
if (!pass) {
mockListener.testFailed(testId,
- resultCode + ":Detail" + resultCode);
+ resultCode + ": Detail" + resultCode);
EasyMock.expectLastCall().once();
}
@@ -274,10 +296,14 @@
mockListener.testRunEnded(EasyMock.anyLong(), EasyMock.<Map<String, String>>notNull());
EasyMock.expectLastCall().once();
+ EasyMock.expect(mockDevice.uninstallPackage(EasyMock.eq(DEQP_ONDEVICE_PKG))).andReturn("")
+ .once();
+
EasyMock.replay(mockDevice);
EasyMock.replay(mockListener);
deqpTest.setDevice(mockDevice);
+ deqpTest.setBuildHelper(new StubCtsBuildHelper());
deqpTest.run(mockListener);
EasyMock.verify(mockListener);
@@ -287,7 +313,7 @@
/**
* Test running multiple test cases.
*/
- public void testRun_multipleTets() throws Exception {
+ public void testRun_multipleTests() throws Exception {
/* MultiLineReceiver expects "\r\n" line ending. */
final String output = "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseName\r\n"
+ "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
@@ -398,6 +424,12 @@
EasyMock.expect(mockDevice.getProperty("ro.opengles.version"))
.andReturn(Integer.toString(version)).atLeastOnce();
+ EasyMock.expect(mockDevice.uninstallPackage(EasyMock.eq(DEQP_ONDEVICE_PKG))).andReturn("")
+ .once();
+ EasyMock.expect(mockDevice.installPackage(EasyMock.<File>anyObject(),
+ EasyMock.eq(true), EasyMock.eq(AbiUtils.createAbiFlag(UnitTests.ABI.getName()))))
+ .andReturn(null).once();
+
EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("rm " + CASE_LIST_FILE_NAME)))
.andReturn("").once();
@@ -409,7 +441,7 @@
String command = String.format(
"am instrument %s -w -e deqpLogFileName \"%s\" -e deqpCmdLine \""
- + "--deqp-caselist-file=%s --deqp-gl-config-name=rgba8888d24s8\""
+ + "--deqp-caselist-file=%s --deqp-gl-config-name=rgba8888d24s8\" "
+ "-e deqpLogData \"%s\" %s",
AbiUtils.createAbiFlag(UnitTests.ABI.getName()), LOG_FILE_NAME,
CASE_LIST_FILE_NAME, false, INSTRUMENTATION_NAME);
@@ -446,10 +478,14 @@
mockListener.testRunEnded(EasyMock.anyLong(), EasyMock.<Map<String, String>>notNull());
EasyMock.expectLastCall().once();
+ EasyMock.expect(mockDevice.uninstallPackage(EasyMock.eq(DEQP_ONDEVICE_PKG))).andReturn("")
+ .once();
+
EasyMock.replay(mockDevice);
EasyMock.replay(mockListener);
deqpTest.setDevice(mockDevice);
+ deqpTest.setBuildHelper(new StubCtsBuildHelper());
deqpTest.run(mockListener);
EasyMock.verify(mockListener);
diff --git a/tools/utils/buildCts.py b/tools/utils/buildCts.py
index 85adb0c..4a1b2f3 100755
--- a/tools/utils/buildCts.py
+++ b/tools/utils/buildCts.py
@@ -158,6 +158,7 @@
# CTS Stable plan
plan = tools.TestPlan(packages)
plan.Exclude(r'com\.android\.cts\.browserbench')
+ plan.Exclude(r'com\.android\.cts\.filesystemperf\.RandomRWTest$')
for package, test_list in flaky_tests.iteritems():
plan.ExcludeTests(package, test_list)
self.__WritePlan(plan, 'CTS-stable')
@@ -166,6 +167,7 @@
plan = tools.TestPlan(packages)
plan.Exclude('.*')
plan.Include(r'com\.android\.cts\.browserbench')
+ plan.Include(r'com\.android\.cts\.filesystemperf\.RandomRWTest$')
for package, test_list in flaky_tests.iteritems():
plan.Include(package+'$')
plan.IncludeTests(package, test_list)
@@ -180,6 +182,8 @@
plan.Exclude('.*')
for package, test_list in small_tests.iteritems():
plan.Include(package+'$')
+ plan.Exclude(r'com\.android\.cts\.browserbench')
+ plan.Exclude(r'com\.android\.cts\.filesystemperf\.RandomRWTest$')
for package, test_list in flaky_tests.iteritems():
plan.ExcludeTests(package, test_list)
self.__WritePlan(plan, 'CTS-kitkat-small')
@@ -189,6 +193,8 @@
plan.Exclude('.*')
for package, test_list in medium_tests.iteritems():
plan.Include(package+'$')
+ plan.Exclude(r'com\.android\.cts\.browserbench')
+ plan.Exclude(r'com\.android\.cts\.filesystemperf\.RandomRWTest$')
for package, test_list in flaky_tests.iteritems():
plan.ExcludeTests(package, test_list)
self.__WritePlan(plan, 'CTS-kitkat-medium')
@@ -197,6 +203,8 @@
plan = tools.TestPlan(packages)
plan.Exclude('.*')
plan.Include(r'android\.hardware$')
+ plan.Exclude(r'com\.android\.cts\.browserbench')
+ plan.Exclude(r'com\.android\.cts\.filesystemperf\.RandomRWTest$')
for package, test_list in flaky_tests.iteritems():
plan.ExcludeTests(package, test_list)
self.__WritePlan(plan, 'CTS-hardware')
@@ -205,6 +213,8 @@
plan = tools.TestPlan(packages)
plan.Exclude('.*')
plan.Include(r'android\.media$')
+ plan.Exclude(r'com\.android\.cts\.browserbench')
+ plan.Exclude(r'com\.android\.cts\.filesystemperf\.RandomRWTest$')
for package, test_list in flaky_tests.iteritems():
plan.ExcludeTests(package, test_list)
self.__WritePlan(plan, 'CTS-media')
@@ -213,6 +223,8 @@
plan = tools.TestPlan(packages)
plan.Exclude('.*')
plan.Include(r'android\.mediastress$')
+ plan.Exclude(r'com\.android\.cts\.browserbench')
+ plan.Exclude(r'com\.android\.cts\.filesystemperf\.RandomRWTest$')
for package, test_list in flaky_tests.iteritems():
plan.ExcludeTests(package, test_list)
self.__WritePlan(plan, 'CTS-mediastress')
@@ -222,6 +234,8 @@
plan.Exclude('.*')
for package, test_list in new_test_packages.iteritems():
plan.Include(package+'$')
+ plan.Exclude(r'com\.android\.cts\.browserbench')
+ plan.Exclude(r'com\.android\.cts\.filesystemperf\.RandomRWTest$')
for package, test_list in flaky_tests.iteritems():
plan.ExcludeTests(package, test_list)
self.__WritePlan(plan, 'CTS-l-tests')
@@ -237,6 +251,8 @@
plan.Exclude(r'android\.hardware$')
plan.Exclude(r'android\.media$')
plan.Exclude(r'android\.mediastress$')
+ plan.Exclude(r'com\.android\.cts\.browserbench')
+ plan.Exclude(r'com\.android\.cts\.filesystemperf\.RandomRWTest$')
for package, test_list in flaky_tests.iteritems():
plan.ExcludeTests(package, test_list)
self.__WritePlan(plan, 'CTS-staging')
@@ -270,6 +286,7 @@
'android.host.security' : [],
'android.net' : [],
'android.os' : [],
+ 'android.permission2' : [],
'android.security' : [],
'android.telephony' : [],
'android.webkit' : [],
@@ -313,7 +330,6 @@
'android.opengl' : [],
'android.openglperf' : [],
'android.permission' : [],
- 'android.permission2' : [],
'android.preference' : [],
'android.preference2' : [],
'android.provider' : [],
@@ -375,17 +391,10 @@
that are known to be flaky. """
return {
'android.app' : [
- 'cts.ActivityManagerTest#testIsRunningInTestHarness',
- 'cts.AlertDialogTest#testAlertDialogCancelable',
- 'cts.ExpandableListActivityTest#testCallback',],
+ 'cts.ActivityManagerTest#testIsRunningInTestHarness',],
'android.dpi' : [
'cts.DefaultManifestAttributesSdkTest#testPackageHasExpectedSdkVersion',],
'android.hardware' : [
- 'camera2.cts.CameraDeviceTest#testCameraDeviceRepeatingRequest',
- 'camera2.cts.ImageReaderTest#testImageReaderFromCameraJpeg',
- 'cts.CameraTest#testImmediateZoom',
- 'cts.CameraTest#testPreviewCallback',
- 'cts.CameraTest#testSmoothZoom',
'cts.CameraTest#testVideoSnapshot',
'cts.CameraGLTest#testCameraToSurfaceTextureMetadata',
'cts.CameraGLTest#testSetPreviewTextureBothCallbacks',
@@ -393,8 +402,6 @@
'android.media' : [
'cts.DecoderTest#testCodecResetsH264WithSurface',
'cts.StreamingMediaPlayerTest#testHLS',],
- 'android.mediastress' : [
- 'cts.NativeMediaTest#test480pPlay',],
'android.net' : [
'cts.ConnectivityManagerTest#testStartUsingNetworkFeature_enableHipri',
'cts.DnsTest#testDnsWorks',
@@ -403,9 +410,7 @@
'cts.SSLCertificateSocketFactoryTest#test_createSocket_simple',
'cts.SSLCertificateSocketFactoryTest#test_createSocket_wrapping',
'cts.TrafficStatsTest#testTrafficStatsForLocalhost',
- 'wifi.cts.NsdManagerTest#testAndroidTestCaseSetupProperly',
- 'wifi.cts.ScanResultTest#testAndroidTestCaseSetupProperly',
- 'wifi.cts.ScanResultTest#testScanResultTimeStamp',],
+ 'wifi.cts.NsdManagerTest#testAndroidTestCaseSetupProperly',],
'android.os' : [
'cts.BuildVersionTest#testReleaseVersion',
'cts.BuildTest#testIsSecureUserBuild',],
@@ -414,16 +419,11 @@
'cts.BannedFilesTest#testNoSuInPath',
'cts.ListeningPortsTest#testNoRemotelyAccessibleListeningUdp6Ports',
'cts.ListeningPortsTest#testNoRemotelyAccessibleListeningUdpPorts',
- 'cts.PackageSignatureTest#testPackageSignatures',],
+ 'cts.PackageSignatureTest#testPackageSignatures',
+ 'cts.SELinuxDomainTest#testSuDomain',
+ 'cts.SELinuxHostTest#testAllEnforcing',],
'android.webkit' : [
- 'cts.WebViewClientTest#testDoUpdateVisitedHistory',
- 'cts.WebViewClientTest#testLoadPage',
- 'cts.WebViewClientTest#testOnFormResubmission',
- 'cts.WebViewClientTest#testOnReceivedError',
- 'cts.WebViewClientTest#testOnReceivedHttpAuthRequest',
- 'cts.WebViewClientTest#testOnScaleChanged',
- 'cts.WebViewClientTest#testOnUnhandledKeyEvent',
- 'cts.WebViewTest#testSetInitialScale',]}
+ 'cts.WebViewClientTest#testOnUnhandledKeyEvent',]}
def LogGenerateDescription(name):
print 'Generating test description for package %s' % name