Merge "Add support for secured element in simcard util"
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index 94deaa7..a74063e 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -1,3 +1,10 @@
+[Builtin Hooks]
+google_java_format = true
+
+[Tool Paths]
+google-java-format = ${REPO_ROOT}/prebuilts/tools/common/google-java-format/google-java-format
+google-java-format-diff = ${REPO_ROOT}/prebuilts/tools/common/google-java-format/google-java-format-diff.py
+
 [Hook Scripts]
 checkstyle_hook = ${REPO_ROOT}/prebuilts/checkstyle/checkstyle.py --sha ${PREUPLOAD_COMMIT}
                   -fw libraries/annotations
diff --git a/build/tasks/tests/native_test_list.mk b/build/tasks/tests/native_test_list.mk
index c3198c8..5a31911 100644
--- a/build/tasks/tests/native_test_list.mk
+++ b/build/tasks/tests/native_test_list.mk
@@ -31,6 +31,7 @@
     bugreportz_test \
     bsdiff_unittest \
     camera_client_test \
+    clatd_test \
     crashcollector \
     debuggerd_test \
     dumpstate_test \
diff --git a/libraries/collectors-helper/perfetto/src/com/android/helpers/PerfettoHelper.java b/libraries/collectors-helper/perfetto/src/com/android/helpers/PerfettoHelper.java
index 99b1b8c..c1d7aee 100644
--- a/libraries/collectors-helper/perfetto/src/com/android/helpers/PerfettoHelper.java
+++ b/libraries/collectors-helper/perfetto/src/com/android/helpers/PerfettoHelper.java
@@ -41,13 +41,17 @@
     private static final String PERFETTO_TMP_OUTPUT_FILE =
             "/data/misc/perfetto-traces/trace_output.pb";
     // Command to stop (i.e kill) the perfetto tracing.
-    private static final String PERFETTO_STOP_CMD = "pkill perfetto";
+    private static final String PERFETTO_STOP_CMD = "pkill -INT perfetto";
     // Command to check the perfetto process id.
     private static final String PERFETTO_PROC_ID_CMD = "pidof perfetto";
     // Remove the trace output file /data/misc/perfetto-traces/trace_output.pb
     private static final String REMOVE_CMD = "rm %s";
     // Command to move the perfetto output trace file to given folder.
     private static final String MOVE_CMD = "mv %s %s";
+    // Max wait count for checking if perfetto is stopped successfully
+    private static final int PERFETTO_KILL_WAIT_COUNT = 12;
+    // Check if perfetto is stopped every 5 secs.
+    private static final long PERFETTO_KILL_WAIT_TIME = 5000;
 
     private UiDevice mUIDevice;
 
@@ -99,8 +103,8 @@
     }
 
     /**
-     * Stop the perfetto trace collection under /data/misc/perfetto-traces/trace_output.pb
-     * after waiting for given time in msecs and copy the output to the destination file.
+     * Stop the perfetto trace collection under /data/misc/perfetto-traces/trace_output.pb after
+     * waiting for given time in msecs and copy the output to the destination file.
      *
      * @param waitTimeInMsecs time to wait in msecs before stopping the trace collection.
      * @param destinationFile file to copy the perfetto output trace.
@@ -138,7 +142,15 @@
     private boolean stopPerfetto() throws IOException {
         String stopOutput = mUIDevice.executeShellCommand(PERFETTO_STOP_CMD);
         Log.i(LOG_TAG, String.format("Perfetto stop command output - %s", stopOutput));
-        if (isPerfettoRunning()) {
+        int waitCount = 0;
+        while (isPerfettoRunning()) {
+            // 60 secs timeout for perfetto shutdown.
+            if (waitCount < PERFETTO_KILL_WAIT_COUNT) {
+                // Check every 5 secs if perfetto stopped successfully.
+                SystemClock.sleep(PERFETTO_KILL_WAIT_TIME);
+                waitCount++;
+                continue;
+            }
             return false;
         }
         Log.e(LOG_TAG, "Perfetto stopped successfully.");
diff --git a/libraries/collectors-helper/statsd/src/com/android/helpers/AppStartupHelper.java b/libraries/collectors-helper/statsd/src/com/android/helpers/AppStartupHelper.java
index 29667c4..f212549 100644
--- a/libraries/collectors-helper/statsd/src/com/android/helpers/AppStartupHelper.java
+++ b/libraries/collectors-helper/statsd/src/com/android/helpers/AppStartupHelper.java
@@ -27,6 +27,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
 
 /**
  * AppStartupHelper consist of helper methods to set the app
@@ -41,6 +42,8 @@
     private static final String COLD_STARTUP = "cold_startup";
     private static final String WARM_STARTUP = "warm_startup";
     private static final String HOT_STARTUP = "hot_startup";
+    private static final String COUNT = "count";
+    private static final String TOTAL_COUNT = "total_count";
 
     private static final String STARTUP_FULLY_DRAWN_UNKNOWN = "startup_fully_drawn_unknown";
     private static final String STARTUP_FULLY_DRAWN_WITH_BUNDLE = "startup_fully_drawn_with_bundle";
@@ -68,6 +71,7 @@
     public Map<String, StringBuilder> getMetrics() {
         List<EventMetricData> eventMetricData = mStatsdHelper.getEventMetrics();
         Map<String, StringBuilder> appStartResultMap = new HashMap<>();
+        Map<String, Integer> appStartCountMap = new HashMap<>();
         for (EventMetricData dataItem : eventMetricData) {
             Atom atom = dataItem.getAtom();
             if (atom.hasAppStartOccurred()) {
@@ -80,21 +84,33 @@
                         pkgName, transitionType, windowsDrawnMillis));
 
                 String metricKey = "";
+                // To track number of startups per type per package.
+                String metricCountKey = "";
+                // To track total number of startups per type.
+                String totalCountKey = "";
                 switch (appStartAtom.getType()) {
                     case COLD:
                         metricKey = MetricUtility.constructKey(COLD_STARTUP, pkgName);
+                        metricCountKey = MetricUtility.constructKey(COLD_STARTUP, COUNT, pkgName);
+                        totalCountKey = MetricUtility.constructKey(COLD_STARTUP, TOTAL_COUNT);
                         break;
                     case WARM:
                         metricKey = MetricUtility.constructKey(WARM_STARTUP, pkgName);
+                        metricCountKey = MetricUtility.constructKey(WARM_STARTUP, COUNT, pkgName);
+                        totalCountKey = MetricUtility.constructKey(WARM_STARTUP, TOTAL_COUNT);
                         break;
                     case HOT:
                         metricKey = MetricUtility.constructKey(HOT_STARTUP, pkgName);
+                        metricCountKey = MetricUtility.constructKey(HOT_STARTUP, COUNT, pkgName);
+                        totalCountKey = MetricUtility.constructKey(HOT_STARTUP, TOTAL_COUNT);
                         break;
                     case UNKNOWN:
                         break;
                 }
                 if (!metricKey.isEmpty()) {
                     MetricUtility.addMetric(metricKey, windowsDrawnMillis, appStartResultMap);
+                    MetricUtility.addMetric(metricCountKey, appStartCountMap);
+                    MetricUtility.addMetric(totalCountKey, appStartCountMap);
                 }
             } else if (atom.hasAppStartFullyDrawn()) {
                 AppStartFullyDrawn appFullyDrawnAtom = atom.getAppStartFullyDrawn();
@@ -124,6 +140,16 @@
                 }
             }
         }
+        // Cast to StringBuilder as the raw app startup metric could be comma separated values
+        // if there are multiple app launches.
+        Map<String, StringBuilder> finalCountMap = appStartCountMap
+                .entrySet()
+                .stream()
+                .collect(
+                        Collectors.toMap(Map.Entry::getKey,
+                                e -> new StringBuilder(Integer.toString(e.getValue()))));
+        // Add the count map in the app start result map.
+        appStartResultMap.putAll(finalCountMap);
         return appStartResultMap;
     }
 
diff --git a/libraries/collectors-helper/statsd/test/src/com/android/helpers/tests/AppStartupHelperTest.java b/libraries/collectors-helper/statsd/test/src/com/android/helpers/tests/AppStartupHelperTest.java
index 2739f8d..36aca80 100644
--- a/libraries/collectors-helper/statsd/test/src/com/android/helpers/tests/AppStartupHelperTest.java
+++ b/libraries/collectors-helper/statsd/test/src/com/android/helpers/tests/AppStartupHelperTest.java
@@ -50,6 +50,8 @@
     private static final String SETTINGS_PKG_NAME = "com.android.settings";
     // Key prefixes to store the cold, warm or hot launch time of the calendar app, respectively.
     private static final String COLD_LAUNCH_KEY_TEMPLATE = "cold_startup_%s";
+    private static final String COLD_LAUNCH_COUNT_PKG_KEY_TEMPLATE = "cold_startup_count_%s";
+    private static final String COLD_LAUNCH_TOTAL_COUNT_KEY_TEMPLATE = "cold_startup_total_count";
     private static final String WARM_LAUNCH_KEY_TEMPLATE = "warm_startup_%s";
     private static final String HOT_LAUNCH_KEY_TEMPLATE = "hot_startup_%s";
     // Keyword for keys to store the app startup fully drawn metric.
@@ -92,7 +94,7 @@
     }
 
     /**
-     * Test cold launch metric.
+     * Test single cold launch metric.
      */
     @Test
     public void testSingleColdLaunchMetric() throws Exception {
@@ -101,8 +103,13 @@
         Map<String, StringBuilder> appLaunchMetrics = mAppStartupHelper.getMetrics();
         // A metric key for the app cold launching should exist, and should only hold one value.
         String coldLaunchMetricKey = String.format(COLD_LAUNCH_KEY_TEMPLATE, CALENDAR_PKG_NAME);
+        String coldLaunchCountPkgKey = String.format(COLD_LAUNCH_COUNT_PKG_KEY_TEMPLATE,
+                CALENDAR_PKG_NAME);
         assertTrue(appLaunchMetrics.keySet().contains(coldLaunchMetricKey));
         assertEquals(1, appLaunchMetrics.get(coldLaunchMetricKey).toString().split(",").length);
+        assertEquals(1, Integer.parseInt(appLaunchMetrics.get(coldLaunchCountPkgKey).toString()));
+        assertEquals(1, Integer.parseInt(appLaunchMetrics.get(COLD_LAUNCH_TOTAL_COUNT_KEY_TEMPLATE)
+                .toString()));
         assertTrue(mAppStartupHelper.stopCollecting());
         mHelper.get().exit();
     }
@@ -121,13 +128,64 @@
         Map<String, StringBuilder> appLaunchMetrics = mAppStartupHelper.getMetrics();
         // A metric key for the app cold launching should exist, and should hold two values.
         String coldLaunchMetricKey = String.format(COLD_LAUNCH_KEY_TEMPLATE, CALENDAR_PKG_NAME);
+        String coldLaunchCountPkgKey = String.format(COLD_LAUNCH_COUNT_PKG_KEY_TEMPLATE,
+                CALENDAR_PKG_NAME);
         assertTrue(appLaunchMetrics.keySet().contains(coldLaunchMetricKey));
         assertEquals(2, appLaunchMetrics.get(coldLaunchMetricKey).toString().split(",").length);
+        assertEquals(2, Integer.parseInt(appLaunchMetrics.get(coldLaunchCountPkgKey).toString()));
+        assertEquals(2, Integer.parseInt(appLaunchMetrics.get(COLD_LAUNCH_TOTAL_COUNT_KEY_TEMPLATE)
+                .toString()));
         assertTrue(mAppStartupHelper.stopCollecting());
         mHelper.get().exit();
     }
 
     /**
+     * Test cold launch metric of two different apps.
+     */
+    @Test
+    public void testDifferentAppColdLaunchMetric() throws Exception {
+
+        // Open the calendar app.
+        assertTrue(mAppStartupHelper.startCollecting());
+        mHelper.get().open();
+        SystemClock.sleep(HelperTestUtility.ACTION_DELAY);
+        mHelper.get().exit();
+        HelperTestUtility.clearApp(String.format(KILL_TEST_APP_CMD_TEMPLATE, CALENDAR_PKG_NAME));
+
+        // Open settings app
+        HelperTestUtility.launchPackageViaAdb(SETTINGS_PKG_NAME);
+        SystemClock.sleep(HelperTestUtility.ACTION_DELAY);
+        HelperTestUtility.sendKeyCode(KEYCODE_HOME);
+        SystemClock.sleep(HelperTestUtility.ACTION_DELAY);
+        HelperTestUtility.clearApp(String.format(KILL_TEST_APP_CMD_TEMPLATE, SETTINGS_PKG_NAME));
+        SystemClock.sleep(HelperTestUtility.ACTION_DELAY);
+
+        Map<String, StringBuilder> appLaunchMetrics = mAppStartupHelper.getMetrics();
+        String coldLaunchCalendarMetricKey = String.format(COLD_LAUNCH_KEY_TEMPLATE,
+                CALENDAR_PKG_NAME);
+        String coldLaunchSettingsMetricKey = String.format(COLD_LAUNCH_KEY_TEMPLATE,
+                SETTINGS_PKG_NAME);
+        String coldLaunchCalendarCountPkgKey = String.format(COLD_LAUNCH_COUNT_PKG_KEY_TEMPLATE,
+                CALENDAR_PKG_NAME);
+        String coldLaunchSettingsCountPkgKey = String.format(COLD_LAUNCH_COUNT_PKG_KEY_TEMPLATE,
+                CALENDAR_PKG_NAME);
+        assertTrue(appLaunchMetrics.keySet().contains(coldLaunchCalendarMetricKey));
+        assertTrue(appLaunchMetrics.keySet().contains(coldLaunchSettingsMetricKey));
+        assertEquals(1,
+                appLaunchMetrics.get(coldLaunchCalendarMetricKey).toString().split(",").length);
+        assertEquals(1,
+                appLaunchMetrics.get(coldLaunchSettingsCountPkgKey).toString().split(",").length);
+        assertEquals(1,
+                Integer.parseInt(appLaunchMetrics.get(coldLaunchCalendarCountPkgKey).toString()));
+        assertEquals(1,
+                Integer.parseInt(appLaunchMetrics.get(coldLaunchSettingsCountPkgKey).toString()));
+        assertEquals(2, Integer.parseInt(appLaunchMetrics.get(COLD_LAUNCH_TOTAL_COUNT_KEY_TEMPLATE)
+                .toString()));
+        assertTrue(mAppStartupHelper.stopCollecting());
+
+    }
+
+    /**
      * Test warm launch metric.
      */
     @Test
diff --git a/libraries/composer/host/.classpath b/libraries/composer/host/.classpath
index 28e115c..76b3ead 100644
--- a/libraries/composer/host/.classpath
+++ b/libraries/composer/host/.classpath
@@ -3,6 +3,5 @@
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
 	<classpathentry kind="src" path="src"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
-	<classpathentry kind="var" path="TRADEFED_ROOT/out/soong/.intermediates/platform_testing/libraries/composer/host/test-composers/linux_glibc_common/combined/test-composers.jar"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git a/libraries/device-collectors/src/main/java/android/device/preparers/GarbageCollectionPreparer.java b/libraries/device-collectors/src/main/java/android/device/preparers/GarbageCollectionPreparer.java
index eadbb9d..797b2f6 100644
--- a/libraries/device-collectors/src/main/java/android/device/preparers/GarbageCollectionPreparer.java
+++ b/libraries/device-collectors/src/main/java/android/device/preparers/GarbageCollectionPreparer.java
@@ -52,11 +52,16 @@
     @VisibleForTesting
     static final String GC_WAIT_TIME_KEY = "garbagecollection-wait-time";
 
-    private GarbageCollectionHelper mGcHelper = new GarbageCollectionHelper();
+    private final GarbageCollectionHelper mGcHelper;
     // Whether the preparer successfully set up and initialized.
     private boolean mSetUp;
     private Long mWaitTime;
 
+    public GarbageCollectionPreparer() {
+        super();
+        mGcHelper = new GarbageCollectionHelper();
+    }
+
     /**
      * Constructor to simulate receiving the instrumentation arguments. Should not be used except
      * for testing.
diff --git a/tests/example/devcodelab/Android.bp b/tests/example/devcodelab/Android.bp
new file mode 100644
index 0000000..1de2986
--- /dev/null
+++ b/tests/example/devcodelab/Android.bp
@@ -0,0 +1,23 @@
+//Copyright (C) 2019 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.
+
+android_test {
+    name: "DevCodelabTest",
+
+    srcs: ["src/**/*.java"],
+    sdk_version: "current",
+
+    static_libs: ["android-support-test"],
+    certificate: "platform",
+}
diff --git a/tests/example/devcodelab/AndroidManifest.xml b/tests/example/devcodelab/AndroidManifest.xml
new file mode 100644
index 0000000..a55e434
--- /dev/null
+++ b/tests/example/devcodelab/AndroidManifest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.test.example.devcodelab" >
+
+    <uses-sdk android:minSdkVersion="26" android:targetSdkVersion="26" />
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="android.test.example.devcodelab"
+                     android:label="Developer Codelab Test"/>
+
+</manifest>
diff --git a/tests/example/devcodelab/README b/tests/example/devcodelab/README
new file mode 100644
index 0000000..b695d1b
--- /dev/null
+++ b/tests/example/devcodelab/README
@@ -0,0 +1,4 @@
+Sample test for Developer Codelabs.
+
+This test is a purposely broken instrumentation apk test meant for new
+developers to fix and run locally as they learn how to Android.
diff --git a/tests/example/devcodelab/src/android/test/example/devcodelab/DevCodelabTest.java b/tests/example/devcodelab/src/android/test/example/devcodelab/DevCodelabTest.java
new file mode 100644
index 0000000..5df2725
--- /dev/null
+++ b/tests/example/devcodelab/src/android/test/example/devcodelab/DevCodelabTest.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2019 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.test.example.devcodelab;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class DevCodelabTest {
+
+    @Test
+    public void testHelloWorld() {
+        Assert.assertTrue(false);
+    }
+
+}
diff --git a/tests/jank/UbSystemUiJankTests/src/android/platform/systemui/tests/jank/SettingsJankTests.java b/tests/jank/UbSystemUiJankTests/src/android/platform/systemui/tests/jank/SettingsJankTests.java
index e6c7b8e..4271e04 100644
--- a/tests/jank/UbSystemUiJankTests/src/android/platform/systemui/tests/jank/SettingsJankTests.java
+++ b/tests/jank/UbSystemUiJankTests/src/android/platform/systemui/tests/jank/SettingsJankTests.java
@@ -42,7 +42,7 @@
     private static final int TIMEOUT = 5000;
     private static final String SETTINGS_PACKAGE = "com.android.settings";
     private static final BySelector SETTINGS_DASHBOARD = By.res(SETTINGS_PACKAGE,
-            "dashboard_container");
+            "main_content_scrollable_container");
     // short transitions should be repeated within the test function, otherwise frame stats
     // captured are not really meaningful in a statistical sense
     private static final int INNER_LOOP = 2;