diff --git a/keystore/java/android/security/KeyChain.java b/keystore/java/android/security/KeyChain.java
index 3ab60f8..adfdfba 100644
--- a/keystore/java/android/security/KeyChain.java
+++ b/keystore/java/android/security/KeyChain.java
@@ -409,24 +409,26 @@
         if (alias == null) {
             throw new NullPointerException("alias == null");
         }
-        KeyChainConnection keyChainConnection = bind(context.getApplicationContext());
-        try {
-            final IKeyChainService keyChainService = keyChainConnection.getService();
-            final String keyId = keyChainService.requestPrivateKey(alias);
-            if (keyId == null) {
-                return null;
-            }
-            return AndroidKeyStoreProvider.loadAndroidKeyStorePrivateKeyFromKeystore(
-                    KeyStore.getInstance(), keyId, KeyStore.UID_SELF);
+
+        final String keyId;
+        try (KeyChainConnection keyChainConnection = bind(context.getApplicationContext())) {
+            keyId = keyChainConnection.getService().requestPrivateKey(alias);
         } catch (RemoteException e) {
             throw new KeyChainException(e);
         } catch (RuntimeException e) {
             // only certain RuntimeExceptions can be propagated across the IKeyChainService call
             throw new KeyChainException(e);
-        } catch (UnrecoverableKeyException e) {
-            throw new KeyChainException(e);
-        } finally {
-            keyChainConnection.close();
+        }
+
+        if (keyId == null) {
+            return null;
+        } else {
+            try {
+                return AndroidKeyStoreProvider.loadAndroidKeyStorePrivateKeyFromKeystore(
+                        KeyStore.getInstance(), keyId, KeyStore.UID_SELF);
+            } catch (RuntimeException | UnrecoverableKeyException e) {
+                throw new KeyChainException(e);
+            }
         }
     }
 
@@ -453,16 +455,25 @@
         if (alias == null) {
             throw new NullPointerException("alias == null");
         }
-        KeyChainConnection keyChainConnection = bind(context.getApplicationContext());
-        try {
-            IKeyChainService keyChainService = keyChainConnection.getService();
 
-            final byte[] certificateBytes = keyChainService.getCertificate(alias);
+        final byte[] certificateBytes;
+        final byte[] certChainBytes;
+        try (KeyChainConnection keyChainConnection = bind(context.getApplicationContext())) {
+            IKeyChainService keyChainService = keyChainConnection.getService();
+            certificateBytes = keyChainService.getCertificate(alias);
             if (certificateBytes == null) {
                 return null;
             }
+            certChainBytes = keyChainService.getCaCertificates(alias);
+        } catch (RemoteException e) {
+            throw new KeyChainException(e);
+        } catch (RuntimeException e) {
+            // only certain RuntimeExceptions can be propagated across the IKeyChainService call
+            throw new KeyChainException(e);
+        }
+
+        try {
             X509Certificate leafCert = toCertificate(certificateBytes);
-            final byte[] certChainBytes = keyChainService.getCaCertificates(alias);
             // If the keypair is installed with a certificate chain by either
             // DevicePolicyManager.installKeyPair or CertInstaller, return that chain.
             if (certChainBytes != null && certChainBytes.length != 0) {
@@ -486,15 +497,8 @@
                 List<X509Certificate> chain = store.getCertificateChain(leafCert);
                 return chain.toArray(new X509Certificate[chain.size()]);
             }
-        } catch (CertificateException e) {
+        } catch (CertificateException | RuntimeException e) {
             throw new KeyChainException(e);
-        } catch (RemoteException e) {
-            throw new KeyChainException(e);
-        } catch (RuntimeException e) {
-            // only certain RuntimeExceptions can be propagated across the IKeyChainService call
-            throw new KeyChainException(e);
-        } finally {
-            keyChainConnection.close();
         }
     }
 
diff --git a/libs/hwui/ShadowTessellator.h b/libs/hwui/ShadowTessellator.h
index 5f4c9c5..2eaf187 100644
--- a/libs/hwui/ShadowTessellator.h
+++ b/libs/hwui/ShadowTessellator.h
@@ -80,8 +80,6 @@
 
     static Vector2 centroid2d(const Vector2* poly, int polyLength);
 
-    static bool isClockwise(const Vector2* polygon, int len);
-
     static Vector2 calculateNormal(const Vector2& p1, const Vector2& p2);
 
     static int getExtraVertexNumber(const Vector2& vector1, const Vector2& vector2,
diff --git a/libs/hwui/SpotShadow.cpp b/libs/hwui/SpotShadow.cpp
index 760d814..e2ee5bf 100644
--- a/libs/hwui/SpotShadow.cpp
+++ b/libs/hwui/SpotShadow.cpp
@@ -302,21 +302,6 @@
 }
 
 /**
- * Make the polygon turn clockwise.
- *
- * @param polygon the polygon as a Vector2 array.
- * @param len the number of points of the polygon
- */
-void SpotShadow::makeClockwise(Vector2* polygon, int len) {
-    if (polygon == nullptr  || len == 0) {
-        return;
-    }
-    if (!ShadowTessellator::isClockwise(polygon, len)) {
-        reverse(polygon, len);
-    }
-}
-
-/**
  * Reverse the polygon
  *
  * @param polygon the polygon as a Vector2 array
diff --git a/libs/hwui/SpotShadow.h b/libs/hwui/SpotShadow.h
index 62a7e5d..6108bb6 100644
--- a/libs/hwui/SpotShadow.h
+++ b/libs/hwui/SpotShadow.h
@@ -54,7 +54,6 @@
     static void quicksortX(Vector2* points, int low, int high);
 
     static bool testPointInsidePolygon(const Vector2 testPoint, const Vector2* poly, int len);
-    static void makeClockwise(Vector2* polygon, int len);
     static void reverse(Vector2* polygon, int len);
 
     static void generateTriangleStrip(bool isCasterOpaque, float shadowStrengthScale,
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 3174c70..64dea57 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -630,7 +630,11 @@
                 MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]);
         if (maxVolume != MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]) {
             MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = maxVolume;
-            AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = (maxVolume * 3) / 4;
+            if (isPlatformTelevision()) {
+                AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = maxVolume / 4;
+            } else {
+                AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = (maxVolume * 3) / 4;
+            }
         }
 
         sSoundEffectVolumeDb = context.getResources().getInteger(
diff --git a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
index 872ebe8..1cf5097 100644
--- a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
@@ -16,13 +16,18 @@
 
 package com.android.server.am;
 
+import android.app.IUserSwitchObserver;
 import android.content.Context;
 import android.content.IIntentReceiver;
 import android.content.Intent;
 import android.content.pm.UserInfo;
+import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.HandlerThread;
+import android.os.IRemoteCallback;
+import android.os.Looper;
+import android.os.Message;
 import android.os.RemoteException;
 import android.os.UserManagerInternal;
 import android.test.AndroidTestCase;
@@ -35,16 +40,30 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.List;
+import java.util.Set;
 
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static com.android.server.am.ActivityManagerService.CONTINUE_USER_SWITCH_MSG;
+import static com.android.server.am.ActivityManagerService.REPORT_USER_SWITCH_COMPLETE_MSG;
+import static com.android.server.am.ActivityManagerService.REPORT_USER_SWITCH_MSG;
+import static com.android.server.am.ActivityManagerService.SYSTEM_USER_CURRENT_MSG;
+import static com.android.server.am.ActivityManagerService.SYSTEM_USER_START_MSG;
+import static com.android.server.am.ActivityManagerService.USER_SWITCH_TIMEOUT_MSG;
+import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.when;
 
 public class UserControllerTest extends AndroidTestCase {
+    private static final int TEST_USER_ID = 10;
     private static String TAG = UserControllerTest.class.getSimpleName();
     private UserController mUserController;
     private TestInjector mInjector;
@@ -54,7 +73,7 @@
         super.setUp();
         mInjector = new TestInjector(getContext());
         mUserController = new UserController(mInjector);
-        setUpUser(10, 0);
+        setUpUser(TEST_USER_ID, 0);
     }
 
     @Override
@@ -65,13 +84,100 @@
     }
 
     public void testStartUser() throws RemoteException {
-        mUserController.startUser(10, true);
-
+        mUserController.startUser(TEST_USER_ID, true);
         Mockito.verify(mInjector.getWindowManager()).startFreezingScreen(anyInt(), anyInt());
         Mockito.verify(mInjector.getWindowManager(), never()).stopFreezingScreen();
         List<String> expectedActions = Arrays.asList(Intent.ACTION_USER_STARTED,
                 Intent.ACTION_USER_SWITCHED, Intent.ACTION_USER_STARTING);
         assertEquals(expectedActions, getActions(mInjector.sentIntents));
+        Set<Integer> expectedCodes = new HashSet<>(
+                Arrays.asList(REPORT_USER_SWITCH_MSG, USER_SWITCH_TIMEOUT_MSG,
+                        SYSTEM_USER_START_MSG, SYSTEM_USER_CURRENT_MSG));
+        Set<Integer> actualCodes = mInjector.handler.getMessageCodes();
+        assertEquals("Unexpected message sent", expectedCodes, actualCodes);
+        Message reportMsg = mInjector.handler.getMessageForCode(REPORT_USER_SWITCH_MSG);
+        assertNotNull(reportMsg);
+        UserState userState = (UserState) reportMsg.obj;
+        assertNotNull(userState);
+        assertEquals(TEST_USER_ID, userState.mHandle.getIdentifier());
+        assertEquals("User must be in STATE_BOOTING", UserState.STATE_BOOTING, userState.state);
+        assertEquals("Unexpected old user id", 0, reportMsg.arg1);
+        assertEquals("Unexpected new user id", TEST_USER_ID, reportMsg.arg2);
+    }
+
+    public void testDispatchUserSwitch() throws RemoteException {
+        // Prepare mock observer and register it
+        IUserSwitchObserver observer = mock(IUserSwitchObserver.class);
+        when(observer.asBinder()).thenReturn(new Binder());
+        doAnswer(invocation -> {
+            IRemoteCallback callback = (IRemoteCallback) invocation.getArguments()[1];
+            callback.sendResult(null);
+            return null;
+        }).when(observer).onUserSwitching(anyInt(), any());
+        mUserController.registerUserSwitchObserver(observer, "mock");
+        // Start user -- this will update state of mUserController
+        mUserController.startUser(TEST_USER_ID, true);
+        Message reportMsg = mInjector.handler.getMessageForCode(REPORT_USER_SWITCH_MSG);
+        assertNotNull(reportMsg);
+        UserState userState = (UserState) reportMsg.obj;
+        int oldUserId = reportMsg.arg1;
+        int newUserId = reportMsg.arg2;
+        // Call dispatchUserSwitch and verify that observer was called only once
+        mInjector.handler.clearAllRecordedMessages();
+        mUserController.dispatchUserSwitch(userState, oldUserId, newUserId);
+        Mockito.verify(observer, times(1)).onUserSwitching(eq(TEST_USER_ID), any());
+        Set<Integer> expectedCodes = Collections.singleton(CONTINUE_USER_SWITCH_MSG);
+        Set<Integer> actualCodes = mInjector.handler.getMessageCodes();
+        assertEquals("Unexpected message sent", expectedCodes, actualCodes);
+        Message conMsg = mInjector.handler.getMessageForCode(CONTINUE_USER_SWITCH_MSG);
+        assertNotNull(conMsg);
+        userState = (UserState) conMsg.obj;
+        assertNotNull(userState);
+        assertEquals(TEST_USER_ID, userState.mHandle.getIdentifier());
+        assertEquals("User must be in STATE_BOOTING", UserState.STATE_BOOTING, userState.state);
+        assertEquals("Unexpected old user id", 0, conMsg.arg1);
+        assertEquals("Unexpected new user id", TEST_USER_ID, conMsg.arg2);
+    }
+
+    public void testDispatchUserSwitchBadReceiver() throws RemoteException {
+        // Prepare mock observer which doesn't notify the callback and register it
+        IUserSwitchObserver observer = mock(IUserSwitchObserver.class);
+        when(observer.asBinder()).thenReturn(new Binder());
+        mUserController.registerUserSwitchObserver(observer, "mock");
+        // Start user -- this will update state of mUserController
+        mUserController.startUser(TEST_USER_ID, true);
+        Message reportMsg = mInjector.handler.getMessageForCode(REPORT_USER_SWITCH_MSG);
+        assertNotNull(reportMsg);
+        UserState userState = (UserState) reportMsg.obj;
+        int oldUserId = reportMsg.arg1;
+        int newUserId = reportMsg.arg2;
+        // Call dispatchUserSwitch and verify that observer was called only once
+        mInjector.handler.clearAllRecordedMessages();
+        mUserController.dispatchUserSwitch(userState, oldUserId, newUserId);
+        Mockito.verify(observer, times(1)).onUserSwitching(eq(TEST_USER_ID), any());
+        // Verify that CONTINUE_USER_SWITCH_MSG is not sent (triggers timeout)
+        Set<Integer> actualCodes = mInjector.handler.getMessageCodes();
+        assertTrue("No messages should be sent", actualCodes.isEmpty());
+    }
+
+    public void testContinueUserSwitch() throws RemoteException {
+        // Start user -- this will update state of mUserController
+        mUserController.startUser(TEST_USER_ID, true);
+        Message reportMsg = mInjector.handler.getMessageForCode(REPORT_USER_SWITCH_MSG);
+        assertNotNull(reportMsg);
+        UserState userState = (UserState) reportMsg.obj;
+        int oldUserId = reportMsg.arg1;
+        int newUserId = reportMsg.arg2;
+        mInjector.handler.clearAllRecordedMessages();
+        // Verify that continueUserSwitch worked as expected
+        mUserController.continueUserSwitch(userState, oldUserId, newUserId);
+        Mockito.verify(mInjector.getWindowManager(), times(1)).stopFreezingScreen();
+        Set<Integer> expectedCodes = Collections.singleton(REPORT_USER_SWITCH_COMPLETE_MSG);
+        Set<Integer> actualCodes = mInjector.handler.getMessageCodes();
+        assertEquals("Unexpected message sent", expectedCodes, actualCodes);
+        Message msg = mInjector.handler.getMessageForCode(REPORT_USER_SWITCH_COMPLETE_MSG);
+        assertNotNull(msg);
+        assertEquals("Unexpected userId", TEST_USER_ID, msg.arg1);
     }
 
     private void setUpUser(int userId, int flags) {
@@ -89,7 +195,7 @@
 
     private static class TestInjector extends UserController.Injector {
         final Object lock = new Object();
-        Handler handler;
+        TestHandler handler;
         HandlerThread handlerThread;
         UserManagerService userManagerMock;
         UserManagerInternal userManagerInternalMock;
@@ -102,7 +208,7 @@
             mCtx = ctx;
             handlerThread = new HandlerThread(TAG);
             handlerThread.start();
-            handler = new Handler(handlerThread.getLooper());
+            handler = new TestHandler(handlerThread.getLooper());
             userManagerMock = mock(UserManagerService.class);
             userManagerInternalMock = mock(UserManagerInternal.class);
             windowManagerMock = mock(WindowManagerService.class);
@@ -176,4 +282,41 @@
             Log.i(TAG, "startHomeActivityLocked " + userId);
         }
    }
+
+    private static class TestHandler extends Handler {
+        private final List<Message> mMessages = new ArrayList<>();
+
+        TestHandler(Looper looper) {
+            super(looper);
+        }
+
+        Set<Integer> getMessageCodes() {
+            Set<Integer> result = new LinkedHashSet<>();
+            for (Message msg : mMessages) {
+                result.add(msg.what);
+            }
+            return result;
+        }
+
+        Message getMessageForCode(int what) {
+            for (Message msg : mMessages) {
+                if (msg.what == what) {
+                    return msg;
+                }
+            }
+            return null;
+        }
+
+        void clearAllRecordedMessages() {
+            mMessages.clear();
+        }
+
+        @Override
+        public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
+            Message copy = new Message();
+            copy.copyFrom(msg);
+            mMessages.add(copy);
+            return super.sendMessageAtTime(msg, uptimeMillis);
+        }
+    }
 }
\ No newline at end of file
