Merge remote-tracking branch 'aosp/nougat-mr1-cts-dev' into master

Test: built
Change-Id: I0e9438d5fdb01c94077aa22cdf402dee8bf5ec97
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
old mode 100644
new mode 100755
index b522c61..d5c166e
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -414,8 +414,8 @@
     <string name="ble_low">Low</string>
     <string name="ble_medium">Medium</string>
     <string name="ble_high">High</string>
-    <string name="ble_scanner_power_level_instruction">Count: Ultra low &lt; low &lt; medium &lt; high\nRssi: Ultra low &lt; low &lt; medium &lt; high\nDistance to see count freezing: Ultra low &lt; low &lt; medium &lt; high\nA common error is ultra low, low and medium behave similarly, with similar rssi, freeze at similar distance.\n\n All power level receive a different mac address. After 15 mins, a green text "Get a new Mac address" will show up.</string>
-    <string name="ble_scanner_scan_filter_name">Bluetooth LE Hardware Scan Filter</string>
+    <string name="ble_scanner_power_level_instruction">Count: Ultra low &lt; low &lt; medium &lt; high\nRssi: Ultra low &lt; low &lt; medium &lt; high\nDistance to see count freezing: Ultra low &lt; low &lt; medium &lt; high\nA common error is ultra low, low and medium behave similarly, with similar rssi, freeze at similar distance.\n\n All power level receive a mac address.</string>
+    <string name="ble_scanner_scan_filter_name">BLE Hardware Scan Filter</string>
     <string name="ble_scanner_scan_filter_info">Lock the screen of scanner, and connect to monsoon. It will not wake up when advertiser is advertising unscannable, and scanner is scanning with filter.</string>
     <string name="ble_scanner_scan_filter_instruction">Scan filter is to scan data with service UUID = 0x6666 only. If you scan without scan filter, data with service UUID = 0x5555 and 0x6666 will show up on screen.\nFor monsoon test:\n\tClick scan with filter, lock the screen, connect to monsoon. It will not wake up when advertiser is advertising unscannable data packets, but will show a peak in power usage when advertiser is advertising scannable data.\nFor logcat test:\n\tClick scan with filter, logcat the scanner. No data will be received by GattService when advertiser is advertising unscannable data.</string>
     <string name="ble_scan_with_filter">Scan with filter</string>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleScannerPowerLevelActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleScannerPowerLevelActivity.java
old mode 100644
new mode 100755
index b2c6c60..ce68dbd
--- a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleScannerPowerLevelActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleScannerPowerLevelActivity.java
@@ -31,7 +31,6 @@
 import android.content.IntentFilter;
 import android.graphics.Color;
 import android.os.Bundle;
-import android.os.CountDownTimer;
 import android.util.Log;
 import android.widget.TextView;
 import android.widget.Toast;
@@ -47,10 +46,6 @@
     private Map<Integer, Integer> mCount;
     private int[] mPowerLevel;
 
-    private TextView mTimerText;
-    private CountDownTimer mTimer;
-    private static final long REFRESH_MAC_TIME = 930000; // 15.5 min
-
     private static final int[] POWER_DBM = {-21, -15, -7, 1, 9};
 
     @Override
@@ -60,23 +55,6 @@
         setPassFailButtonClickListeners();
         setInfoResources(R.string.ble_power_level_name,
                          R.string.ble_power_level_info, -1);
-        getPassButton().setEnabled(false);
-
-        mTimerText = (TextView)findViewById(R.id.ble_timer);
-        mTimer = new CountDownTimer(REFRESH_MAC_TIME, 1000) {
-            @Override
-            public void onTick(long millis) {
-                int min = (int)millis / 60000;
-                int sec = ((int)millis / 1000) % 60;
-                mTimerText.setText(min + ":" + sec);
-            }
-
-            @Override
-            public void onFinish() {
-                mTimerText.setTextColor(Color.RED);
-                mTimerText.setText("Time is up!");
-            }
-        };
 
         mRssiText = new HashMap<Integer, TextView>();
         mCountText = new HashMap<Integer, TextView>();
@@ -169,7 +147,6 @@
                         for (int i : mPowerLevel) {
                             mCount.put(i, 0);
                         }
-                        mTimer.start();
                     }
                     Integer t = mCount.get(powerLevelBit) + 1;
                     mCount.put(powerLevelBit, t);
@@ -189,10 +166,6 @@
                 case BleScannerService.BLE_PRIVACY_NEW_MAC_RECEIVE:
                      Toast.makeText(context, "New MAC address detected", Toast.LENGTH_SHORT)
                             .show();
-                     mTimerText.setTextColor(Color.GREEN);
-                     mTimerText.append("   Get new MAC address.");
-                     mTimer.cancel();
-                     getPassButton().setEnabled(true);
                      break;
             }
         }
diff --git a/hostsidetests/sustainedperf/src/android/SustainedPerformance/cts/SustainedPerformanceHostTest.java b/hostsidetests/sustainedperf/src/android/SustainedPerformance/cts/SustainedPerformanceHostTest.java
index fffeeb8..702b15b 100644
--- a/hostsidetests/sustainedperf/src/android/SustainedPerformance/cts/SustainedPerformanceHostTest.java
+++ b/hostsidetests/sustainedperf/src/android/SustainedPerformance/cts/SustainedPerformanceHostTest.java
@@ -219,12 +219,21 @@
         device.executeShellCommand("settings put global airplane_mode_on 0");
         device.executeShellCommand("am broadcast -a android.intent.action.AIRPLANE_MODE --ez state false");
 
+        double resDhry = dhrystoneResultsWithMode.get(2);
+        double resApp = appResultsWithMode.get(2);
+
+        /* Report if performance is below 5% margin for both dhrystone and shader */
+        if ((resDhry > 5) || (resApp > 5)) {
+            Log.w("SustainedPerformanceHostTests",
+                  "Sustainable mode results, Dhrystone: " + resDhry + " App: " + resApp);
+        }
+
         /*
-         * Checks if the performance in the mode is consistent with
+         * Error if the performance in the mode is not consistent with
          * 5% error margin for shader and 10% error margin for dhrystone.
          */
         assertFalse("Results in the mode are not sustainable",
-                (dhrystoneResultsWithMode.get(2) > 10) ||
-                (appResultsWithMode.get(2)) > 5);
+                    (resDhry > 15) ||
+                    (resApp > 5));
     }
 }
diff --git a/tests/tests/os/src/android/os/cts/SecurityPatchTest.java b/tests/tests/os/src/android/os/cts/SecurityPatchTest.java
index 68609e1..4531aa6 100644
--- a/tests/tests/os/src/android/os/cts/SecurityPatchTest.java
+++ b/tests/tests/os/src/android/os/cts/SecurityPatchTest.java
@@ -32,7 +32,7 @@
     private static final String SECURITY_PATCH_DATE_ERROR =
             "ro.build.version.security_patch should be \"%d-%02d\" or later. Found \"%s\"";
     private static final int SECURITY_PATCH_YEAR = 2016;
-    private static final int SECURITY_PATCH_MONTH = 06;
+    private static final int SECURITY_PATCH_MONTH = 12;
 
     private boolean mSkipTests = false;
 
diff --git a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
index df82225..845cf30 100644
--- a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
@@ -785,6 +785,92 @@
         assertTrue("/data is not mounted NODEV", (vfs.f_flag & OsConstants.ST_NODEV) != 0);
     }
 
+    public void testAllBlockDevicesAreSecure() throws Exception {
+        Set<File> insecure = getAllInsecureDevicesInDirAndSubdir(new File("/dev"), FileUtils.S_IFBLK);
+        assertTrue("Found insecure block devices: " + insecure.toString(),
+                insecure.isEmpty());
+    }
+
+    private static final Set<File> CHAR_DEV_EXCEPTIONS = new HashSet<File>(
+            Arrays.asList(
+                // All exceptions should be alphabetical and associated with a bug number.
+                new File("/dev/adsprpc-smd"), // b/11710243
+                new File("/dev/alarm"),      // b/9035217
+                new File("/dev/ashmem"),
+                new File("/dev/binder"),
+                new File("/dev/card0"),       // b/13159510
+                new File("/dev/renderD128"),
+                new File("/dev/renderD129"),  // b/23798677
+                new File("/dev/dri/card0"),   // b/13159510
+                new File("/dev/dri/renderD128"),
+                new File("/dev/dri/renderD129"), // b/23798677
+                new File("/dev/felica"),     // b/11142586
+                new File("/dev/felica_ant"), // b/11142586
+                new File("/dev/felica_cen"), // b/11142586
+                new File("/dev/felica_pon"), // b/11142586
+                new File("/dev/felica_rfs"), // b/11142586
+                new File("/dev/felica_rws"), // b/11142586
+                new File("/dev/felica_uicc"), // b/11142586
+                new File("/dev/full"),
+                new File("/dev/galcore"),
+                new File("/dev/genlock"),    // b/9035217
+                new File("/dev/graphics/galcore"),
+                new File("/dev/ion"),
+                new File("/dev/kgsl-2d0"),   // b/11271533
+                new File("/dev/kgsl-2d1"),   // b/11271533
+                new File("/dev/kgsl-3d0"),   // b/9035217
+                new File("/dev/log/events"), // b/9035217
+                new File("/dev/log/main"),   // b/9035217
+                new File("/dev/log/radio"),  // b/9035217
+                new File("/dev/log/system"), // b/9035217
+                new File("/dev/mali0"),       // b/9106968
+                new File("/dev/mali"),        // b/11142586
+                new File("/dev/mm_interlock"), // b/12955573
+                new File("/dev/mm_isp"),      // b/12955573
+                new File("/dev/mm_v3d"),      // b/12955573
+                new File("/dev/msm_rotator"), // b/9035217
+                new File("/dev/null"),
+                new File("/dev/nvhost-as-gpu"),
+                new File("/dev/nvhost-ctrl"), // b/9088251
+                new File("/dev/nvhost-ctrl-gpu"),
+                new File("/dev/nvhost-dbg-gpu"),
+                new File("/dev/nvhost-gpu"),
+                new File("/dev/nvhost-gr2d"), // b/9088251
+                new File("/dev/nvhost-gr3d"), // b/9088251
+                new File("/dev/nvhost-tsec"),
+                new File("/dev/nvhost-prof-gpu"),
+                new File("/dev/nvhost-vic"),
+                new File("/dev/nvmap"),       // b/9088251
+                new File("/dev/pmsg0"),       // b/31857082
+                new File("/dev/ptmx"),        // b/9088251
+                new File("/dev/pvrsrvkm"),    // b/9108170
+                new File("/dev/pvr_sync"),
+                new File("/dev/quadd"),
+                new File("/dev/random"),
+                new File("/dev/snfc_cen"),    // b/11142586
+                new File("/dev/snfc_hsel"),   // b/11142586
+                new File("/dev/snfc_intu_poll"), // b/11142586
+                new File("/dev/snfc_rfs"),    // b/11142586
+                new File("/dev/tegra-throughput"),
+                new File("/dev/tiler"),       // b/9108170
+                new File("/dev/tty"),
+                new File("/dev/urandom"),
+                new File("/dev/ump"),         // b/11142586
+                new File("/dev/xt_qtaguid"),  // b/9088251
+                new File("/dev/zero"),
+                new File("/dev/fimg2d"),      // b/10428016
+                new File("/dev/mobicore-user") // b/10428016
+            ));
+
+    public void testAllCharacterDevicesAreSecure() throws Exception {
+        Set<File> insecure = getAllInsecureDevicesInDirAndSubdir(new File("/dev"), FileUtils.S_IFCHR);
+        Set<File> insecurePts = getAllInsecureDevicesInDirAndSubdir(new File("/dev/pts"), FileUtils.S_IFCHR);
+        insecure.removeAll(CHAR_DEV_EXCEPTIONS);
+        insecure.removeAll(insecurePts);
+        assertTrue("Found insecure character devices: " + insecure.toString(),
+                insecure.isEmpty());
+    }
+
     public void testDevRandomWorldReadableAndWritable() throws Exception {
         File f = new File("/dev/random");
 
@@ -898,6 +984,67 @@
                 .fileHasOnly("/system/bin/run-as"));
     }
 
+    private static Set<File>
+    getAllInsecureDevicesInDirAndSubdir(File dir, int type) throws Exception {
+        assertTrue(dir.isDirectory());
+        Set<File> retval = new HashSet<File>();
+
+        if (isSymbolicLink(dir)) {
+            // don't examine symbolic links.
+            return retval;
+        }
+
+        File[] subDirectories = dir.listFiles(new FileFilter() {
+            @Override public boolean accept(File pathname) {
+                return pathname.isDirectory();
+            }
+        });
+
+
+        /* recurse into subdirectories */
+        if (subDirectories != null) {
+            for (File f : subDirectories) {
+                retval.addAll(getAllInsecureDevicesInDirAndSubdir(f, type));
+            }
+        }
+
+        File[] filesInThisDirectory = dir.listFiles();
+        if (filesInThisDirectory == null) {
+            return retval;
+        }
+
+        for (File f: filesInThisDirectory) {
+            FileUtils.FileStatus status = new FileUtils.FileStatus();
+            FileUtils.getFileStatus(f.getAbsolutePath(), status, false);
+            if (status.isOfType(type)) {
+                if (f.canRead() || f.canWrite() || f.canExecute()) {
+                    retval.add(f);
+                }
+                if (status.uid == 2000) {
+                    // The shell user should not own any devices
+                    retval.add(f);
+                }
+
+                // Don't allow devices owned by GIDs
+                // accessible to non-privileged applications.
+                if ((status.gid == 1007)           // AID_LOG
+                          || (status.gid == 1015)  // AID_SDCARD_RW
+                          || (status.gid == 1023)  // AID_MEDIA_RW
+                          || (status.gid == 1028)  // AID_SDCARD_R
+                          || (status.gid == 2000)) // AID_SHELL
+                {
+                    if (status.hasModeFlag(FileUtils.S_IRGRP)
+                            || status.hasModeFlag(FileUtils.S_IWGRP)
+                            || status.hasModeFlag(FileUtils.S_IXGRP))
+                    {
+                        retval.add(f);
+                    }
+                }
+            }
+        }
+        return retval;
+    }
+
     private Set<File> getWritableDirectoriesAndSubdirectoriesOf(File dir) throws Exception {
         Set<File> retval = new HashSet<File>();
         if (!dir.isDirectory()) {
diff --git a/tools/cts-tradefed/Android.mk b/tools/cts-tradefed/Android.mk
index bb4b934..7783e58c 100644
--- a/tools/cts-tradefed/Android.mk
+++ b/tools/cts-tradefed/Android.mk
@@ -25,7 +25,7 @@
 LOCAL_SUITE_TARGET_ARCH := $(TARGET_ARCH)
 LOCAL_SUITE_NAME := CTS
 LOCAL_SUITE_FULLNAME := "Compatibility Test Suite"
-LOCAL_SUITE_VERSION := 7.1_r1
+LOCAL_SUITE_VERSION := 7.1_r2
 
 LOCAL_MODULE := cts-tradefed