Merge "Check Device Certificates" into gingerbread
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/admin/PolicySerializationTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/admin/PolicySerializationTestActivity.java
index 49cc7fe..1591df3 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/admin/PolicySerializationTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/admin/PolicySerializationTestActivity.java
@@ -396,8 +396,7 @@
                     DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC,
                     DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC,
                     DevicePolicyManager.PASSWORD_QUALITY_NUMERIC,
-                    DevicePolicyManager.PASSWORD_QUALITY_SOMETHING,
-                    DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED
+                    DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
             };
 
             int index = random.nextInt(passwordQualities.length);
@@ -426,8 +425,6 @@
                     return mContext.getString(R.string.da_password_quality_numeric);
                 case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
                     return mContext.getString(R.string.da_password_quality_something);
-                case DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED:
-                    return mContext.getString(R.string.da_password_quality_unspecified);
                 default:
                     return Integer.toString(value);
             }
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 aad97ad..4c5694b 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/features/FeatureSummaryActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/features/FeatureSummaryActivity.java
@@ -40,6 +40,8 @@
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.Set;
 
 public class FeatureSummaryActivity extends PassFailButtons.ListActivity {
     /**
@@ -74,6 +76,23 @@
             this.required = required;
             this.present = false;
         }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) {
+                return true;
+            } else if (o == null || !(o instanceof Feature)) {
+                return false;
+            } else {
+                Feature feature = (Feature) o;
+                return name.equals(feature.name);
+            }
+        }
+
+        @Override
+        public int hashCode() {
+            return name.hashCode();
+        }
     }
 
     /**
@@ -115,6 +134,15 @@
     };
 
     public static final Feature[] ALL_GINGERBREAD_FEATURES = {
+            // Required features in prior releases that became optional in GB
+            new Feature("android.hardware.bluetooth", false),
+            new Feature("android.hardware.camera", false),
+            new Feature("android.hardware.location.gps", false),
+            new Feature("android.hardware.microphone", false),
+            new Feature("android.hardware.sensor.accelerometer", false),
+            new Feature("android.hardware.sensor.compass", false),
+
+            // New features in GB
             new Feature("android.hardware.audio.low_latency", false),
             new Feature("android.hardware.camera.front", false),
             new Feature("android.hardware.nfc", false),
@@ -151,16 +179,18 @@
         // roll over all known features & check whether device reports them
         boolean present = false;
         int statusIcon;
-        ArrayList<Feature> features = new ArrayList<Feature>();
+        Set<Feature> features = new LinkedHashSet<Feature>();
+
+        // 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.ECLAIR_MR1) {
-            Collections.addAll(features, ALL_ECLAIR_FEATURES);
+        if (apiVersion >= Build.VERSION_CODES.GINGERBREAD) {
+            Collections.addAll(features, ALL_GINGERBREAD_FEATURES);
         }
         if (apiVersion >= Build.VERSION_CODES.FROYO) {
             Collections.addAll(features, ALL_FROYO_FEATURES);
         }
-        if (apiVersion >= Build.VERSION_CODES.GINGERBREAD) {
-            Collections.addAll(features, ALL_GINGERBREAD_FEATURES);
+        if (apiVersion >= Build.VERSION_CODES.ECLAIR_MR1) {
+            Collections.addAll(features, ALL_ECLAIR_FEATURES);
         }
         for (Feature f : features) {
             HashMap<String, Object> row = new HashMap<String, Object>();
diff --git a/tests/tests/graphics/src/android/graphics/cts/BitmapFactoryTest.java b/tests/tests/graphics/src/android/graphics/cts/BitmapFactoryTest.java
old mode 100644
new mode 100755
index 4c6259c..fdffd51
--- a/tests/tests/graphics/src/android/graphics/cts/BitmapFactoryTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/BitmapFactoryTest.java
@@ -174,7 +174,8 @@
                 android.graphics.BitmapFactory.Options.class}
     )
     public void testDecodeFileDescriptor1() throws IOException {
-        FileDescriptor input = obtainDescriptor(obtainPath());
+        ParcelFileDescriptor pfd = obtainParcelDescriptor(obtainPath());
+        FileDescriptor input = pfd.getFileDescriptor();
         Rect r = new Rect(1, 1, 1, 1);
         Bitmap b = BitmapFactory.decodeFileDescriptor(input, r, mOpt1);
         assertNotNull(b);
@@ -191,7 +192,8 @@
         args = {java.io.FileDescriptor.class}
     )
     public void testDecodeFileDescriptor2() throws IOException {
-        FileDescriptor input = obtainDescriptor(obtainPath());
+        ParcelFileDescriptor pfd = obtainParcelDescriptor(obtainPath());
+        FileDescriptor input = pfd.getFileDescriptor();
         Bitmap b = BitmapFactory.decodeFileDescriptor(input);
         assertNotNull(b);
         // Test the bitmap size
@@ -240,10 +242,11 @@
         return mRes.openRawResource(R.drawable.start);
     }
 
-    private FileDescriptor obtainDescriptor(String path) throws IOException {
-      File file = new File(path);
-      return(ParcelFileDescriptor.open(file,
-              ParcelFileDescriptor.MODE_READ_ONLY).getFileDescriptor());
+    private ParcelFileDescriptor obtainParcelDescriptor(String path)
+            throws IOException {
+        File file = new File(path);
+        return(ParcelFileDescriptor.open(file,
+                ParcelFileDescriptor.MODE_READ_ONLY));
     }
 
     private String obtainPath() throws IOException {
diff --git a/tests/tests/graphics/src/android/graphics/cts/BitmapRegionDecoderTest.java b/tests/tests/graphics/src/android/graphics/cts/BitmapRegionDecoderTest.java
old mode 100644
new mode 100755
index e1ba12a..5cda2cb
--- a/tests/tests/graphics/src/android/graphics/cts/BitmapRegionDecoderTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/BitmapRegionDecoderTest.java
@@ -157,7 +157,8 @@
     public void testNewInstanceStringAndFileDescriptor() throws IOException {
         for (int i = 0; i < RES_IDS.length; ++i) {
             String filepath = obtainPath(i);
-            FileDescriptor fd = obtainDescriptor(filepath);
+            ParcelFileDescriptor pfd = obtainParcelDescriptor(filepath);
+            FileDescriptor fd = pfd.getFileDescriptor();
             try {
                 BitmapRegionDecoder decoder1 =
                         BitmapRegionDecoder.newInstance(filepath, false);
@@ -245,9 +246,11 @@
                     Bitmap wholeImage = BitmapFactory.decodeFile(filepath, opts);
                     compareRegionByRegion(decoder, opts, wholeImage);
 
-                    FileDescriptor fd1 = obtainDescriptor(filepath);
+                    ParcelFileDescriptor pfd1 = obtainParcelDescriptor(filepath);
+                    FileDescriptor fd1 = pfd1.getFileDescriptor();
                     decoder = BitmapRegionDecoder.newInstance(fd1, false);
-                    FileDescriptor fd2 = obtainDescriptor(filepath);
+                    ParcelFileDescriptor pfd2 = obtainParcelDescriptor(filepath);
+                    FileDescriptor fd2 = pfd2.getFileDescriptor();
                     compareRegionByRegion(decoder, opts, wholeImage);
                     wholeImage.recycle();
                 }
@@ -357,12 +360,14 @@
         return (file.getPath());
     }
 
-    private FileDescriptor obtainDescriptor(String path) throws IOException {
+    private ParcelFileDescriptor obtainParcelDescriptor(String path)
+            throws IOException {
         File file = new File(path);
         return(ParcelFileDescriptor.open(file,
-                ParcelFileDescriptor.MODE_READ_ONLY).getFileDescriptor());
+                ParcelFileDescriptor.MODE_READ_ONLY));
     }
 
+
     // Compare expected to actual to see if their diff is less then mseMargin.
     // lessThanMargin is to indicate whether we expect the diff to be
     // "less than" or "no less than".
diff --git a/tests/tests/media/src/android/media/cts/MediaScannerNotificationTest.java b/tests/tests/media/src/android/media/cts/MediaScannerNotificationTest.java
new file mode 100644
index 0000000..3c201ca
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/MediaScannerNotificationTest.java
@@ -0,0 +1,107 @@
+/*
+ * 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.media.cts;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.Uri;
+import android.os.Environment;
+import android.test.AndroidTestCase;
+
+
+public class MediaScannerNotificationTest extends AndroidTestCase {
+    private static final int MEDIA_SCANNER_TIME_OUT = 2000;
+
+    private ScannerNotificationReceiver mScannerStartedReceiver;
+    private ScannerNotificationReceiver mScannerFinishedReceiver;
+    private boolean mScannerStarted;
+    private boolean mScannerFinished;
+
+    public void testMediaScannerNotification() throws InterruptedException {
+        mScannerStarted = false;
+        mScannerFinished = false;
+
+        IntentFilter scannerStartedIntentFilter = new IntentFilter(
+                Intent.ACTION_MEDIA_SCANNER_STARTED);
+        scannerStartedIntentFilter.addDataScheme("file");
+        IntentFilter scannerFinshedIntentFilter = new IntentFilter(
+                Intent.ACTION_MEDIA_SCANNER_FINISHED);
+        scannerFinshedIntentFilter.addDataScheme("file");
+
+        mScannerStartedReceiver = new ScannerNotificationReceiver(
+                Intent.ACTION_MEDIA_SCANNER_STARTED);
+        mScannerFinishedReceiver = new ScannerNotificationReceiver(
+                Intent.ACTION_MEDIA_SCANNER_FINISHED);
+
+        getContext().registerReceiver(mScannerStartedReceiver, scannerStartedIntentFilter);
+        getContext().registerReceiver(mScannerFinishedReceiver, scannerFinshedIntentFilter);
+
+        getContext().sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"
+            + Environment.getExternalStorageDirectory())));
+        mScannerStartedReceiver.waitForCalls(1, MEDIA_SCANNER_TIME_OUT);
+        mScannerFinishedReceiver.waitForCalls(1, MEDIA_SCANNER_TIME_OUT);
+
+        assertTrue(mScannerStarted);
+        assertTrue(mScannerFinished);
+    }
+
+    class ScannerNotificationReceiver extends BroadcastReceiver {
+        private int mCalls;
+        private int mExpectedCalls;
+        private String mAction;
+        private Object mLock;
+
+        ScannerNotificationReceiver(String action) {
+            mAction = action;
+            reset();
+            mLock = new Object();
+        }
+
+        void reset() {
+            mExpectedCalls = Integer.MAX_VALUE;
+            mCalls = 0;
+        }
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (intent.getAction().equals(mAction)) {
+                if (mAction.equals(Intent.ACTION_MEDIA_SCANNER_STARTED)) {
+                    mScannerStarted = true;
+                } else if (mAction.equals(Intent.ACTION_MEDIA_SCANNER_FINISHED)) {
+                    mScannerFinished = true;
+                }
+                synchronized (mLock) {
+                    mCalls += 1;
+                    if (mCalls >= mExpectedCalls) {
+                        mLock.notify();
+                    }
+                }
+            }
+        }
+
+        public void waitForCalls(int expectedCalls, long timeout) throws InterruptedException {
+            synchronized(mLock) {
+                mExpectedCalls = expectedCalls;
+                if (mCalls < mExpectedCalls) {
+                    mLock.wait(timeout);
+                }
+            }
+        }
+    }
+}
diff --git a/tests/tests/security/src/android/security/cts/VoldExploitTest.java b/tests/tests/security/src/android/security/cts/VoldExploitTest.java
index 38eece7..12b4392 100644
--- a/tests/tests/security/src/android/security/cts/VoldExploitTest.java
+++ b/tests/tests/security/src/android/security/cts/VoldExploitTest.java
@@ -115,6 +115,9 @@
     private static Set<String> getSysFsPath(String file) throws IOException {
         Set<String> retval = new HashSet<String>();
         File netlink = new File(file);
+        if (!netlink.canRead()) {
+            return retval;
+        }
         Scanner scanner = null;
         try {
             scanner = new Scanner(netlink);
diff --git a/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java b/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java
index bd2cbbf..83a5df5 100644
--- a/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java
@@ -79,21 +79,33 @@
                     "44075",    // KDDI
                     "44076",    // KDDI
                     "311870",   // Boost Mobile
-                    "311220"    // USCC
+                    "311220",   // USCC
+                    "302720",   // Rogers
+                    "30272",    // Rogers
+                    "302370",   // Fido
+                    "30237"     // Fido
             );
 
     // List of network operators that doesn't support Data(binary) SMS message
     private static final List<String> UNSUPPORT_DATA_SMS_MESSAGES =
             Arrays.asList(
                     "44010",    // NTT DOCOMO
-                    "44020"     // SBM
+                    "44020",    // SBM
+                    "302720",   // Rogers
+                    "30272",    // Rogers
+                    "302370",   // Fido
+                    "30237"     // Fido
             );
 
     // List of network operators that doesn't support Maltipart SMS message
     private static final List<String> UNSUPPORT_MULTIPART_SMS_MESSAGES =
             Arrays.asList(
                     "44010",    // NTT DOCOMO
-                    "44020"     // SBM
+                    "44020",    // SBM
+                    "302720",   // Rogers
+                    "30272",    // Rogers
+                    "302370",   // Fido
+                    "30237"     // Fido
             );
 
     private TelephonyManager mTelephonyManager;