am 81c1ef94: Merge "Add bionic unit tests to CTS."
* commit '81c1ef94541a4cb44a9738b048a79fbc3ebd5e3f':
Add bionic unit tests to CTS.
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 afbf97e..46963a0 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/features/FeatureSummaryActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/features/FeatureSummaryActivity.java
@@ -172,6 +172,14 @@
new Feature(PackageManager.FEATURE_TELEVISION, false),
};
+ public static final Feature[] ALL_JELLY_BEAN_MR2_FEATURES = {
+ new Feature("android.software.app_widgets", false),
+ new Feature("android.software.input_methods", false),
+ new Feature("android.software.home_screen", false),
+ new Feature("android.hardware.bluetooth_le", false),
+ new Feature("android.hardware.camera.any", false),
+ };
+
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -202,6 +210,9 @@
// 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.JELLY_BEAN_MR2) {
+ Collections.addAll(features, ALL_JELLY_BEAN_MR2_FEATURES);
+ }
if (apiVersion >= Build.VERSION_CODES.JELLY_BEAN) {
Collections.addAll(features, ALL_JELLY_BEAN_FEATURES);
}
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 79b2e57..70d6f58 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_FilesTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_FilesTest.java
@@ -21,6 +21,7 @@
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
+import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Environment;
@@ -30,6 +31,8 @@
import android.test.AndroidTestCase;
import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
import java.io.IOException;
public class MediaStore_FilesTest extends AndroidTestCase {
@@ -150,6 +153,133 @@
}
}
+ public void testAccess() throws IOException {
+ // clean up from previous run
+ mResolver.delete(MediaStore.Images.Media.INTERNAL_CONTENT_URI,
+ "_data NOT LIKE ?", new String[] { "/system/%" } );
+
+ // insert some dummy starter data into the provider
+ ContentValues values = new ContentValues();
+ values.put(MediaStore.Images.Media.DISPLAY_NAME, "My Bitmap");
+ values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
+ values.put(MediaStore.Images.Media.DATA, "/mnt/sdcard/dummy.jpg");
+ Uri uri = mResolver.insert(MediaStore.Images.Media.INTERNAL_CONTENT_URI, values);
+
+ // point _data at directory and try to get an fd for it
+ values = new ContentValues();
+ values.put("_data", "/data/media");
+ mResolver.update(uri, values, null, null);
+ ParcelFileDescriptor pfd = null;
+ try {
+ pfd = mResolver.openFileDescriptor(uri, "r");
+ pfd.close();
+ fail("shouldn't be here");
+ } catch (FileNotFoundException e) {
+ // expected
+ }
+
+ // try to create a file in a place we don't have access to
+ values = new ContentValues();
+ values.put("_data", "/data/media/test.dat");
+ mResolver.update(uri, values, null, null);
+ try {
+ pfd = mResolver.openFileDescriptor(uri, "w");
+ pfd.close();
+ fail("shouldn't be here");
+ } catch (FileNotFoundException e) {
+ // expected
+ }
+ // read file back
+ try {
+ pfd = mResolver.openFileDescriptor(uri, "r");
+ pfd.close();
+ fail("shouldn't be here");
+ } catch (FileNotFoundException e) {
+ // expected
+ }
+
+ // point _data at media database and read it
+ values = new ContentValues();
+ values.put("_data", "/data/data/com.android.providers.media/databases/internal.db");
+ mResolver.update(uri, values, null, null);
+ try {
+ pfd = mResolver.openFileDescriptor(uri, "r");
+ pfd.close();
+ fail("shouldn't be here");
+ } catch (FileNotFoundException e) {
+ // expected
+ }
+
+ // Insert a private file into the database. Since it's private, the media provider won't
+ // be able to open it
+ FileOutputStream fos = mContext.openFileOutput("dummy.dat", Context.MODE_PRIVATE);
+ fos.write(0);
+ fos.close();
+ File path = mContext.getFileStreamPath("dummy.dat");
+ values = new ContentValues();
+ values.put("_data", path.getAbsolutePath());
+
+ mResolver.update(uri, values, null, null);
+ try {
+ pfd = mResolver.openFileDescriptor(uri, "r");
+ pfd.close();
+ fail("shouldn't be here");
+ } catch (FileNotFoundException e) {
+ // expected
+ }
+ // now make the file world-readable
+ fos = mContext.openFileOutput("dummy.dat", Context.MODE_WORLD_READABLE);
+ fos.write(0);
+ fos.close();
+ try {
+ pfd = mResolver.openFileDescriptor(uri, "r");
+ pfd.close();
+ } catch (FileNotFoundException e) {
+ fail("failed to open file");
+ }
+ path.delete();
+
+ File sdfile = null;
+ if (Environment.isExternalStorageEmulated()) {
+ // create file on sdcard and check access via real path
+ String fileDir = Environment.getExternalStorageDirectory() +
+ "/" + getClass().getCanonicalName() + "/test.mp3";
+ sdfile = new File(fileDir);
+ writeFile(R.raw.testmp3, sdfile.getCanonicalPath());
+ assertTrue(sdfile.exists());
+ values = new ContentValues();
+ values.put("_data", sdfile.getCanonicalPath());
+ mResolver.update(uri, values, null, null);
+ try {
+ pfd = mResolver.openFileDescriptor(uri, "r");
+
+ // get the real path from the file descriptor
+ File real = new File("/proc/self/fd/" + pfd.getFd());
+ values = new ContentValues();
+ values.put("_data", real.getCanonicalPath());
+ mResolver.update(uri, values, null, null);
+ pfd.close();
+
+ // we shouldn't be able to access this
+ try {
+ pfd = mResolver.openFileDescriptor(uri, "r");
+ pfd.close();
+ fail("shouldn't be here");
+ } catch (FileNotFoundException e) {
+ // expected
+ }
+ } catch (FileNotFoundException e) {
+ fail("couldn't open file");
+ }
+ }
+
+ // clean up
+ assertEquals(1, mResolver.delete(uri, null, null));
+ if (sdfile != null) {
+ sdfile.delete();
+ }
+ }
+
private void writeFile(int resid, String path) throws IOException {
File out = new File(path);
File dir = out.getParentFile();
diff --git a/tests/tests/provider/src/android/provider/cts/VoicemailContractTest.java b/tests/tests/provider/src/android/provider/cts/VoicemailContractTest.java
index ffb60f4..34a546e 100644
--- a/tests/tests/provider/src/android/provider/cts/VoicemailContractTest.java
+++ b/tests/tests/provider/src/android/provider/cts/VoicemailContractTest.java
@@ -21,6 +21,7 @@
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
+import android.os.RemoteException;
import android.provider.VoicemailContract;
import android.provider.VoicemailContract.Status;
import android.provider.VoicemailContract.Voicemails;
@@ -140,6 +141,66 @@
cursor.close();
}
+ // Data column should be automatically generated during insert.
+ public void testInsert_doesNotUpdateDataColumn() throws Exception {
+
+ final String newFilePath = "my/new/file/path";
+ final ContentValues value = buildContentValuesForNewVoicemail();
+ value.put(Voicemails._DATA, newFilePath);
+ mVoicemailProvider.insert(mVoicemailContentUri, value);
+
+ assertDataNotEquals(newFilePath);
+ }
+
+ public void testDataColumnUpdate_throwsIllegalArgumentException() throws Exception {
+
+ final ContentValues value = buildContentValuesForNewVoicemail();
+ final Uri uri = mVoicemailProvider.insert(mVoicemailContentUri, value);
+
+ // Test: update
+ final String newFilePath = "another/file/path";
+
+ value.clear();
+ value.put(Voicemails._DATA, newFilePath);
+ try {
+ mVoicemailProvider.update(uri, value, null, null);
+ fail("IllegalArgumentException expected but not thrown.");
+ } catch (IllegalArgumentException e) {
+ // pass
+ }
+
+ assertDataNotEquals(newFilePath);
+ }
+
+ private void assertDataNotEquals(String newFilePath) throws RemoteException {
+ // Make sure data value is not actually updated.
+ final Cursor cursor = mVoicemailProvider.query(mVoicemailContentUri,
+ new String[]{Voicemails._DATA}, null, null, null);
+ cursor.moveToNext();
+ final String data = cursor.getString(0);
+ assertFalse(data.equals(newFilePath));
+ }
+
+ private ContentValues buildContentValuesForNewVoicemail() {
+ final String insertCallsNumber = "0123456789";
+ final long insertCallsDuration = 120;
+ final String insertSourceData = "internal_id";
+ final String insertMimeType = "audio/mp3";
+ final long insertDate = 1324478862000L;
+
+ ContentValues value = new ContentValues();
+ value.put(Voicemails.NUMBER, insertCallsNumber);
+ value.put(Voicemails.DATE, insertDate);
+ value.put(Voicemails.DURATION, insertCallsDuration);
+ // Source package is expected to be inserted by the provider, if not set.
+ value.put(Voicemails.SOURCE_DATA, insertSourceData);
+ value.put(Voicemails.MIME_TYPE, insertMimeType);
+ value.put(Voicemails.IS_READ, false);
+ value.put(Voicemails.HAS_CONTENT, true);
+
+ return value;
+ }
+
public void testStatusTable() throws Exception {
final String[] STATUS_PROJECTION = new String[] {
Status._ID, Status.SOURCE_PACKAGE, Status.CONFIGURATION_STATE,