Merge "Fix Bluetooth failing to connect after pairing"
diff --git a/car_product/build/car_base.mk b/car_product/build/car_base.mk
index 658992b..4576c79 100644
--- a/car_product/build/car_base.mk
+++ b/car_product/build/car_base.mk
@@ -83,11 +83,12 @@
     A2dpSinkService \
 
 # EVS resources
-PRODUCT_PACKAGES += android.hardware.automotive.evs@1.0-service
-PRODUCT_PACKAGES += android.hardware.automotive.evs@1.0-sample
 PRODUCT_PACKAGES += android.automotive.evs.manager@1.0
 PRODUCT_PACKAGES += evs_app
-PRODUCT_PACKAGES += evs_app_resources
+# The following packages, or their vendor specific equivalents should be include in the device.mk
+#PRODUCT_PACKAGES += evs_app_default_resources
+#PRODUCT_PACKAGES += android.hardware.automotive.evs@1.0-service
+#PRODUCT_PACKAGES += android.hardware.automotive.evs@1.0-sample
 
 # Device running Android is a car
 PRODUCT_COPY_FILES += \
diff --git a/evs/app/Android.mk b/evs/app/Android.mk
index 7a81cbe..f5d9b6e 100644
--- a/evs/app/Android.mk
+++ b/evs/app/Android.mk
@@ -18,10 +18,6 @@
     WindowSurface.cpp \
     FormatConvert.cpp \
 
-LOCAL_C_INCLUDES += \
-    frameworks/base/include \
-    packages/services/Car/evs/app \
-
 LOCAL_SHARED_LIBRARIES := \
     libcutils \
     liblog \
@@ -57,20 +53,28 @@
 include $(CLEAR_VARS)
 LOCAL_MODULE := config.json
 LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH  := $(TARGET_ROOT_OUT)/system/etc/automotive/evs
+LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/automotive/evs
 LOCAL_SRC_FILES := $(LOCAL_MODULE)
 include $(BUILD_PREBUILT)
 
 include $(CLEAR_VARS)
 LOCAL_MODULE := CarFromTop.png
 LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH  := $(TARGET_ROOT_OUT)/system/etc/automotive/evs
+LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/automotive/evs
 LOCAL_SRC_FILES := $(LOCAL_MODULE)
 include $(BUILD_PREBUILT)
 
 include $(CLEAR_VARS)
 LOCAL_MODULE := LabeledChecker.png
 LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH  := $(TARGET_ROOT_OUT)/system/etc/automotive/evs
+LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/automotive/evs
 LOCAL_SRC_FILES := $(LOCAL_MODULE)
 include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := evs_app_default_resources
+LOCAL_REQUIRED_MODULES := \
+    config.json \
+    CarFromTop.png \
+    LabeledChecker.png
+include $(BUILD_PHONY_PACKAGE)
\ No newline at end of file
diff --git a/evs/app/EvsStateControl.cpp b/evs/app/EvsStateControl.cpp
index 44986c0..79533f7 100644
--- a/evs/app/EvsStateControl.cpp
+++ b/evs/app/EvsStateControl.cpp
@@ -203,7 +203,7 @@
 
 
 bool EvsStateControl::selectStateForCurrentConditions() {
-    ALOGD("selectStateForCurrentConditions");
+    ALOGV("selectStateForCurrentConditions");
 
     static int32_t sDummyGear   = int32_t(VehicleGear::GEAR_REVERSE);
     static int32_t sDummySignal = int32_t(VehicleTurnSignal::NONE);
@@ -248,7 +248,7 @@
         desiredState = PARKING;
     }
 
-    ALOGV("Selected state %d.", desiredState);
+    ALOGD("Selected state %d.", desiredState);
 
     // Apply the desire state
     return configureEvsPipeline(desiredState);
@@ -256,7 +256,7 @@
 
 
 StatusCode EvsStateControl::invokeGet(VehiclePropValue *pRequestedPropValue) {
-    ALOGD("invokeGet");
+    ALOGV("invokeGet");
 
     StatusCode status = StatusCode::TRY_AGAIN;
 
@@ -274,7 +274,7 @@
 
 
 bool EvsStateControl::configureEvsPipeline(State desiredState) {
-    ALOGD("configureEvsPipeline");
+    ALOGV("configureEvsPipeline");
 
     if (mCurrentState == desiredState) {
         // Nothing to do here...
diff --git a/evs/sampleDriver/EvsGlDisplay.cpp b/evs/sampleDriver/EvsGlDisplay.cpp
index a2d92a1..0f62e64 100644
--- a/evs/sampleDriver/EvsGlDisplay.cpp
+++ b/evs/sampleDriver/EvsGlDisplay.cpp
@@ -153,7 +153,7 @@
  * display is no longer visible.
  */
 Return<void> EvsGlDisplay::getTargetBuffer(getTargetBuffer_cb _hidl_cb)  {
-    ALOGD("getTargetBuffer");
+    ALOGV("getTargetBuffer");
     std::lock_guard<std::mutex> lock(mAccessLock);
 
     if (mRequestedState == DisplayState::DEAD) {
@@ -230,7 +230,7 @@
         mFrameBusy = true;
 
         // Send the buffer to the client
-        ALOGD("Providing display buffer handle %p as id %d",
+        ALOGV("Providing display buffer handle %p as id %d",
               mBuffer.memHandle.getNativeHandle(), mBuffer.bufferId);
         _hidl_cb(mBuffer);
         return Void();
@@ -243,7 +243,7 @@
  * The buffer is no longer valid for use by the client after this call.
  */
 Return<EvsResult> EvsGlDisplay::returnTargetBufferForDisplay(const BufferDesc& buffer)  {
-    ALOGD("returnTargetBufferForDisplay %p", buffer.memHandle.getNativeHandle());
+    ALOGV("returnTargetBufferForDisplay %p", buffer.memHandle.getNativeHandle());
     std::lock_guard<std::mutex> lock(mAccessLock);
 
     // Nobody should call us with a null handle
diff --git a/evs/sampleDriver/ServiceNames.h b/evs/sampleDriver/ServiceNames.h
index d20a37f..1178da5 100644
--- a/evs/sampleDriver/ServiceNames.h
+++ b/evs/sampleDriver/ServiceNames.h
@@ -14,4 +14,4 @@
  * limitations under the License.
  */
 
-const static char kEnumeratorServiceName[] = "EvsEnumeratorHw-Mock";
+const static char kEnumeratorServiceName[] = "EvsEnumeratorHw";
diff --git a/tests/carservice_test/src/com/android/car/test/AudioTestUtils.java b/tests/carservice_test/src/com/android/car/test/AudioTestUtils.java
new file mode 100644
index 0000000..8c3de7c
--- /dev/null
+++ b/tests/carservice_test/src/com/android/car/test/AudioTestUtils.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2017 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 com.android.car.test;
+
+import android.media.AudioAttributes;
+import android.media.AudioFocusRequest;
+import android.media.AudioManager;
+import android.media.AudioManager.OnAudioFocusChangeListener;
+
+final class AudioTestUtils {
+    private AudioTestUtils() {}
+
+    static int doRequestFocus(
+            AudioManager audioManager,
+            OnAudioFocusChangeListener listener,
+            int streamType,
+            int androidFocus) {
+        AudioAttributes.Builder attributesBuilder = new AudioAttributes.Builder();
+        attributesBuilder.setLegacyStreamType(streamType);
+        return doRequestFocus(audioManager, listener, attributesBuilder.build(), androidFocus);
+    }
+
+    static int doRequestFocus(
+            AudioManager audioManager,
+            OnAudioFocusChangeListener listener,
+            AudioAttributes attributes,
+            int androidFocus) {
+        return doRequestFocus(audioManager, listener, attributes, androidFocus, false);
+    }
+
+    static int doRequestFocus(
+        AudioManager audioManager,
+        OnAudioFocusChangeListener listener,
+        AudioAttributes attributes,
+        int androidFocus,
+        boolean acceptsDelayedFocus) {
+        AudioFocusRequest.Builder focusBuilder = new AudioFocusRequest.Builder(androidFocus);
+        focusBuilder.setOnAudioFocusChangeListener(listener).setAcceptsDelayedFocusGain(
+                acceptsDelayedFocus);
+        focusBuilder.setAudioAttributes(attributes);
+
+        return audioManager.requestAudioFocus(focusBuilder.build());
+    }
+}
diff --git a/tests/carservice_test/src/com/android/car/test/CarAudioExtFocusTest.java b/tests/carservice_test/src/com/android/car/test/CarAudioExtFocusTest.java
index 047ad41..71e0d04 100644
--- a/tests/carservice_test/src/com/android/car/test/CarAudioExtFocusTest.java
+++ b/tests/carservice_test/src/com/android/car/test/CarAudioExtFocusTest.java
@@ -16,6 +16,7 @@
 package com.android.car.test;
 
 import static android.hardware.automotive.vehicle.V2_0.VehicleProperty.AUDIO_FOCUS;
+import static com.android.car.test.AudioTestUtils.doRequestFocus;
 import static java.lang.Integer.toHexString;
 
 import android.car.Car;
@@ -226,7 +227,7 @@
     public void testMediaNavFocus() throws Exception {
         //music start
         AudioFocusListener listenerMusic = new AudioFocusListener();
-        int res = mAudioManager.requestAudioFocus(listenerMusic,
+        int res = doRequestFocus(mAudioManager, listenerMusic,
                 AudioManager.STREAM_MUSIC,
                 AudioManager.AUDIOFOCUS_GAIN);
         assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
@@ -248,8 +249,8 @@
                 setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION).
                 setUsage(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE).
                 build();
-        mAudioManager.requestAudioFocus(listenerNav, navAttrib,
-                AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, 0);
+        doRequestFocus(mAudioManager, listenerNav, navAttrib,
+                AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
         request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
         assertEquals(VehicleAudioFocusRequest.REQUEST_GAIN, request[0]);
         assertEquals(0x3, request[1]);
@@ -292,7 +293,7 @@
     public void testMediaExternalMediaNavFocus() throws Exception {
         // android music
         AudioFocusListener listenerMusic = new AudioFocusListener();
-        int res = mAudioManager.requestAudioFocus(listenerMusic,
+        int res = doRequestFocus(mAudioManager, listenerMusic,
                 AudioManager.STREAM_MUSIC,
                 AudioManager.AUDIOFOCUS_GAIN);
         assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
@@ -322,8 +323,8 @@
                 setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION).
                 setUsage(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE).
                 build();
-        mAudioManager.requestAudioFocus(listenerNav, navAttrib,
-                AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, 0);
+        doRequestFocus(mAudioManager, listenerNav, navAttrib,
+                AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
         request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
         assertEquals(VehicleAudioFocusRequest.REQUEST_GAIN_TRANSIENT_MAY_DUCK,
                 request[0]);
@@ -368,8 +369,8 @@
         assertNotNull(carAudioManager);
         AudioAttributes radioAttributes = carAudioManager.getAudioAttributesForCarUsage(
                 CarAudioManager.CAR_AUDIO_USAGE_RADIO);
-        int res = mAudioManager.requestAudioFocus(listenerRadio,
-                radioAttributes, AudioManager.AUDIOFOCUS_GAIN, 0);
+        int res = doRequestFocus(mAudioManager, listenerRadio,
+                radioAttributes, AudioManager.AUDIOFOCUS_GAIN);
         assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
         int[] request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
         assertEquals(VehicleAudioFocusRequest.REQUEST_GAIN, request[0]);
@@ -388,8 +389,8 @@
         AudioFocusListener listenerNav = new AudioFocusListener();
         AudioAttributes extNavAttributes = mCarAudioManager.getAudioAttributesForExternalSource(
                 CarAudioManager.CAR_EXTERNAL_SOURCE_TYPE_EXT_NAV_GUIDANCE);
-        res = mAudioManager.requestAudioFocus(listenerNav,
-                extNavAttributes, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, 0);
+        res = doRequestFocus(mAudioManager, listenerNav,
+                extNavAttributes, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
         assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
         request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
         assertEquals(VehicleAudioFocusRequest.REQUEST_GAIN,
@@ -437,7 +438,7 @@
     public void testMediaExternalNav() throws Exception {
         // android music
         AudioFocusListener listenerMusic = new AudioFocusListener();
-        int res = mAudioManager.requestAudioFocus(listenerMusic,
+        int res = doRequestFocus(mAudioManager, listenerMusic,
                 AudioManager.STREAM_MUSIC,
                 AudioManager.AUDIOFOCUS_GAIN);
         assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
@@ -457,8 +458,8 @@
         AudioFocusListener listenerNav = new AudioFocusListener();
         AudioAttributes extNavAttributes = mCarAudioManager.getAudioAttributesForExternalSource(
                 CarAudioManager.CAR_EXTERNAL_SOURCE_TYPE_EXT_NAV_GUIDANCE);
-        res = mAudioManager.requestAudioFocus(listenerNav,
-                extNavAttributes, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, 0);
+        res = doRequestFocus(mAudioManager, listenerNav,
+                extNavAttributes, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
         assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
         request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
         assertEquals(VehicleAudioFocusRequest.REQUEST_GAIN,
@@ -513,8 +514,8 @@
         AudioFocusListener listenerIntNav = new AudioFocusListener();
         AudioAttributes intNavAttributes = mCarAudioManager.getAudioAttributesForCarUsage(
                 CarAudioManager.CAR_AUDIO_USAGE_NAVIGATION_GUIDANCE);
-        int res = mAudioManager.requestAudioFocus(listenerIntNav, intNavAttributes,
-                AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, 0);
+        int res = doRequestFocus(mAudioManager, listenerIntNav, intNavAttributes,
+                AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
         assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
         int[] request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
         assertEquals(VehicleAudioFocusRequest.REQUEST_GAIN_TRANSIENT_MAY_DUCK,
@@ -533,8 +534,8 @@
         AudioFocusListener listenerExtNav = new AudioFocusListener();
         AudioAttributes extNavAttributes = mCarAudioManager.getAudioAttributesForExternalSource(
                 CarAudioManager.CAR_EXTERNAL_SOURCE_TYPE_EXT_NAV_GUIDANCE);
-        res = mAudioManager.requestAudioFocus(listenerExtNav,
-                extNavAttributes, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, 0);
+        res = doRequestFocus(mAudioManager, listenerExtNav,
+                extNavAttributes, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
         assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
         request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
         assertEquals(VehicleAudioFocusRequest.REQUEST_GAIN,
@@ -581,7 +582,7 @@
     public void testMediaExternalRadioNavMediaFocus() throws Exception {
         // android music
         AudioFocusListener listenerMusic = new AudioFocusListener();
-        int res = mAudioManager.requestAudioFocus(listenerMusic,
+        int res = doRequestFocus(mAudioManager, listenerMusic,
                 AudioManager.STREAM_MUSIC,
                 AudioManager.AUDIOFOCUS_GAIN);
         assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
@@ -604,8 +605,8 @@
         assertNotNull(carAudioManager);
         AudioAttributes radioAttributes = carAudioManager.getAudioAttributesForCarUsage(
                 CarAudioManager.CAR_AUDIO_USAGE_RADIO);
-        res = mAudioManager.requestAudioFocus(listenerRadio,
-                radioAttributes, AudioManager.AUDIOFOCUS_GAIN, 0);
+        res = doRequestFocus(mAudioManager, listenerRadio,
+                radioAttributes, AudioManager.AUDIOFOCUS_GAIN);
         assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
         request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
         assertEquals(VehicleAudioFocusRequest.REQUEST_GAIN, request[0]);
@@ -626,8 +627,8 @@
                 setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION).
                 setUsage(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE).
                 build();
-        res = mAudioManager.requestAudioFocus(listenerNav, navAttrib,
-                AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, 0);
+        res = doRequestFocus(mAudioManager, listenerNav, navAttrib,
+                AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
         request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
         assertEquals(VehicleAudioFocusRequest.REQUEST_GAIN,
                 request[0]);
@@ -762,8 +763,8 @@
         assertNotNull(carAudioManager);
         AudioAttributes radioAttributes = carAudioManager.getAudioAttributesForCarUsage(mediaUsage);
         Log.i(TAG, "request media Focus");
-        int res = mAudioManager.requestAudioFocus(listenerMedia,
-                radioAttributes, AudioManager.AUDIOFOCUS_GAIN, 0);
+        int res = doRequestFocus(mAudioManager, listenerMedia,
+                radioAttributes, AudioManager.AUDIOFOCUS_GAIN);
         assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
         int[] request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
         assertEquals(VehicleAudioFocusRequest.REQUEST_GAIN, request[0]);
@@ -806,8 +807,8 @@
                 setUsage(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE).
                 build();
         Log.i(TAG, "request nav Focus");
-        res = mAudioManager.requestAudioFocus(listenerNav, navAttrib,
-                AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, 0);
+        res = doRequestFocus(mAudioManager, listenerNav, navAttrib,
+                AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
         request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
         assertEquals(VehicleAudioFocusRequest.REQUEST_GAIN_TRANSIENT_MAY_DUCK,
                 request[0]);
diff --git a/tests/carservice_test/src/com/android/car/test/CarAudioFocusSystemSoundTest.java b/tests/carservice_test/src/com/android/car/test/CarAudioFocusSystemSoundTest.java
index 99958cc..afafb28 100644
--- a/tests/carservice_test/src/com/android/car/test/CarAudioFocusSystemSoundTest.java
+++ b/tests/carservice_test/src/com/android/car/test/CarAudioFocusSystemSoundTest.java
@@ -17,6 +17,7 @@
 
 import static android.hardware.automotive.vehicle.V2_0.VehicleProperty.AUDIO_FOCUS;
 import static android.hardware.automotive.vehicle.V2_0.VehicleProperty.AUDIO_STREAM_STATE;
+import static com.android.car.test.AudioTestUtils.doRequestFocus;
 
 import com.google.android.collect.Lists;
 
@@ -136,8 +137,8 @@
         assertNotNull(carAudioManager);
         AudioAttributes radioAttributes = carAudioManager.getAudioAttributesForCarUsage(
                 CarAudioManager.CAR_AUDIO_USAGE_RADIO);
-        int res = mAudioManager.requestAudioFocus(listenerRadio,
-                radioAttributes, AudioManager.AUDIOFOCUS_GAIN, 0);
+        int res = doRequestFocus(mAudioManager, listenerRadio,
+                radioAttributes, AudioManager.AUDIOFOCUS_GAIN);
         assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
         int[] request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
         assertEquals(VehicleAudioFocusRequest.REQUEST_GAIN, request[0]);
@@ -190,7 +191,7 @@
     public void testMusicSystemSound() throws Exception {
         // music start
         AudioFocusListener listenerMusic = new AudioFocusListener();
-        int res = mAudioManager.requestAudioFocus(listenerMusic,
+        int res = doRequestFocus(mAudioManager, listenerMusic,
                 AudioManager.STREAM_MUSIC,
                 AudioManager.AUDIOFOCUS_GAIN);
         assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
@@ -246,8 +247,8 @@
                 setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION).
                 setUsage(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE).
                 build();
-        int res = mAudioManager.requestAudioFocus(listenerNav, navAttrib,
-                AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, 0);
+        int res = doRequestFocus(mAudioManager, listenerNav, navAttrib,
+                AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
         assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
         int[] request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
         assertEquals(VehicleAudioFocusRequest.REQUEST_GAIN_TRANSIENT_MAY_DUCK,
diff --git a/tests/carservice_test/src/com/android/car/test/CarAudioFocusTest.java b/tests/carservice_test/src/com/android/car/test/CarAudioFocusTest.java
index 9ead75d..6f5da5f 100644
--- a/tests/carservice_test/src/com/android/car/test/CarAudioFocusTest.java
+++ b/tests/carservice_test/src/com/android/car/test/CarAudioFocusTest.java
@@ -16,6 +16,7 @@
 package com.android.car.test;
 
 import static android.hardware.automotive.vehicle.V2_0.VehicleProperty.AUDIO_FOCUS;
+import static com.android.car.test.AudioTestUtils.doRequestFocus;
 
 import android.car.Car;
 import android.car.media.CarAudioManager;
@@ -135,7 +136,7 @@
     public void testMediaNavFocus() throws Exception {
         //music start
         AudioFocusListener listenerMusic = new AudioFocusListener();
-        int res = mAudioManager.requestAudioFocus(listenerMusic,
+        int res = doRequestFocus(mAudioManager, listenerMusic,
                 AudioManager.STREAM_MUSIC,
                 AudioManager.AUDIOFOCUS_GAIN);
         assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
@@ -155,8 +156,8 @@
                 setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION).
                 setUsage(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE).
                 build();
-        mAudioManager.requestAudioFocus(listenerNav, navAttrib,
-                AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, 0);
+        doRequestFocus(mAudioManager, listenerNav, navAttrib,
+                AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
         request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
         assertEquals(VehicleAudioFocusRequest.REQUEST_GAIN, request[0]);
         assertEquals(0x3, request[1]);
@@ -193,7 +194,7 @@
     public void testMediaExternalMediaNavFocus() throws Exception {
         // android music
         AudioFocusListener listenerMusic = new AudioFocusListener();
-        int res = mAudioManager.requestAudioFocus(listenerMusic,
+        int res = doRequestFocus(mAudioManager, listenerMusic,
                 AudioManager.STREAM_MUSIC,
                 AudioManager.AUDIOFOCUS_GAIN);
         assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
@@ -221,8 +222,8 @@
                 setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION).
                 setUsage(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE).
                 build();
-        mAudioManager.requestAudioFocus(listenerNav, navAttrib,
-                AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, 0);
+        doRequestFocus(mAudioManager, listenerNav, navAttrib,
+                AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
         request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
         assertEquals(VehicleAudioFocusRequest.REQUEST_GAIN_TRANSIENT_MAY_DUCK,
                 request[0]);
@@ -258,7 +259,7 @@
     public void testMediaExternalRadioNavMediaFocus() throws Exception {
         // android music
         AudioFocusListener listenerMusic = new AudioFocusListener();
-        int res = mAudioManager.requestAudioFocus(listenerMusic,
+        int res = doRequestFocus(mAudioManager, listenerMusic,
                 AudioManager.STREAM_MUSIC,
                 AudioManager.AUDIOFOCUS_GAIN);
         assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
@@ -279,8 +280,8 @@
         assertNotNull(carAudioManager);
         AudioAttributes radioAttributes = carAudioManager.getAudioAttributesForCarUsage(
                 CarAudioManager.CAR_AUDIO_USAGE_RADIO);
-        res = mAudioManager.requestAudioFocus(listenerRadio,
-                radioAttributes, AudioManager.AUDIOFOCUS_GAIN, 0);
+        res = doRequestFocus(mAudioManager, listenerRadio,
+                radioAttributes, AudioManager.AUDIOFOCUS_GAIN);
         assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
         request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
         assertEquals(VehicleAudioFocusRequest.REQUEST_GAIN, request[0]);
@@ -299,8 +300,8 @@
                 setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION).
                 setUsage(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE).
                 build();
-        res = mAudioManager.requestAudioFocus(listenerNav, navAttrib,
-                AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, 0);
+        res = doRequestFocus(mAudioManager, listenerNav, navAttrib,
+                AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
         request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
         assertEquals(VehicleAudioFocusRequest.REQUEST_GAIN,
                 request[0]);
@@ -360,7 +361,7 @@
             int context)
             throws Exception {
         AudioFocusListener lister = new AudioFocusListener();
-        int res = mAudioManager.requestAudioFocus(lister,
+        int res = doRequestFocus(mAudioManager, lister,
                 streamType,
                 androidFocus);
         assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
@@ -426,8 +427,8 @@
         assertNotNull(carAudioManager);
         AudioAttributes radioAttributes = carAudioManager.getAudioAttributesForCarUsage(mediaUsage);
         Log.i(TAG, "request media Focus");
-        int res = mAudioManager.requestAudioFocus(listenerMedia,
-                radioAttributes, AudioManager.AUDIOFOCUS_GAIN, 0);
+        int res = doRequestFocus(mAudioManager, listenerMedia,
+                radioAttributes, AudioManager.AUDIOFOCUS_GAIN);
         assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
         int[] request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
         assertEquals(VehicleAudioFocusRequest.REQUEST_GAIN, request[0]);
@@ -461,8 +462,8 @@
                 setUsage(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE).
                 build();
         Log.i(TAG, "request nav Focus");
-        res = mAudioManager.requestAudioFocus(listenerNav, navAttrib,
-                AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, 0);
+        res = doRequestFocus(mAudioManager, listenerNav, navAttrib,
+                AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
         request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
         assertEquals(VehicleAudioFocusRequest.REQUEST_GAIN_TRANSIENT_MAY_DUCK,
                 request[0]);
diff --git a/tests/carservice_test/src/com/android/car/test/CarVolumeServiceTest.java b/tests/carservice_test/src/com/android/car/test/CarVolumeServiceTest.java
index cdd8838..df2b532 100644
--- a/tests/carservice_test/src/com/android/car/test/CarVolumeServiceTest.java
+++ b/tests/carservice_test/src/com/android/car/test/CarVolumeServiceTest.java
@@ -15,6 +15,8 @@
  */
 package com.android.car.test;
 
+import static com.android.car.test.AudioTestUtils.doRequestFocus;
+
 import com.google.android.collect.Lists;
 
 import android.car.Car;
@@ -121,7 +123,7 @@
             // first give focus to system sound
             CarAudioFocusTest.AudioFocusListener listenerMusic =
                     new CarAudioFocusTest.AudioFocusListener();
-            int res = mAudioManager.requestAudioFocus(listenerMusic,
+            int res = doRequestFocus(mAudioManager, listenerMusic,
                     AudioManager.STREAM_SYSTEM,
                     AudioManager.AUDIOFOCUS_GAIN);
             assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
@@ -137,8 +139,8 @@
             AudioAttributes callAttrib = (new AudioAttributes.Builder()).
                     setUsage(AudioAttributes.USAGE_ALARM).
                     build();
-            res = mAudioManager.requestAudioFocus(listenerAlarm, callAttrib,
-                    AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, 0);
+            res = doRequestFocus(mAudioManager, listenerAlarm, callAttrib,
+                    AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
             assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
             request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
             mAudioFocusPropertyHandler.sendAudioFocusState(
@@ -169,7 +171,7 @@
 
             CarAudioFocusTest.AudioFocusListener listenerMusic =
                     new CarAudioFocusTest.AudioFocusListener();
-            int res = mAudioManager.requestAudioFocus(listenerMusic,
+            int res = doRequestFocus(mAudioManager, listenerMusic,
                     AudioManager.STREAM_MUSIC,
                     AudioManager.AUDIOFOCUS_GAIN);
             assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
@@ -191,8 +193,8 @@
             AudioAttributes callAttrib = (new AudioAttributes.Builder()).
                     setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION).
                     build();
-            mAudioManager.requestAudioFocus(listenerCall, callAttrib,
-                    AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, 0);
+            doRequestFocus(mAudioManager, listenerCall, callAttrib,
+                    AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
             request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
             mAudioFocusPropertyHandler.sendAudioFocusState(
                     VehicleAudioFocusState.STATE_GAIN, request[1],
diff --git a/tools/bootanalyze/bootanalyze.py b/tools/bootanalyze/bootanalyze.py
index 6f87aac..23cbe11 100755
--- a/tools/bootanalyze/bootanalyze.py
+++ b/tools/bootanalyze/bootanalyze.py
@@ -86,9 +86,11 @@
   cfg = yaml.load(args.config)
 
   if args.stressfs:
-    if subprocess.call(ADB_CMD + ' install -r -g ' + args.stressfs, shell=True) != 0:
+    if run_adb_cmd('install -r -g ' + args.stressfs) != 0:
       raise Exception('StressFS APK not installed');
 
+  if args.iterate > 1 and args.bootchart:
+    run_adb_shell_cmd_as_root('touch /data/bootchart/enabled')
 
   search_events = {key: re.compile(pattern)
                    for key, pattern in cfg['events'].iteritems()}
@@ -99,9 +101,11 @@
   kernel_timing_points = collections.OrderedDict()
   logcat_timing_points = collections.OrderedDict()
   boottime_points = collections.OrderedDict()
+  boot_chart_file_name_prefix = "bootchart-" + datetime.now().strftime("%Y-%m-%d-%H-%M-%S")
+  systrace_file_name_prefix = "systrace-" + datetime.now().strftime("%Y-%m-%d-%H-%M-%S")
   for it in range(0, args.iterate):
     if args.iterate > 1:
-      print "Run: {0}".format(it + 1)
+      print "Run: {0}".format(it)
     attempt = 1
     processing_data = None
     timings = None
@@ -113,8 +117,13 @@
 
     if not processing_data or not boottime_events:
       # Processing error
-      print "Failed to collect valid samples for run {0}".format(it + 1)
+      print "Failed to collect valid samples for run {0}".format(it)
       continue
+    if args.bootchart:
+      grab_bootchart(boot_chart_file_name_prefix + "_run_" + str(it))
+
+    if args.systrace:
+      grab_systrace(systrace_file_name_prefix + "_run_" + str(it))
     for k, v in processing_data.iteritems():
       if k not in data_points:
         data_points[k] = []
@@ -137,8 +146,8 @@
       boottime_points[k].append(v)
 
   if args.stressfs:
-    subprocess.call(ADB_CMD + ' uninstall com.android.car.test.stressfs', shell=True)
-    subprocess.call(ADB_CMD + ' shell "rm -rf /storage/emulated/0/stressfs_data*"', shell=True)
+    run_adb_cmd('uninstall com.android.car.test.stressfs')
+    run_adb_shell_cmd('"rm -rf /storage/emulated/0/stressfs_data*"')
 
   if args.iterate > 1:
     print "-----------------"
@@ -168,6 +177,8 @@
       print '{0:30}: {1:<7.5} {2:<7.5} {3}'.format(
         item[0], item[1], item[2], item[3] if item[3] != args.iterate else "")
 
+    run_adb_shell_cmd_as_root('rm /data/bootchart/enabled')
+
 
 def dump_timings_points_summary(msg_header, timing_points, args):
       averaged_timing_points = []
@@ -442,6 +453,12 @@
                       help='capture bugreport if specified timing component is taking more than ' +\
                            'certain time. Unlike errortime, the result will not be rejected in' +\
                            'averaging. Format is key1=time1,key2=time2...')
+  parser.add_argument('-b', '--bootchart', dest='bootchart',
+                      action='store_true',
+                      help='collect bootchart from the device.', )
+  parser.add_argument('-y', '--systrace', dest='systrace',
+                      action='store_true',
+                      help='collect systrace from the device. kernel trace should be already enabled', )
   return parser.parse_args()
 
 def handle_zygote_event(zygote_pids, events, event, line):
@@ -601,10 +618,10 @@
   original_devices = subprocess.check_output("adb devices", shell=True)
   if use_adb_reboot:
     print 'Rebooting the device using adb reboot'
-    subprocess.call(ADB_CMD + ' reboot', shell=True)
+    run_adb_cmd('reboot')
   else:
     print 'Rebooting the device using svc power reboot'
-    subprocess.call(ADB_CMD + ' shell su root svc power reboot', shell=True)
+    run_adb_shell_cmd_as_root('svc power reboot')
   # Wait for the device to go away
   retry = 0
   while retry < 20:
@@ -619,13 +636,13 @@
 def reboot(serial, use_stressfs, permissive, use_adb_reboot):
   if use_stressfs:
     print 'Starting write to data partition'
-    subprocess.call(ADB_CMD + ' shell am start' +\
-                              ' -n com.android.car.test.stressfs/.WritingActivity' +\
-                              ' -a com.android.car.test.stressfs.START', shell=True)
+    run_adb_shell_cmd('am start' +\
+                      ' -n com.android.car.test.stressfs/.WritingActivity' +\
+                      ' -a com.android.car.test.stressfs.START')
     # Give this app some time to start.
     time.sleep(1)
   if permissive:
-    subprocess.call(ADB_CMD + ' shell su root setenforce 0', shell=True)
+    run_adb_shell_cmd_as_root('setenforce 0')
 
   retry = 0
   while retry < 5:
@@ -634,7 +651,16 @@
     retry += 1
 
   print 'Waiting the device'
-  subprocess.call(ADB_CMD + ' wait-for-device', shell=True)
+  run_adb_cmd('wait-for-device')
+
+def run_adb_cmd(cmd):
+  return subprocess.call(ADB_CMD + ' ' + cmd, shell=True)
+
+def run_adb_shell_cmd(cmd):
+  return subprocess.call(ADB_CMD + ' shell ' + cmd, shell=True)
+
+def run_adb_shell_cmd_as_root(cmd):
+  return subprocess.call(ADB_CMD + ' shell su root ' + cmd, shell=True)
 
 def logcat_time_func(offset_year):
   def f(date_str):
@@ -653,5 +679,21 @@
   variance = sq_diffs_sum / items_count
   return math.sqrt(variance)
 
+def grab_bootchart(boot_chart_file_name):
+  subprocess.call("./system/core/init/grab-bootchart.sh --no-viewer", shell=True)
+  print "Saving boot chart as " + boot_chart_file_name + ".tgz"
+  subprocess.call('cp /tmp/android-bootchart/bootchart.tgz ./' + boot_chart_file_name + '.tgz',\
+                  shell=True)
+  subprocess.call('cp ./bootchart.png ./' + boot_chart_file_name + '.png', shell=True)
+
+def grab_systrace(systrace_file_name):
+  trace_file = systrace_file_name + "_trace.txt"
+  with open(trace_file, 'w') as f:
+    f.write("TRACE:\n")
+  run_adb_shell_cmd_as_root("cat /d/tracing/trace >> " + trace_file)
+  html_file = systrace_file_name + ".html"
+  subprocess.call("./external/chromium-trace/systrace.py --from-file=" + trace_file + " -o " +\
+                  html_file, shell=True)
+
 if __name__ == '__main__':
   main()
diff --git a/tools/bootanalyze/config.yaml b/tools/bootanalyze/config.yaml
index 9d322ed..ea60434 100644
--- a/tools/bootanalyze/config.yaml
+++ b/tools/bootanalyze/config.yaml
@@ -6,7 +6,8 @@
   ueventd_secs: ueventd:\s(?P<name>[^\s].+)\stook\s(?P<time>[.0-9]+)\sseconds
   init_command_ms: init:\sCommand\s(?P<name>[^\s].+)\sreturned.*took\s(?P<time>[.0-9]+)ms
   init_service_exec_secs: init:\sService\s.*exec\s[^\s]+\s\((?P<name>[^\s].+)\).*pid.*\swaiting\stook\s(?P<time>[.0-9]+)\sseconds
-
+  zygote64_timing: (?P<name>Zygote64Timing\:\s[^\s]+)\stook\sto\scomplete\:\s(?P<time>[0-9]+)ms
+  zygote32_timing: (?P<name>Zygote32Timing\:\s[^\s]+)\stook\sto\scomplete\:\s(?P<time>[0-9]+)ms
 events:
   kernel: Linux version
   android_init_1st_stage: init first stage started
@@ -29,6 +30,8 @@
   correction: Updating system time diff=([0-9]+\.?[0-9]*), cuttime=([0-9]+)
   servicemanager_start_by_init: starting service 'servicemanager'
   zygoteInit: START com.android.internal.os.ZygoteInit
+  ZygoteMainSystemServer: app_process\smain\swith\sargv.*\-\-start\-system\-server
+  ZygoteMainOthers: app_process\smain\swith\sargv
   zygote_preload_start: Zygote\s*:\s*begin preload
   zygote_preload_classes_start: Zygote\s*:\s*Preloading classes...
   zygote_preload_res_start: Zygote\s*:\s*Preloading resources...