Snap for 6128581 from b735f448e61c99f4c06101902ff76eee4e5496f1 to rvc-release

Change-Id: I750af62600d5b13f6f0e1bf2654ea545028a459c
diff --git a/scripts/run-user-switch-perf.sh b/scripts/run-user-switch-perf.sh
new file mode 100755
index 0000000..bebb06f
--- /dev/null
+++ b/scripts/run-user-switch-perf.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+# usage (From root directory): ./scripts/run-user-switch-perf.sh <target user>
+
+# Runs user switch, collects a trace and prints out a summary of user switch
+# metrics - time taken by user start, user switch and user unlock and top 5
+# most expensive service in each category
+
+TargetUser=$1
+
+adb shell atrace -o /sdcard/atrace-ss.txt -t 10 ss &
+sleep 2
+adb shell am switch-user $TargetUser
+wait
+sleep 2
+adb pull /sdcard/atrace-ss.txt /tmp
+sleep 1
+./gradlew :trebuchet:user-switch-analyzer:run --args="/tmp/atrace-ss.txt -u $TargetUser"
diff --git a/settings.gradle b/settings.gradle
index 62d53d5..2878b87 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -28,5 +28,6 @@
 include 'trebuchet:startup-common'
 include 'trebuchet:startup-summarizer'
 include 'trebuchet:system-server-analyzer'
+include 'trebuchet:user-switch-analyzer'
 include 'trebuchet:traceutils'
 include 'trebuchet:viewer'
diff --git a/trebuchet/user-switch-analyzer/MANIFEST.mf b/trebuchet/user-switch-analyzer/MANIFEST.mf
new file mode 100644
index 0000000..2108524
--- /dev/null
+++ b/trebuchet/user-switch-analyzer/MANIFEST.mf
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+Main-Class: UserSwitchStartupAnalyzerKt
diff --git a/trebuchet/user-switch-analyzer/README.md b/trebuchet/user-switch-analyzer/README.md
new file mode 100644
index 0000000..0fa00a2
--- /dev/null
+++ b/trebuchet/user-switch-analyzer/README.md
@@ -0,0 +1,52 @@
+# Android User Switch Analyzer
+
+This is a tool for processing atrace and summarizing how long
+user start, user switch and user unlock process takes during `user switching`
+
+It also provides the time takes by top 5 slowest services in each category
+
+To run the tool, enter the root directory for the
+Trebuchet project and use the following command template:
+`./gradlew :trebuchet:system-server-analyzer:run --args="<trace_file> [-u user_Id] [-o output_filename] [-c service_count]"`.
+
+If you do not already have a trace file to analyze you can follow the steps
+below: (Assuming switching from user 10 to user 11)
+
+1.switch to user 10
+  `adb shell am switch-user 10`
+2.Capture 15 seconds of tracing information using `atrace`:
+  `adb shell atrace -o /sdcard/atrace-ss.txt -t 15 ss`
+3.In another console, switch to user 11:
+  `adb shell am switch-user 11`
+4.Pull the generate file:
+  `adb pull /sdcard/atrace-ss.txt`
+
+Alternatively, run-user-switch-perf.sh script in the scripts folder
+  `./scripts/run-user-switch-perf.sh <from_user> <to_user>`
+  `./scripts/run-user-switch-perf.sh 10 11`
+
+Below is an example of its output:
+
+```
+Opening /tmp/atrace-ss.txt
+Progress: 100.00%
+Parsing atrace-ss.txt took 161ms
+StartUser-11 duration: 175.161 ms
+com.android.server.policy.PermissionPolicyService 136.691 ms
+com.android.server.role.RoleManagerService 13.945 ms
+com.android.server.voiceinteraction.VoiceInteractionManagerService 10.931 ms
+com.android.server.locksettings.LockSettingsService$Lifecycle 2.052 ms
+com.android.server.devicepolicy.DevicePolicyManagerService$Lifecycle 1.231 ms
+SwitchUser-11 duration: 276.585 ms
+com.android.server.om.OverlayManagerService 253.871 ms
+com.android.server.inputmethod.InputMethodManagerService$Lifecycle 10.970 ms
+com.android.server.usb.UsbService$Lifecycle 1.021 ms
+com.android.server.media.MediaSessionService 0.522 ms
+com.android.server.media.projection.MediaProjectionManagerService 0.493 ms
+UnlockUser-11 duration: 72.586 ms
+com.android.server.autofill.AutofillManagerService 28.399 ms
+com.android.server.voiceinteraction.VoiceInteractionManagerService 16.270 ms
+com.android.server.accounts.AccountManagerService$Lifecycle 6.775 ms
+com.android.server.StorageManagerService$Lifecycle 4.069 ms
+com.android.internal.car.CarServiceHelperService 1.290 ms
+```
diff --git a/trebuchet/user-switch-analyzer/build.gradle b/trebuchet/user-switch-analyzer/build.gradle
new file mode 100644
index 0000000..cd0b086
--- /dev/null
+++ b/trebuchet/user-switch-analyzer/build.gradle
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2020 Google Inc.
+ *
+ * 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
+ *
+ *     https://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.
+ */
+
+apply plugin: 'java'
+apply plugin: 'application'
+apply plugin: 'kotlin-platform-jvm'
+
+sourceCompatibility = 1.8
+mainClassName = "UserSwitchAnalyzerKt"
+
+sourceSets {
+    main.kotlin.srcDirs += 'src'
+}
+
+dependencies {
+    compile project(":core:common")
+    compile project(":core:model")
+    compile project(":trebuchet:startup-common")
+    compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
+}
diff --git a/trebuchet/user-switch-analyzer/src/UserSwitchAnalyzer.kt b/trebuchet/user-switch-analyzer/src/UserSwitchAnalyzer.kt
new file mode 100644
index 0000000..28811dc
--- /dev/null
+++ b/trebuchet/user-switch-analyzer/src/UserSwitchAnalyzer.kt
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2020 Google Inc.
+ *
+ * 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
+ *
+ *     https://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.
+ */
+
+/*
+ * Notes
+ *
+ */
+
+/*
+ * Imports
+ */
+
+import java.io.File
+import trebuchet.model.Model
+import trebuchet.extras.parseTrace
+import trebuchet.model.base.Slice
+import trebuchet.model.base.SliceGroup
+import trebuchet.queries.slices.slices
+import java.io.PrintStream
+
+/*
+ * Constants
+ */
+
+/*
+ * Class Definition
+ */
+
+/*
+ * Class Extensions
+ */
+
+/*
+ * Helper Functions
+ */
+
+fun Double.durationString(): String {
+    return "%.3f ms".format(this * 1000)
+}
+
+fun measureServiceStartup(
+    model: Model,
+    userId: Int = 0,
+    count: Int = 0,
+    output: PrintStream = System.out) {
+
+    var stages = arrayOf("Start", "Switch", "Unlock")
+
+    for (item in stages) {
+        model.slices().filter {
+            it.name.contains("ssm." + item + "User-" + userId) && !it.name.contains("ssm.on")
+        }.forEach {
+            output.println(item + "User-" + userId + " duration: " + it.duration.durationString())
+        }
+
+        model.slices().filter {
+            it.name.contains("ssm.on" + item + "User-" + userId)
+        }.sortedByDescending {
+            it.duration
+        }.take(count).forEach {
+            output.println(it.name.removePrefix("ssm.on" + item + "User-" + userId + " ") + " " + it.duration.durationString())
+        }
+    }
+}
+
+/*
+ * Main Function
+ */
+
+fun main(args: Array<String>) {
+    if (args.isEmpty()) {
+        println("Usage: UserSwitchAnalyzerKt <trace_filename> [-u user_Id] [-o output_filename] [-c service_count]")
+        return
+    }
+
+    val input = args[0]
+
+    println("Opening ${input}")
+    val trace = parseTrace(File(input), verbose = true)
+
+    var output = System.out
+    var userId = -1;
+    var serviceCount = 5;
+
+    // Parse optional arguments
+    var nextArg = 1
+    while (nextArg < args.size) {
+        var arg = args[nextArg++]
+        var value = args[nextArg++]
+        when (arg) {
+            "-u" -> userId = value.toInt()
+            "-c" -> serviceCount = value.toInt()
+            "-o" -> {
+                output = PrintStream(File(value).outputStream())
+            }
+            else -> println("invalid option: ${arg}")
+        }
+    }
+
+    if (userId == -1) {
+        println("user Id not provided")
+        return
+    }
+
+    measureServiceStartup(trace, userId, serviceCount, output)
+}