Merge "ShortcutManager: implement backup & restore" into nyc-dev
diff --git a/api/current.txt b/api/current.txt
index 67f4c1f..07a4f6d 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -71,6 +71,7 @@
     field public static final java.lang.String GET_ACCOUNTS = "android.permission.GET_ACCOUNTS";
     field public static final java.lang.String GET_ACCOUNTS_PRIVILEGED = "android.permission.GET_ACCOUNTS_PRIVILEGED";
     field public static final java.lang.String GET_PACKAGE_SIZE = "android.permission.GET_PACKAGE_SIZE";
+    field public static final java.lang.String GET_PASSWORD_PRIVILEGED = "android.permission.GET_PASSWORD_PRIVILEGED";
     field public static final deprecated java.lang.String GET_TASKS = "android.permission.GET_TASKS";
     field public static final java.lang.String GLOBAL_SEARCH = "android.permission.GLOBAL_SEARCH";
     field public static final java.lang.String INSTALL_LOCATION_PROVIDER = "android.permission.INSTALL_LOCATION_PROVIDER";
@@ -19811,7 +19812,7 @@
 
   public static abstract class AudioManager.AudioRecordingCallback {
     ctor public AudioManager.AudioRecordingCallback();
-    method public void onRecordConfigChanged(android.media.AudioRecordingConfiguration[]);
+    method public void onRecordingConfigChanged(android.media.AudioRecordingConfiguration[]);
   }
 
   public static abstract interface AudioManager.OnAudioFocusChangeListener {
diff --git a/api/system-current.txt b/api/system-current.txt
index 3ccd7e0..e1e73e9 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -103,6 +103,7 @@
     field public static final java.lang.String GET_APP_OPS_STATS = "android.permission.GET_APP_OPS_STATS";
     field public static final java.lang.String GET_PACKAGE_IMPORTANCE = "android.permission.GET_PACKAGE_IMPORTANCE";
     field public static final java.lang.String GET_PACKAGE_SIZE = "android.permission.GET_PACKAGE_SIZE";
+    field public static final java.lang.String GET_PASSWORD_PRIVILEGED = "android.permission.GET_PASSWORD_PRIVILEGED";
     field public static final java.lang.String GET_PROCESS_STATE_AND_OOM_SCORE = "android.permission.GET_PROCESS_STATE_AND_OOM_SCORE";
     field public static final deprecated java.lang.String GET_TASKS = "android.permission.GET_TASKS";
     field public static final java.lang.String GET_TOP_ACTIVITY_INFO = "android.permission.GET_TOP_ACTIVITY_INFO";
@@ -15270,7 +15271,6 @@
     ctor public ContextHubInfo();
     method public int describeContents();
     method public int getId();
-    method public int getMaxPacketLengthBytes();
     method public android.hardware.location.MemoryRegion[] getMemoryRegions();
     method public java.lang.String getName();
     method public float getPeakMips();
@@ -15298,6 +15298,10 @@
     method public int sendMessage(int, int, android.hardware.location.ContextHubMessage);
     method public int unloadNanoApp(int);
     method public int unregisterCallback(android.hardware.location.ContextHubManager.Callback);
+    field public static final int ANY_HUB = -1; // 0xffffffff
+    field public static final int MSG_DATA_SEND = 3; // 0x3
+    field public static final int MSG_LOAD_NANO_APP = 1; // 0x1
+    field public static final int MSG_UNLOAD_NANO_APP = 2; // 0x2
   }
 
   public static abstract class ContextHubManager.Callback {
@@ -15491,7 +15495,7 @@
   public class NanoAppInstanceInfo {
     ctor public NanoAppInstanceInfo();
     method public int describeContents();
-    method public long getAppId();
+    method public int getAppId();
     method public int getAppVersion();
     method public int getContexthubId();
     method public int getHandle();
@@ -15502,6 +15506,17 @@
     method public int getNeededWriteMemBytes();
     method public int[] getOutputEvents();
     method public java.lang.String getPublisher();
+    method public void setAppId(int);
+    method public void setAppVersion(int);
+    method public void setContexthubId(int);
+    method public void setHandle(int);
+    method public void setName(java.lang.String);
+    method public void setNeededExecMemBytes(int);
+    method public void setNeededReadMemBytes(int);
+    method public void setNeededSensors(int[]);
+    method public void setNeededWriteMemBytes(int);
+    method public void setOutputEvents(int[]);
+    method public void setPublisher(java.lang.String);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.hardware.location.NanoAppInstanceInfo> CREATOR;
   }
@@ -21287,7 +21302,7 @@
 
   public static abstract class AudioManager.AudioRecordingCallback {
     ctor public AudioManager.AudioRecordingCallback();
-    method public void onRecordConfigChanged(android.media.AudioRecordingConfiguration[]);
+    method public void onRecordingConfigChanged(android.media.AudioRecordingConfiguration[]);
   }
 
   public static abstract interface AudioManager.OnAudioFocusChangeListener {
diff --git a/api/test-current.txt b/api/test-current.txt
index 3be562d..09c55b9 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -71,6 +71,7 @@
     field public static final java.lang.String GET_ACCOUNTS = "android.permission.GET_ACCOUNTS";
     field public static final java.lang.String GET_ACCOUNTS_PRIVILEGED = "android.permission.GET_ACCOUNTS_PRIVILEGED";
     field public static final java.lang.String GET_PACKAGE_SIZE = "android.permission.GET_PACKAGE_SIZE";
+    field public static final java.lang.String GET_PASSWORD_PRIVILEGED = "android.permission.GET_PASSWORD_PRIVILEGED";
     field public static final deprecated java.lang.String GET_TASKS = "android.permission.GET_TASKS";
     field public static final java.lang.String GLOBAL_SEARCH = "android.permission.GLOBAL_SEARCH";
     field public static final java.lang.String INSTALL_LOCATION_PROVIDER = "android.permission.INSTALL_LOCATION_PROVIDER";
@@ -19876,7 +19877,7 @@
 
   public static abstract class AudioManager.AudioRecordingCallback {
     ctor public AudioManager.AudioRecordingCallback();
-    method public void onRecordConfigChanged(android.media.AudioRecordingConfiguration[]);
+    method public void onRecordingConfigChanged(android.media.AudioRecordingConfiguration[]);
   }
 
   public static abstract interface AudioManager.OnAudioFocusChangeListener {
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index e520b40..7465ed9 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -2798,6 +2798,15 @@
         if (account == null) {
             throw new IllegalArgumentException("account is null");
         }
+
+        // Always include the calling package name. This just makes life easier
+        // down stream.
+        final Bundle optionsIn = new Bundle();
+        if (options != null) {
+            optionsIn.putAll(options);
+        }
+        optionsIn.putString(KEY_ANDROID_PACKAGE_NAME, mContext.getPackageName());
+
         return new AmsTask(activity, handler, callback) {
             @Override
             public void doWork() throws RemoteException {
@@ -2806,7 +2815,7 @@
                         account,
                         authTokenType,
                         activity != null,
-                        options);
+                        optionsIn);
             }
         }.start();
     }
diff --git a/core/java/android/app/ActivityTransitionState.java b/core/java/android/app/ActivityTransitionState.java
index d3ca7ee..4a1aff7 100644
--- a/core/java/android/app/ActivityTransitionState.java
+++ b/core/java/android/app/ActivityTransitionState.java
@@ -239,9 +239,6 @@
     public void onResume(Activity activity, boolean isTopOfTask) {
         // After orientation change, the onResume can come in before the top Activity has
         // left, so if the Activity is not top, wait a second for the top Activity to exit.
-        if (mCalledExitCoordinator == null) {
-            return; // This is the called activity
-        }
         if (isTopOfTask || mEnterTransitionCoordinator == null) {
             restoreExitedViews();
             restoreReenteringViews();
diff --git a/core/java/android/app/AlarmManager.java b/core/java/android/app/AlarmManager.java
index cb2130c..e4fff9d 100644
--- a/core/java/android/app/AlarmManager.java
+++ b/core/java/android/app/AlarmManager.java
@@ -905,10 +905,12 @@
 
         ListenerWrapper wrapper = null;
         synchronized (AlarmManager.class) {
-            final WeakReference<ListenerWrapper> wrapperRef;
-            wrapperRef = sWrappers.get(listener);
-            if (wrapperRef != null) {
-                wrapper = wrapperRef.get();
+            if (sWrappers != null) {
+                final WeakReference<ListenerWrapper> wrapperRef;
+                wrapperRef = sWrappers.get(listener);
+                if (wrapperRef != null) {
+                    wrapper = wrapperRef.get();
+                }
             }
         }
 
diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java
index 54e2989..85a0403 100644
--- a/core/java/android/app/Dialog.java
+++ b/core/java/android/app/Dialog.java
@@ -16,6 +16,10 @@
 
 package android.app;
 
+import com.android.internal.R;
+import com.android.internal.app.WindowDecorActionBar;
+import com.android.internal.policy.PhoneWindow;
+
 import android.annotation.CallSuper;
 import android.annotation.DrawableRes;
 import android.annotation.IdRes;
@@ -56,12 +60,7 @@
 import android.view.WindowManager;
 import android.view.accessibility.AccessibilityEvent;
 
-import com.android.internal.R;
-import com.android.internal.app.WindowDecorActionBar;
-import com.android.internal.policy.PhoneWindow;
-
 import java.lang.ref.WeakReference;
-import java.util.List;
 
 /**
  * Base class for Dialogs.
@@ -93,11 +92,14 @@
         KeyEvent.Callback, OnCreateContextMenuListener, Window.OnWindowDismissedCallback {
     private static final String TAG = "Dialog";
     private Activity mOwnerActivity;
-    
+
+    private final WindowManager mWindowManager;
+
     final Context mContext;
-    final WindowManager mWindowManager;
-    Window mWindow;
+    final Window mWindow;
+
     View mDecor;
+
     private ActionBar mActionBar;
     /**
      * This field should be made private, so it is hidden from the SDK.
@@ -122,7 +124,7 @@
     private static final int CANCEL = 0x44;
     private static final int SHOW = 0x45;
 
-    private Handler mListenersHandler;
+    private final Handler mListenersHandler;
 
     private SearchEvent mSearchEvent;
 
@@ -130,11 +132,7 @@
 
     private int mActionModeTypeStarting = ActionMode.TYPE_PRIMARY;
 
-    private final Runnable mDismissAction = new Runnable() {
-        public void run() {
-            dismissDialog();
-        }
-    };
+    private final Runnable mDismissAction = this::dismissDialog;
 
     /**
      * Creates a dialog window that uses the default dialog theme.
@@ -197,14 +195,15 @@
      * @hide
      */
     @Deprecated
-    protected Dialog(@NonNull Context context, boolean cancelable, Message cancelCallback) {
+    protected Dialog(@NonNull Context context, boolean cancelable,
+            @Nullable Message cancelCallback) {
         this(context);
         mCancelable = cancelable;
         mCancelMessage = cancelCallback;
     }
 
     protected Dialog(@NonNull Context context, boolean cancelable,
-            OnCancelListener cancelListener) {
+            @Nullable OnCancelListener cancelListener) {
         this(context);
         mCancelable = cancelable;
         setOnCancelListener(cancelListener);
@@ -215,8 +214,7 @@
      * 
      * @return Context The Context used by the Dialog.
      */
-    @NonNull
-    public final Context getContext() {
+    public final @NonNull Context getContext() {
         return mContext;
     }
 
@@ -225,7 +223,7 @@
      *
      * @return The ActionBar attached to the dialog or null if no ActionBar is present.
      */
-    public ActionBar getActionBar() {
+    public @Nullable ActionBar getActionBar() {
         return mActionBar;
     }
 
@@ -235,7 +233,7 @@
      * 
      * @param activity The Activity that owns this dialog.
      */
-    public final void setOwnerActivity(Activity activity) {
+    public final void setOwnerActivity(@NonNull Activity activity) {
         mOwnerActivity = activity;
         
         getWindow().setVolumeControlStream(mOwnerActivity.getVolumeControlStream());
@@ -249,7 +247,7 @@
      * 
      * @return The Activity that owns this Dialog.
      */
-    public final Activity getOwnerActivity() {
+    public final @Nullable Activity getOwnerActivity() {
         return mOwnerActivity;
     }
     
@@ -315,13 +313,10 @@
             l = nl;
         }
 
-        try {
-            mWindowManager.addView(mDecor, l);
-            mShowing = true;
-    
-            sendShowMessage();
-        } finally {
-        }
+        mWindowManager.addView(mDecor, l);
+        mShowing = true;
+
+        sendShowMessage();
     }
     
     /**
@@ -387,7 +382,7 @@
         }
     }
 
-    // internal method to make sure mcreated is set properly without requiring
+    // internal method to make sure mCreated is set properly without requiring
     // users to call through to super in onCreate
     void dispatchOnCreate(Bundle savedInstanceState) {
         if (!mCreated) {
@@ -399,7 +394,7 @@
     /**
      * Similar to {@link Activity#onCreate}, you should initialize your dialog
      * in this method, including calling {@link #setContentView}.
-     * @param savedInstanceState If this dialog is being reinitalized after a
+     * @param savedInstanceState If this dialog is being reinitialized after a
      *     the hosting activity was previously shut down, holds the result from
      *     the most recent call to {@link #onSaveInstanceState}, or null if this
      *     is the first time.
@@ -432,7 +427,7 @@
      * state.
      * @return A bundle with the state of the dialog.
      */
-    public Bundle onSaveInstanceState() {
+    public @NonNull Bundle onSaveInstanceState() {
         Bundle bundle = new Bundle();
         bundle.putBoolean(DIALOG_SHOWING_TAG, mShowing);
         if (mCreated) {
@@ -451,7 +446,7 @@
      * @param savedInstanceState The state of the dialog previously saved by
      *     {@link #onSaveInstanceState()}.
      */
-    public void onRestoreInstanceState(Bundle savedInstanceState) {
+    public void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
         final Bundle dialogHierarchyState = savedInstanceState.getBundle(DIALOG_HIERARCHY_TAG);
         if (dialogHierarchyState == null) {
             // dialog has never been shown, or onCreated, nothing to restore.
@@ -472,7 +467,7 @@
      * @return Window The current window, or null if the activity is not
      *         visual.
      */
-    public Window getWindow() {
+    public @Nullable Window getWindow() {
         return mWindow;
     }
 
@@ -485,7 +480,7 @@
      * @see #getWindow
      * @see android.view.Window#getCurrentFocus
      */
-    public View getCurrentFocus() {
+    public @Nullable View getCurrentFocus() {
         return mWindow != null ? mWindow.getCurrentFocus() : null;
     }
 
@@ -497,8 +492,7 @@
      * @param id the identifier of the view to find
      * @return The view with the given id or null.
      */
-    @Nullable
-    public View findViewById(@IdRes int id) {
+    public @Nullable View findViewById(@IdRes int id) {
         return mWindow.findViewById(id);
     }
 
@@ -519,19 +513,19 @@
      * 
      * @param view The desired content to display.
      */
-    public void setContentView(View view) {
+    public void setContentView(@NonNull View view) {
         mWindow.setContentView(view);
     }
 
     /**
      * Set the screen content to an explicit view.  This view is placed
      * directly into the screen's view hierarchy.  It can itself be a complex
-     * view hierarhcy.
+     * view hierarchy.
      * 
      * @param view The desired content to display.
      * @param params Layout parameters for the view.
      */
-    public void setContentView(View view, ViewGroup.LayoutParams params) {
+    public void setContentView(@NonNull View view, @Nullable ViewGroup.LayoutParams params) {
         mWindow.setContentView(view, params);
     }
 
@@ -542,7 +536,7 @@
      * @param view The desired content to display.
      * @param params Layout parameters for the view.
      */
-    public void addContentView(View view, ViewGroup.LayoutParams params) {
+    public void addContentView(@NonNull View view, @Nullable ViewGroup.LayoutParams params) {
         mWindow.addContentView(view, params);
     }
 
@@ -551,7 +545,7 @@
      * 
      * @param title The new text to display in the title.
      */
-    public void setTitle(CharSequence title) {
+    public void setTitle(@Nullable CharSequence title) {
         mWindow.setTitle(title);
         mWindow.getAttributes().setTitle(title);
     }
@@ -577,7 +571,8 @@
      * @see #onKeyUp
      * @see android.view.KeyEvent
      */
-    public boolean onKeyDown(int keyCode, KeyEvent event) {
+    @Override
+    public boolean onKeyDown(int keyCode, @NonNull KeyEvent event) {
         if (keyCode == KeyEvent.KEYCODE_BACK) {
             event.startTracking();
             return true;
@@ -591,7 +586,8 @@
      * KeyEvent.Callback.onKeyLongPress()}: always returns false (doesn't handle
      * the event).
      */
-    public boolean onKeyLongPress(int keyCode, KeyEvent event) {
+    @Override
+    public boolean onKeyLongPress(int keyCode, @NonNull KeyEvent event) {
         return false;
     }
 
@@ -604,7 +600,8 @@
      * @see #onKeyDown
      * @see KeyEvent
      */
-    public boolean onKeyUp(int keyCode, KeyEvent event) {
+    @Override
+    public boolean onKeyUp(int keyCode, @NonNull KeyEvent event) {
         if (keyCode == KeyEvent.KEYCODE_BACK && event.isTracking()
                 && !event.isCanceled()) {
             onBackPressed();
@@ -618,7 +615,8 @@
      * KeyEvent.Callback.onKeyMultiple()}: always returns false (doesn't handle
      * the event).
      */
-    public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) {
+    @Override
+    public boolean onKeyMultiple(int keyCode, int repeatCount, @NonNull KeyEvent event) {
         return false;
     }
     
@@ -643,7 +641,7 @@
      * @param event Description of the key event.
      * @return True if the key shortcut was handled.
      */
-    public boolean onKeyShortcut(int keyCode, KeyEvent event) {
+    public boolean onKeyShortcut(int keyCode, @NonNull KeyEvent event) {
         return false;
     }
 
@@ -657,7 +655,7 @@
      *         The default implementation will cancel the dialog when a touch
      *         happens outside of the window bounds.
      */
-    public boolean onTouchEvent(MotionEvent event) {
+    public boolean onTouchEvent(@NonNull MotionEvent event) {
         if (mCancelable && mShowing && mWindow.shouldCloseOnTouch(mContext, event)) {
             cancel();
             return true;
@@ -680,7 +678,7 @@
      * @return Return true if you have consumed the event, false if you haven't.
      * The default implementation always returns false.
      */
-    public boolean onTrackballEvent(MotionEvent event) {
+    public boolean onTrackballEvent(@NonNull MotionEvent event) {
         return false;
     }
 
@@ -709,25 +707,30 @@
      * @return Return true if you have consumed the event, false if you haven't.
      * The default implementation always returns false.
      */
-    public boolean onGenericMotionEvent(MotionEvent event) {
+    public boolean onGenericMotionEvent(@NonNull MotionEvent event) {
         return false;
     }
 
+    @Override
     public void onWindowAttributesChanged(WindowManager.LayoutParams params) {
         if (mDecor != null) {
             mWindowManager.updateViewLayout(mDecor, params);
         }
     }
 
+    @Override
     public void onContentChanged() {
     }
 
+    @Override
     public void onWindowFocusChanged(boolean hasFocus) {
     }
 
+    @Override
     public void onAttachedToWindow() {
     }
 
+    @Override
     public void onDetachedFromWindow() {
     }
 
@@ -746,7 +749,8 @@
      *
      * @return boolean Return true if this event was consumed.
      */
-    public boolean dispatchKeyEvent(KeyEvent event) {
+    @Override
+    public boolean dispatchKeyEvent(@NonNull KeyEvent event) {
         if ((mOnKeyListener != null) && (mOnKeyListener.onKey(this, event.getKeyCode(), event))) {
             return true;
         }
@@ -766,7 +770,8 @@
      * @param event The key shortcut event.
      * @return True if this event was consumed.
      */
-    public boolean dispatchKeyShortcutEvent(KeyEvent event) {
+    @Override
+    public boolean dispatchKeyShortcutEvent(@NonNull KeyEvent event) {
         if (mWindow.superDispatchKeyShortcutEvent(event)) {
             return true;
         }
@@ -783,7 +788,8 @@
      * 
      * @return boolean Return true if this event was consumed.
      */
-    public boolean dispatchTouchEvent(MotionEvent ev) {
+    @Override
+    public boolean dispatchTouchEvent(@NonNull MotionEvent ev) {
         if (mWindow.superDispatchTouchEvent(ev)) {
             return true;
         }
@@ -800,7 +806,8 @@
      * 
      * @return boolean Return true if this event was consumed.
      */
-    public boolean dispatchTrackballEvent(MotionEvent ev) {
+    @Override
+    public boolean dispatchTrackballEvent(@NonNull MotionEvent ev) {
         if (mWindow.superDispatchTrackballEvent(ev)) {
             return true;
         }
@@ -817,14 +824,16 @@
      *
      * @return boolean Return true if this event was consumed.
      */
-    public boolean dispatchGenericMotionEvent(MotionEvent ev) {
+    @Override
+    public boolean dispatchGenericMotionEvent(@NonNull MotionEvent ev) {
         if (mWindow.superDispatchGenericMotionEvent(ev)) {
             return true;
         }
         return onGenericMotionEvent(ev);
     }
 
-    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+    @Override
+    public boolean dispatchPopulateAccessibilityEvent(@NonNull AccessibilityEvent event) {
         event.setClassName(getClass().getName());
         event.setPackageName(mContext.getPackageName());
 
@@ -839,6 +848,7 @@
     /**
      * @see Activity#onCreatePanelView(int)
      */
+    @Override
     public View onCreatePanelView(int featureId) {
         return null;
     }
@@ -846,7 +856,8 @@
     /**
      * @see Activity#onCreatePanelMenu(int, Menu)
      */
-    public boolean onCreatePanelMenu(int featureId, Menu menu) {
+    @Override
+    public boolean onCreatePanelMenu(int featureId, @NonNull Menu menu) {
         if (featureId == Window.FEATURE_OPTIONS_PANEL) {
             return onCreateOptionsMenu(menu);
         }
@@ -857,10 +868,10 @@
     /**
      * @see Activity#onPreparePanel(int, View, Menu)
      */
+    @Override
     public boolean onPreparePanel(int featureId, View view, Menu menu) {
         if (featureId == Window.FEATURE_OPTIONS_PANEL && menu != null) {
-            boolean goforit = onPrepareOptionsMenu(menu);
-            return goforit && menu.hasVisibleItems();
+            return onPrepareOptionsMenu(menu) && menu.hasVisibleItems();
         }
         return true;
     }
@@ -868,6 +879,7 @@
     /**
      * @see Activity#onMenuOpened(int, Menu)
      */
+    @Override
     public boolean onMenuOpened(int featureId, Menu menu) {
         if (featureId == Window.FEATURE_ACTION_BAR) {
             mActionBar.dispatchMenuVisibilityChanged(true);
@@ -878,6 +890,7 @@
     /**
      * @see Activity#onMenuItemSelected(int, MenuItem)
      */
+    @Override
     public boolean onMenuItemSelected(int featureId, MenuItem item) {
         return false;
     }
@@ -885,6 +898,7 @@
     /**
      * @see Activity#onPanelClosed(int, Menu)
      */
+    @Override
     public void onPanelClosed(int featureId, Menu menu) {
         if (featureId == Window.FEATURE_ACTION_BAR) {
             mActionBar.dispatchMenuVisibilityChanged(false);
@@ -899,7 +913,7 @@
      * @see Activity#onCreateOptionsMenu(Menu)
      * @see #getOwnerActivity()
      */
-    public boolean onCreateOptionsMenu(Menu menu) {
+    public boolean onCreateOptionsMenu(@NonNull Menu menu) {
         return true;
     }
 
@@ -911,21 +925,21 @@
      * @see Activity#onPrepareOptionsMenu(Menu)
      * @see #getOwnerActivity()
      */
-    public boolean onPrepareOptionsMenu(Menu menu) {
+    public boolean onPrepareOptionsMenu(@NonNull Menu menu) {
         return true;
     }
 
     /**
      * @see Activity#onOptionsItemSelected(MenuItem)
      */
-    public boolean onOptionsItemSelected(MenuItem item) {
+    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
         return false;
     }
 
     /**
      * @see Activity#onOptionsMenuClosed(Menu)
      */
-    public void onOptionsMenuClosed(Menu menu) {
+    public void onOptionsMenuClosed(@NonNull Menu menu) {
     }
 
     /**
@@ -958,47 +972,49 @@
     /**
      * @see Activity#onCreateContextMenu(ContextMenu, View, ContextMenuInfo)
      */
+    @Override
     public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
     }
 
     /**
      * @see Activity#registerForContextMenu(View)
      */
-    public void registerForContextMenu(View view) {
+    public void registerForContextMenu(@NonNull View view) {
         view.setOnCreateContextMenuListener(this);
     }
     
     /**
      * @see Activity#unregisterForContextMenu(View)
      */
-    public void unregisterForContextMenu(View view) {
+    public void unregisterForContextMenu(@NonNull View view) {
         view.setOnCreateContextMenuListener(null);
     }
     
     /**
      * @see Activity#openContextMenu(View)
      */
-    public void openContextMenu(View view) {
+    public void openContextMenu(@NonNull View view) {
         view.showContextMenu();
     }
 
     /**
      * @see Activity#onContextItemSelected(MenuItem)
      */
-    public boolean onContextItemSelected(MenuItem item) {
+    public boolean onContextItemSelected(@NonNull MenuItem item) {
         return false;
     }
 
     /**
      * @see Activity#onContextMenuClosed(Menu)
      */
-    public void onContextMenuClosed(Menu menu) {
+    public void onContextMenuClosed(@NonNull Menu menu) {
     }
 
     /**
      * This hook is called when the user signals the desire to start a search.
      */
-    public boolean onSearchRequested(SearchEvent searchEvent) {
+    @Override
+    public boolean onSearchRequested(@NonNull SearchEvent searchEvent) {
         mSearchEvent = searchEvent;
         return onSearchRequested();
     }
@@ -1006,6 +1022,7 @@
     /**
      * This hook is called when the user signals the desire to start a search.
      */
+    @Override
     public boolean onSearchRequested() {
         final SearchManager searchManager = (SearchManager) mContext
                 .getSystemService(Context.SEARCH_SERVICE);
@@ -1028,13 +1045,10 @@
      * @return SearchEvent The SearchEvent that triggered the {@link
      *                    #onSearchRequested} callback.
      */
-    public final SearchEvent getSearchEvent() {
+    public final @Nullable SearchEvent getSearchEvent() {
         return mSearchEvent;
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     public ActionMode onWindowStartingActionMode(ActionMode.Callback callback) {
         if (mActionBar != null && mActionModeTypeStarting == ActionMode.TYPE_PRIMARY) {
@@ -1043,9 +1057,6 @@
         return null;
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     public ActionMode onWindowStartingActionMode(ActionMode.Callback callback, int type) {
         try {
@@ -1062,6 +1073,7 @@
      * Note that if you override this method you should always call through
      * to the superclass implementation by calling super.onActionModeStarted(mode).
      */
+    @Override
     @CallSuper
     public void onActionModeStarted(ActionMode mode) {
         mActionMode = mode;
@@ -1073,6 +1085,7 @@
      * Note that if you override this method you should always call through
      * to the superclass implementation by calling super.onActionModeFinished(mode).
      */
+    @Override
     @CallSuper
     public void onActionModeFinished(ActionMode mode) {
         if (mode == mActionMode) {
@@ -1138,7 +1151,7 @@
      * Convenience for calling
      * {@link android.view.Window#setFeatureDrawableUri}.
      */
-    public final void setFeatureDrawableUri(int featureId, Uri uri) {
+    public final void setFeatureDrawableUri(int featureId, @Nullable Uri uri) {
         getWindow().setFeatureDrawableUri(featureId, uri);
     }
 
@@ -1146,7 +1159,7 @@
      * Convenience for calling
      * {@link android.view.Window#setFeatureDrawable(int, Drawable)}.
      */
-    public final void setFeatureDrawable(int featureId, Drawable drawable) {
+    public final void setFeatureDrawable(int featureId, @Nullable Drawable drawable) {
         getWindow().setFeatureDrawable(featureId, drawable);
     }
 
@@ -1158,7 +1171,7 @@
         getWindow().setFeatureDrawableAlpha(featureId, alpha);
     }
 
-    public LayoutInflater getLayoutInflater() {
+    public @NonNull LayoutInflater getLayoutInflater() {
         return getWindow().getLayoutInflater();
     }
 
@@ -1190,6 +1203,7 @@
      * Cancel the dialog.  This is essentially the same as calling {@link #dismiss()}, but it will
      * also call your {@link DialogInterface.OnCancelListener} (if registered).
      */
+    @Override
     public void cancel() {
         if (!mCanceled && mCancelMessage != null) {
             mCanceled = true;
@@ -1210,7 +1224,7 @@
      * 
      * @param listener The {@link DialogInterface.OnCancelListener} to use.
      */
-    public void setOnCancelListener(final OnCancelListener listener) {
+    public void setOnCancelListener(@Nullable OnCancelListener listener) {
         if (mCancelAndDismissTaken != null) {
             throw new IllegalStateException(
                     "OnCancelListener is already taken by "
@@ -1228,7 +1242,7 @@
      * @param msg The msg to send when the dialog is canceled.
      * @see #setOnCancelListener(android.content.DialogInterface.OnCancelListener)
      */
-    public void setCancelMessage(final Message msg) {
+    public void setCancelMessage(@Nullable Message msg) {
         mCancelMessage = msg;
     }
 
@@ -1236,7 +1250,7 @@
      * Set a listener to be invoked when the dialog is dismissed.
      * @param listener The {@link DialogInterface.OnDismissListener} to use.
      */
-    public void setOnDismissListener(final OnDismissListener listener) {
+    public void setOnDismissListener(@Nullable OnDismissListener listener) {
         if (mCancelAndDismissTaken != null) {
             throw new IllegalStateException(
                     "OnDismissListener is already taken by "
@@ -1253,7 +1267,7 @@
      * Sets a listener to be invoked when the dialog is shown.
      * @param listener The {@link DialogInterface.OnShowListener} to use.
      */
-    public void setOnShowListener(OnShowListener listener) {
+    public void setOnShowListener(@Nullable OnShowListener listener) {
         if (listener != null) {
             mShowMessage = mListenersHandler.obtainMessage(SHOW, listener);
         } else {
@@ -1265,13 +1279,13 @@
      * Set a message to be sent when the dialog is dismissed.
      * @param msg The msg to send when the dialog is dismissed.
      */
-    public void setDismissMessage(final Message msg) {
+    public void setDismissMessage(@Nullable Message msg) {
         mDismissMessage = msg;
     }
 
     /** @hide */
-    public boolean takeCancelAndDismissListeners(String msg, final OnCancelListener cancel,
-            final OnDismissListener dismiss) {
+    public boolean takeCancelAndDismissListeners(@Nullable String msg,
+            @Nullable OnCancelListener cancel, @Nullable OnDismissListener dismiss) {
         if (mCancelAndDismissTaken != null) {
             mCancelAndDismissTaken = null;
         } else if (mCancelMessage != null || mDismissMessage != null) {
@@ -1305,15 +1319,15 @@
     /**
      * Sets the callback that will be called if a key is dispatched to the dialog.
      */
-    public void setOnKeyListener(final OnKeyListener onKeyListener) {
+    public void setOnKeyListener(@Nullable OnKeyListener onKeyListener) {
         mOnKeyListener = onKeyListener;
     }
 
     private static final class ListenersHandler extends Handler {
-        private WeakReference<DialogInterface> mDialog;
+        private final WeakReference<DialogInterface> mDialog;
 
         public ListenersHandler(Dialog dialog) {
-            mDialog = new WeakReference<DialogInterface>(dialog);
+            mDialog = new WeakReference<>(dialog);
         }
 
         @Override
diff --git a/core/java/android/bluetooth/BluetoothManager.java b/core/java/android/bluetooth/BluetoothManager.java
index e355a1c..35437a1 100644
--- a/core/java/android/bluetooth/BluetoothManager.java
+++ b/core/java/android/bluetooth/BluetoothManager.java
@@ -144,7 +144,7 @@
     }
 
     /**
-     * 
+     *
      * Get a list of devices that match any of the given connection
      * states.
      *
diff --git a/core/java/android/hardware/location/ContextHubInfo.java b/core/java/android/hardware/location/ContextHubInfo.java
index ae44f1d..644e29f 100644
--- a/core/java/android/hardware/location/ContextHubInfo.java
+++ b/core/java/android/hardware/location/ContextHubInfo.java
@@ -37,7 +37,6 @@
     private float mStoppedPowerDrawMw;
     private float mSleepPowerDrawMw;
     private float mPeakPowerDrawMw;
-    private int mMaxPacketLengthBytes;
 
     private int[] mSupportedSensors;
 
@@ -47,27 +46,6 @@
     }
 
     /**
-     * returns the maximum number of bytes that can be sent per message to the hub
-     *
-     * @return int - maximum bytes that can be transmitted in a
-     *         single packet
-     */
-    public int getMaxPacketLengthBytes() {
-        return mMaxPacketLengthBytes;
-    }
-
-    /**
-     * set the context hub unique identifer
-     *
-     * @param bytes - Maximum number of bytes per message
-     *
-     * @hide
-     */
-    public void setMaxPacketLenBytes(int bytes) {
-        mMaxPacketLengthBytes = bytes;
-    }
-
-    /**
      * get the context hub unique identifer
      *
      * @return int - unique system wide identifier
@@ -396,4 +374,4 @@
             return new ContextHubInfo[size];
         }
     };
-}
\ No newline at end of file
+}
diff --git a/core/java/android/hardware/location/ContextHubManager.java b/core/java/android/hardware/location/ContextHubManager.java
index 89edaa9..4ddf767 100644
--- a/core/java/android/hardware/location/ContextHubManager.java
+++ b/core/java/android/hardware/location/ContextHubManager.java
@@ -43,6 +43,23 @@
     private Handler mCallbackHandler;
 
     /**
+     * A special context hub identifier meaning any possible hub on the system.
+     */
+    public static final int ANY_HUB       = -1;
+    /**
+     * A constant denoting a message to load a a Nano App
+     */
+    public static final int MSG_LOAD_NANO_APP   = 1;
+    /**
+     * A constant denoting a message to unload a a Nano App
+     */
+    public static final int MSG_UNLOAD_NANO_APP = 2;
+    /**
+     * A constant denoting a message to send a message
+     */
+    public static final int MSG_DATA_SEND       = 3;
+
+    /**
      * An interface to receive asynchronous communication from the context hub.
      */
     public abstract static class Callback {
@@ -52,7 +69,7 @@
          * Callback function called on message receipt from context hub.
          *
          * @param hubHandle Handle (system-wide unique identifier) of the hub of the message.
-         * @param nanoAppHandle Handle (unique identifier) for app instance that sent the message.
+         * @param nanoAppHandle Handle (unique identifier) for the app that sent the message.
          * @param message The context hub message.
          *
          * @see ContextHubMessage
@@ -72,7 +89,7 @@
         try {
             retVal = getBinder().getContextHubHandles();
         } catch (RemoteException e) {
-            Log.w(TAG, "Could not fetch context hub handles : " + e);
+            Log.e(TAG, "Could not fetch context hub handles : " + e);
         }
         return retVal;
     }
@@ -90,7 +107,7 @@
         try {
             retVal = getBinder().getContextHubInfo(hubHandle);
         } catch (RemoteException e) {
-            Log.w(TAG, "Could not fetch context hub info :" + e);
+            Log.e(TAG, "Could not fetch context hub info :" + e);
         }
 
         return retVal;
@@ -109,7 +126,6 @@
      */
     public int loadNanoApp(int hubHandle, NanoApp app) {
         int retVal = -1;
-
         if (app == null) {
             return retVal;
         }
@@ -117,7 +133,7 @@
         try {
             retVal = getBinder().loadNanoApp(hubHandle, app);
         } catch (RemoteException e) {
-            Log.w(TAG, "Could not load nanoApp :" + e);
+            Log.e(TAG, "Could not fetch load nanoApp :" + e);
         }
 
         return retVal;
@@ -136,7 +152,7 @@
         try {
             retVal = getBinder().unloadNanoApp(nanoAppHandle);
         } catch (RemoteException e) {
-            Log.w(TAG, "Could not fetch unload nanoApp :" + e);
+            Log.e(TAG, "Could not fetch unload nanoApp :" + e);
         }
 
         return retVal;
@@ -156,7 +172,7 @@
         try {
             retVal = getBinder().getNanoAppInstanceInfo(nanoAppHandle);
         } catch (RemoteException e) {
-            Log.w(TAG, "Could not fetch nanoApp info :" + e);
+            Log.e(TAG, "Could not fetch nanoApp info :" + e);
         }
 
         return retVal;
@@ -177,7 +193,7 @@
         try {
             retVal = getBinder().findNanoAppOnHub(hubHandle, filter);
         } catch (RemoteException e) {
-            Log.w(TAG, "Could not query nanoApp instance :" + e);
+            Log.e(TAG, "Could not query nanoApp instance :" + e);
         }
         return retVal;
     }
@@ -196,14 +212,10 @@
     public int sendMessage(int hubHandle, int nanoAppHandle, ContextHubMessage message) {
         int retVal = -1;
 
-        if (message == null || message.getData() == null) {
-            Log.w(TAG, "null ptr");
-            return retVal;
-        }
         try {
             retVal = getBinder().sendMessage(hubHandle, nanoAppHandle, message);
         } catch (RemoteException e) {
-            Log.w(TAG, "Could not send message :" + e.toString());
+            Log.e(TAG, "Could not fetch send message :" + e.toString());
         }
 
         return retVal;
@@ -235,7 +247,7 @@
     public int registerCallback(Callback callback, Handler handler) {
         synchronized(this) {
             if (mCallback != null) {
-                Log.w(TAG, "Max number of callbacks reached!");
+                Log.e(TAG, "Max number of callbacks reached!");
                 return -1;
             }
             mCallback = callback;
@@ -256,7 +268,7 @@
     public int unregisterCallback(Callback callback) {
       synchronized(this) {
           if (callback != mCallback) {
-              Log.w(TAG, "Cannot recognize callback!");
+              Log.e(TAG, "Cannot recognize callback!");
               return -1;
           }
 
@@ -299,11 +311,11 @@
             try {
                 getBinder().registerCallback(mClientCallback);
             } catch (RemoteException e) {
-                Log.w(TAG, "Could not register callback:" + e);
+                Log.e(TAG, "Could not register callback:" + e);
             }
 
         } else {
-            Log.w(TAG, "failed to getService");
+            Log.d(TAG, "failed to getService");
         }
     }
 
diff --git a/core/java/android/hardware/location/ContextHubMessage.java b/core/java/android/hardware/location/ContextHubMessage.java
index bca2ae6..954e97d 100644
--- a/core/java/android/hardware/location/ContextHubMessage.java
+++ b/core/java/android/hardware/location/ContextHubMessage.java
@@ -16,10 +16,10 @@
 
 package android.hardware.location;
 
+
 import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.util.Log;
 
 import java.util.Arrays;
 
@@ -32,9 +32,6 @@
     private int mVersion;
     private byte[]mData;
 
-    private static final String TAG = "ContextHubMessage";
-
-
     /**
      * Get the message type
      *
@@ -109,11 +106,9 @@
     private ContextHubMessage(Parcel in) {
         mType = in.readInt();
         mVersion = in.readInt();
-        int bufferLength = in.readInt();
-        mData = new byte[bufferLength];
-        in.readByteArray(mData);
+        byte[] byteBuffer = new byte[in.readInt()];
+        in.readByteArray(byteBuffer);
     }
-
     public void writeToParcel(Parcel out, int flags) {
         out.writeInt(mType);
         out.writeInt(mVersion);
diff --git a/core/java/android/hardware/location/ContextHubService.java b/core/java/android/hardware/location/ContextHubService.java
index b65e24e..274babe 100644
--- a/core/java/android/hardware/location/ContextHubService.java
+++ b/core/java/android/hardware/location/ContextHubService.java
@@ -29,30 +29,12 @@
  */
 public class ContextHubService extends IContextHubService.Stub {
 
-    public static final String CONTEXTHUB_SERVICE = "contexthub_service";
-
     private static final String TAG = "ContextHubService";
     private static final String HARDWARE_PERMISSION = Manifest.permission.LOCATION_HARDWARE;
     private static final String ENFORCE_HW_PERMISSION_MESSAGE = "Permission '"
             + HARDWARE_PERMISSION + "' not granted to access ContextHub Hardware";
 
-
-    public static final int ANY_HUB             = -1;
-    public static final int MSG_LOAD_NANO_APP   = 5;
-    public static final int MSG_UNLOAD_NANO_APP = 2;
-
-    private static final String PRE_LOADED_GENERIC_UNKNOWN = "Preloaded app, unknown";
-    private static final String PRE_LOADED_APP_NAME = PRE_LOADED_GENERIC_UNKNOWN;
-    private static final String PRE_LOADED_APP_PUBLISHER = PRE_LOADED_GENERIC_UNKNOWN;
-    private static final int PRE_LOADED_APP_MEM_REQ = 0;
-
-    private static final int MSG_HEADER_SIZE = 4;
-    private static final int MSG_FIELD_TYPE = 0;
-    private static final int MSG_FIELD_VERSION = 1;
-    private static final int MSG_FIELD_HUB_HANDLE = 2;
-    private static final int MSG_FIELD_APP_INSTANCE = 3;
-
-    private static final int OS_APP_INSTANCE = -1;
+    public static final String CONTEXTHUB_SERVICE = "contexthub_service";
 
     private final Context mContext;
 
@@ -60,27 +42,44 @@
     private ContextHubInfo[] mContextHubInfo;
     private IContextHubCallback mCallback;
 
-    private native int nativeSendMessage(int[] header, byte[] data);
-    private native ContextHubInfo[] nativeInitialize();
-
-
     public ContextHubService(Context context) {
         mContext = context;
         mContextHubInfo = nativeInitialize();
-        mNanoAppHash = new HashMap<Integer, NanoAppInstanceInfo>();
 
         for (int i = 0; i < mContextHubInfo.length; i++) {
-            Log.d(TAG, "ContextHub[" + i + "] id: " + mContextHubInfo[i].getId()
+            Log.v(TAG, "ContextHub[" + i + "] id: " + mContextHubInfo[i].getId()
                   + ", name:  " + mContextHubInfo[i].getName());
         }
     }
 
+    private native int nativeSendMessage(int[] header, byte[] data);
+    private native ContextHubInfo[] nativeInitialize();
+
     @Override
-    public int registerCallback(IContextHubCallback callback) throws RemoteException {
+    public int registerCallback(IContextHubCallback callback) throws RemoteException{
         checkPermissions();
-        synchronized(this) {
-          mCallback = callback;
+        mCallback = callback;
+        return 0;
+    }
+
+
+    private int onMessageReceipt(int[] header, byte[] data) {
+        if (mCallback != null) {
+            // TODO : Defend against unexpected header sizes
+            //        Add abstraction for magic numbers
+            //        onMessageRecipt should pass the right arguments
+            ContextHubMessage msg = new ContextHubMessage(header[0], header[1], data);
+
+            try {
+                mCallback.onMessageReceipt(0, 0, msg);
+            } catch (Exception e) {
+                Log.e(TAG, "Exception " + e + " when calling remote callback");
+                return -1;
+            }
+        } else {
+            Log.d(TAG, "Message Callback is NULL");
         }
+
         return 0;
     }
 
@@ -119,17 +118,14 @@
         }
 
         // Call Native interface here
-        int[] msgHeader = new int[MSG_HEADER_SIZE];
-        msgHeader[MSG_FIELD_HUB_HANDLE] = contextHubHandle;
-        msgHeader[MSG_FIELD_APP_INSTANCE] = OS_APP_INSTANCE;
-        msgHeader[MSG_FIELD_VERSION] = 0;
-        msgHeader[MSG_FIELD_TYPE] = MSG_LOAD_NANO_APP;
+        int[] msgHeader = new int[8];
+        msgHeader[0] = contextHubHandle;
+        msgHeader[1] = app.getAppId();
+        msgHeader[2] = app.getAppVersion();
+        msgHeader[3] = ContextHubManager.MSG_LOAD_NANO_APP;
+        msgHeader[4] = 0; // Loading hints
 
-        if (nativeSendMessage(msgHeader, app.getAppBinary()) != 0) {
-            return -1;
-        }
-        // Do not add an entry to mNanoAppInstance Hash yet. The HAL may reject the app
-        return 0;
+        return nativeSendMessage(msgHeader, app.getAppBinary());
     }
 
     @Override
@@ -141,18 +137,12 @@
         }
 
         // Call Native interface here
-        int[] msgHeader = new int[MSG_HEADER_SIZE];
-        msgHeader[MSG_FIELD_HUB_HANDLE] = ANY_HUB;
-        msgHeader[MSG_FIELD_APP_INSTANCE] = OS_APP_INSTANCE;
-        msgHeader[MSG_FIELD_VERSION] = 0;
-        msgHeader[MSG_FIELD_TYPE] = MSG_UNLOAD_NANO_APP;
+        int[] msgHeader = new int[8];
+        msgHeader[0] = info.getContexthubId();
+        msgHeader[1] = ContextHubManager.MSG_UNLOAD_NANO_APP;
+        msgHeader[2] = info.getHandle();
 
-        if(nativeSendMessage(msgHeader, null) != 0) {
-            return -1;
-        }
-
-        // Do not add an entry to mNanoAppInstance Hash yet. The HAL may reject the app
-        return 0;
+        return nativeSendMessage(msgHeader, null);
     }
 
     @Override
@@ -176,7 +166,7 @@
         for(Integer nanoAppInstance : mNanoAppHash.keySet()) {
             NanoAppInstanceInfo info = mNanoAppHash.get(nanoAppInstance);
 
-            if (filter.testMatch(info)){
+            if(filter.testMatch(info)){
                 foundInstances.add(nanoAppInstance);
             }
         }
@@ -193,12 +183,12 @@
     public int sendMessage(int hubHandle, int nanoAppHandle, ContextHubMessage msg)
             throws RemoteException {
         checkPermissions();
-
-        int[] msgHeader = new int[MSG_HEADER_SIZE];
-        msgHeader[MSG_FIELD_HUB_HANDLE] = hubHandle;
-        msgHeader[MSG_FIELD_APP_INSTANCE] = nanoAppHandle;
-        msgHeader[MSG_FIELD_VERSION] = msg.getVersion();
-        msgHeader[MSG_FIELD_TYPE] = msg.getMsgType();
+        int[] msgHeader = new int[8];
+        msgHeader[0] = ContextHubManager.MSG_DATA_SEND;
+        msgHeader[1] = hubHandle;
+        msgHeader[2] = nanoAppHandle;
+        msgHeader[3] = msg.getMsgType();
+        msgHeader[4] = msg.getVersion();
 
         return nativeSendMessage(msgHeader, msg.getData());
     }
@@ -206,52 +196,5 @@
     private void checkPermissions() {
         mContext.enforceCallingPermission(HARDWARE_PERMISSION, ENFORCE_HW_PERMISSION_MESSAGE);
     }
-
-    private int onMessageReceipt(int[] header, byte[] data) {
-        if (header == null || data == null || header.length < MSG_HEADER_SIZE) {
-            return  -1;
-        }
-
-        synchronized(this) {
-            if (mCallback != null) {
-                ContextHubMessage msg = new ContextHubMessage(header[MSG_FIELD_TYPE],
-                        header[MSG_FIELD_VERSION],
-                        data);
-
-                try {
-                    mCallback.onMessageReceipt(header[MSG_FIELD_HUB_HANDLE],
-                            header[MSG_FIELD_APP_INSTANCE],
-                            msg);
-                } catch (Exception e) {
-                    Log.w(TAG, "Exception " + e + " when calling remote callback");
-                    return -1;
-                }
-            } else {
-                Log.d(TAG, "Message Callback is NULL");
-            }
-        }
-
-        return 0;
-    }
-
-    private int addAppInstance(int hubHandle, int appInstanceHandle, long appId, int appVersion) {
-        // App Id encodes vendor & version
-        NanoAppInstanceInfo appInfo = new NanoAppInstanceInfo();
-
-        appInfo.setAppId(appId);
-        appInfo.setAppVersion(appVersion);
-        appInfo.setName(PRE_LOADED_APP_NAME);
-        appInfo.setContexthubId(hubHandle);
-        appInfo.setHandle(appInstanceHandle);
-        appInfo.setPublisher(PRE_LOADED_APP_PUBLISHER);
-        appInfo.setNeededExecMemBytes(PRE_LOADED_APP_MEM_REQ);
-        appInfo.setNeededReadMemBytes(PRE_LOADED_APP_MEM_REQ);
-        appInfo.setNeededWriteMemBytes(PRE_LOADED_APP_MEM_REQ);
-
-        mNanoAppHash.put(appInstanceHandle, appInfo);
-        Log.d(TAG, "Added app instance " + appInstanceHandle + " with id " + appId
-              + " version " + appVersion);
-
-        return 0;
-    }
 }
+
diff --git a/core/java/android/hardware/location/NanoAppFilter.java b/core/java/android/hardware/location/NanoAppFilter.java
index 8db70e9..369f9e4 100644
--- a/core/java/android/hardware/location/NanoAppFilter.java
+++ b/core/java/android/hardware/location/NanoAppFilter.java
@@ -20,7 +20,6 @@
 import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.util.Log;
 
 /**
  * @hide
@@ -28,8 +27,6 @@
 @SystemApi
 public class NanoAppFilter {
 
-    private static final String TAG = "NanoAppFilter";
-
     // The appId, can be set to APP_ID_ANY
     private long mAppId;
 
@@ -57,10 +54,6 @@
      * If this flag is set, only versions strictly less than the version specified shall match.
      */
     public static final int FLAGS_VERSION_LESS_THAN   = 4;
-    /**
-     * If this flag is set, only versions strictly equal to the
-     * version specified shall match.
-     */
     public static final int FLAGS_VERSION_STRICTLY_EQUAL = 8;
 
     /**
@@ -124,9 +117,14 @@
      * @return true if this is a match, false otherwise
      */
     public boolean testMatch(NanoAppInstanceInfo info) {
-        return (mContextHubId == HUB_ANY || info.getContexthubId() == mContextHubId) &&
+        if ((mContextHubId == HUB_ANY || info.getContexthubId() == mContextHubId) &&
                 (mAppId == APP_ANY || info.getAppId() == mAppId) &&
-                (versionsMatch(mVersionRestrictionMask, mAppVersion, info.getAppVersion()));
+               // (mAppIdVendorMask == VENDOR_ANY) TODO : Expose Vendor mask cleanly
+                (versionsMatch(mVersionRestrictionMask, mAppVersion, info.getAppVersion()))) {
+            return true;
+        } else {
+            return false;
+        }
     }
 
     public static final Parcelable.Creator<NanoAppFilter> CREATOR
diff --git a/core/java/android/hardware/location/NanoAppInstanceInfo.java b/core/java/android/hardware/location/NanoAppInstanceInfo.java
index 977f645..ac62919 100644
--- a/core/java/android/hardware/location/NanoAppInstanceInfo.java
+++ b/core/java/android/hardware/location/NanoAppInstanceInfo.java
@@ -29,7 +29,7 @@
     private String mPublisher;
     private String mName;
 
-    private long mAppId;
+    private int mAppId;
     private int mAppVersion;
 
     private int mNeededReadMemBytes;
@@ -59,8 +59,6 @@
      * set the publisher name for the app
      *
      * @param publisher - name of the publisher
-     *
-     * @hide
      */
     public void setPublisher(String publisher) {
         mPublisher = publisher;
@@ -79,8 +77,6 @@
      * set the name of the app
      *
      * @param name - name of the app
-     *
-     * @hide
      */
     public void setName(String name) {
         mName = name;
@@ -91,7 +87,7 @@
      *
      * @return int - application identifier
      */
-    public long getAppId() {
+    public int getAppId() {
         return mAppId;
     }
 
@@ -99,10 +95,8 @@
      * Set the application identifier
      *
      * @param appId - application identifier
-     *
-     * @hide
      */
-    public void setAppId(long appId) {
+    public void setAppId(int appId) {
         mAppId = appId;
     }
 
@@ -119,8 +113,6 @@
      * Set the application version
      *
      * @param appVersion - version of the app
-     *
-     * @hide
      */
     public void setAppVersion(int appVersion) {
         mAppVersion = appVersion;
@@ -139,8 +131,6 @@
      * Set the read memory needed by the app
      *
      * @param neededReadMemBytes - readable Memory needed in bytes
-     *
-     * @hide
      */
     public void setNeededReadMemBytes(int neededReadMemBytes) {
         mNeededReadMemBytes = neededReadMemBytes;
@@ -160,8 +150,6 @@
      *
      * @param neededWriteMemBytes - writable memory needed by the
      *                            app
-     *
-     * @hide
      */
     public void setNeededWriteMemBytes(int neededWriteMemBytes) {
         mNeededWriteMemBytes = neededWriteMemBytes;
@@ -181,8 +169,6 @@
      *
      * @param neededExecMemBytes - executable memory needed by the
      *                           app
-     *
-     * @hide
      */
     public void setNeededExecMemBytes(int neededExecMemBytes) {
         mNeededExecMemBytes = neededExecMemBytes;
@@ -201,8 +187,6 @@
      * set the sensors needed by this app
      *
      * @param neededSensors - all the sensors needed by this app
-     *
-     * @hide
      */
     public void setNeededSensors(int[] neededSensors) {
         mNeededSensors = neededSensors;
@@ -222,8 +206,6 @@
      *
      * @param outputEvents - the events that may be generated by
      *                     this app
-     *
-     * @hide
      */
     public void setOutputEvents(int[] outputEvents) {
         mOutputEvents = outputEvents;
@@ -242,8 +224,6 @@
      * set the context hub identifier
      *
      * @param contexthubId - system wide unique identifier
-     *
-     * @hide
      */
     public void setContexthubId(int contexthubId) {
         mContexthubId = contexthubId;
@@ -262,8 +242,6 @@
      * set the handle for an app instance
      *
      * @param handle - handle to this instance
-     *
-     * @hide
      */
     public void setHandle(int handle) {
         mHandle = handle;
@@ -274,7 +252,7 @@
         mPublisher = in.readString();
         mName = in.readString();
 
-        mAppId = in.readLong();
+        mAppId = in.readInt();
         mAppVersion = in.readInt();
         mNeededReadMemBytes = in.readInt();
         mNeededWriteMemBytes = in.readInt();
@@ -296,7 +274,7 @@
     public void writeToParcel(Parcel out, int flags) {
         out.writeString(mPublisher);
         out.writeString(mName);
-        out.writeLong(mAppId);
+        out.writeInt(mAppId);
         out.writeInt(mAppVersion);
         out.writeInt(mContexthubId);
         out.writeInt(mNeededReadMemBytes);
@@ -308,6 +286,7 @@
 
         out.writeInt(mOutputEvents.length);
         out.writeIntArray(mOutputEvents);
+
     }
 
     public static final Parcelable.Creator<NanoAppInstanceInfo> CREATOR
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 5bcf102..4ba97d5 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -180,7 +180,12 @@
     // caller must call setNewConfiguration() sometime later.
     Configuration updateOrientationFromAppTokens(in Configuration currentConfig,
             IBinder freezeThisOneIfNeeded);
-    void setNewConfiguration(in Configuration config);
+    // Notify window manager of the new configuration. Returns an array of stack ids that's
+    // affected by the update, ActivityManager should resize these stacks.
+    int[] setNewConfiguration(in Configuration config);
+
+    // Retrieves the new bounds after the configuration update evaluated by window manager.
+    Rect getBoundsForNewConfiguration(int stackId);
 
     void startFreezingScreen(int exitAnim, int enterAnim);
     void stopFreezingScreen();
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 8bd63df..6d2cea6 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -17,6 +17,7 @@
 package android.widget;
 
 import android.annotation.ColorInt;
+import android.app.ActivityManager.StackId;
 import android.app.ActivityOptions;
 import android.app.ActivityThread;
 import android.app.Application;
@@ -228,6 +229,11 @@
 
         public boolean onClickHandler(View view, PendingIntent pendingIntent,
                 Intent fillInIntent) {
+            return onClickHandler(view, pendingIntent, fillInIntent, StackId.INVALID_STACK_ID);
+        }
+
+        public boolean onClickHandler(View view, PendingIntent pendingIntent,
+                Intent fillInIntent, int launchStackId) {
             try {
                 // TODO: Unregister this handler if PendingIntent.FLAG_ONE_SHOT?
                 Context context = view.getContext();
@@ -239,6 +245,10 @@
                             0, 0,
                             view.getMeasuredWidth(), view.getMeasuredHeight());
                 }
+
+                if (launchStackId != StackId.INVALID_STACK_ID) {
+                    opts.setLaunchStackId(launchStackId);
+                }
                 context.startIntentSender(
                         pendingIntent.getIntentSender(), fillInIntent,
                         Intent.FLAG_ACTIVITY_NEW_TASK,
diff --git a/core/java/com/android/internal/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java
index ee73b90..bed5a2e 100644
--- a/core/java/com/android/internal/util/ArrayUtils.java
+++ b/core/java/com/android/internal/util/ArrayUtils.java
@@ -238,6 +238,14 @@
         return total;
     }
 
+    public static int[] convertToIntArray(List<Integer> list) {
+        int[] array = new int[list.size()];
+        for (int i = 0; i < list.size(); i++) {
+            array[i] = list.get(i);
+        }
+        return array;
+    }
+
     /**
      * Adds value to given array if not already present, providing set-like
      * behavior.
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 9d14478..3d892af 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -1099,7 +1099,8 @@
                 || mode == DevicePolicyManager.PASSWORD_QUALITY_NUMERIC
                 || mode == DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX
                 || mode == DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC
-                || mode == DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
+                || mode == DevicePolicyManager.PASSWORD_QUALITY_COMPLEX
+                || mode == DevicePolicyManager.PASSWORD_QUALITY_MANAGED;
         return passwordEnabled && savedPasswordExists(userId);
     }
 
diff --git a/core/jni/android_hardware_location_ContextHubService.cpp b/core/jni/android_hardware_location_ContextHubService.cpp
index d05f82e..8724729 100644
--- a/core/jni/android_hardware_location_ContextHubService.cpp
+++ b/core/jni/android_hardware_location_ContextHubService.cpp
@@ -16,39 +16,23 @@
 
 #include "context_hub.h"
 
-#define LOG_NDEBUG 0
-#define LOG_TAG "ContextHubService"
-
-#include <inttypes.h>
-#include <jni.h>
-#include <map>
-#include <queue>
 #include <string.h>
 #include <stdint.h>
 #include <stdio.h>
-#include <stdlib.h>
 
-#include <cutils/log.h>
-
+#include <jni.h>
 #include "JNIHelp.h"
 #include "core_jni_helpers.h"
-
-static constexpr int OS_APP_ID=-1;
-
-static constexpr int MIN_APP_ID=1;
-static constexpr int MAX_APP_ID=128;
-
-static constexpr size_t MSG_HEADER_SIZE=4;
-static constexpr int HEADER_FIELD_MSG_TYPE=0;
-static constexpr int HEADER_FIELD_MSG_VERSION=1;
-static constexpr int HEADER_FIELD_HUB_HANDLE=2;
-static constexpr int HEADER_FIELD_APP_INSTANCE=3;
+#include "stdint.h"
+#include "stdlib.h"
 
 
 namespace android {
 
 namespace {
 
+// TODO: We should share this array_length function widely around Android
+//     code.
 /*
  * Finds the length of a statically-sized array using template trickery that
  * also prevents it from being applied to the wrong type.
@@ -80,207 +64,35 @@
     jmethodID contextHubInfoSetPeakPowerDrawMw;
     jmethodID contextHubInfoSetSupportedSensors;
     jmethodID contextHubInfoSetMemoryRegions;
-    jmethodID contextHubInfoSetMaxPacketLenBytes;
 
     jmethodID contextHubServiceMsgReceiptCallback;
-    jmethodID contextHubServiceAddAppInstance;
 };
 
 struct context_hub_info_s {
-    uint32_t *cookies;
+    int cookie;
     int numHubs;
     const struct context_hub_t *hubs;
     struct context_hub_module_t *contextHubModule;
 };
 
-struct app_instance_info_s {
-    uint32_t hubHandle; // Id of the hub this app is on
-    int instanceId; // systemwide unique instance id - assigned
-    struct hub_app_info appInfo; // returned from the HAL
-    uint64_t truncName; // Possibly truncated name - logging
-};
-
 struct contextHubServiceDb_s {
     int initialized;
     context_hub_info_s hubInfo;
     jniInfo_s jniInfo;
-    std::queue<int> freeIds;
-    std::map<int, app_instance_info_s *> appInstances;
 };
 
 }  // unnamed namespace
 
 static contextHubServiceDb_s db;
 
-int context_hub_callback(uint32_t hubId, const struct hub_message_t *msg,
+int context_hub_callback(uint32_t hub_id, const struct hub_message_t *msg,
                          void *cookie);
 
-const context_hub_t *get_hub_info(int hubHandle) {
-    if (hubHandle >= 0 && hubHandle < db.hubInfo.numHubs) {
-        return &db.hubInfo.hubs[hubHandle];
-    }
-    return nullptr;
-}
-
-static int send_msg_to_hub(const hub_message_t *msg, int hubHandle) {
-    const context_hub_t *info = get_hub_info(hubHandle);
-
-    if (info) {
-        return db.hubInfo.contextHubModule->send_message(info->hub_id, msg);
-    } else {
-        ALOGD("%s: Hub information is null for hubHandle %d", __FUNCTION__, hubHandle);
-        return -1;
-    }
-}
-
-static int set_os_app_as_destination(hub_message_t *msg, int hubHandle) {
-    const context_hub_t *info = get_hub_info(hubHandle);
-
-    if (info) {
-        msg->app = info->os_app_name;
-        return 0;
-    } else {
-        ALOGD("%s: Hub information is null for hubHandle %d", __FUNCTION__, hubHandle);
-        return -1;
-    }
-}
-
-static int get_hub_id_for_app_instance(int id) {
-    if (db.appInstances.find(id) == db.appInstances.end()) {
-        ALOGD("%s: Cannot find app for app instance %d", __FUNCTION__, id);
-        return -1;
-    }
-
-    int hubHandle = db.appInstances[id]->hubHandle;
-
-    return db.hubInfo.hubs[hubHandle].hub_id;
-}
-
-static int set_dest_app(hub_message_t *msg, int id) {
-    if (db.appInstances.find(id) == db.appInstances.end()) {
-        ALOGD("%s: Cannod find app for app instance %d", __FUNCTION__, id);
-        return -1;
-    }
-
-    msg->app = db.appInstances[id]->appInfo.name;
-    return 0;
-}
-
-static void send_query_for_apps() {
-    hub_message_t msg;
-
-    msg.message_type = CONTEXT_HUB_QUERY_APPS;
-    msg.message_len  = 0;
-
-    for (int i = 0; i < db.hubInfo.numHubs; i++ ) {
-        ALOGD("Sending query for apps to hub %d", i);
-        set_os_app_as_destination(&msg, i);
-        if (send_msg_to_hub(&msg, i) != 0) {
-          ALOGW("Could not query hub %i for apps", i);
-        }
-    }
-}
-
-static int return_id(int id) {
-    // Note : This method is not thread safe.
-    // id returned is guarenteed to be in use
-    db.freeIds.push(id);
-    return 0;
-}
-
-static int generate_id(void) {
-    // Note : This method is not thread safe.
-    int retVal = -1;
-
-    if (!db.freeIds.empty()) {
-        retVal = db.freeIds.front();
-        db.freeIds.pop();
-    }
-
-    return retVal;
-}
-
-int add_app_instance(const hub_app_info *appInfo, uint32_t hubHandle, JNIEnv *env) {
-    // Not checking if the apps are indeed distinct
-
-    app_instance_info_s *entry;
-    void *appName;
-    hub_app_name_t *name;
-
-    assert(appInfo && appInfo->name && appInfo->name->app_name);
-
-    entry = (app_instance_info_s *) malloc(sizeof(app_instance_info_s));
-    appName = malloc(appInfo->name->app_name_len);
-    name = (hub_app_name_t *) malloc(sizeof(hub_app_name_t));
-
-    int appInstanceHandle = generate_id();
-
-    if (appInstanceHandle < 0 || !appName || !entry || !name) {
-        ALOGE("Cannot find resources to add app instance %d, %p, %p",
-            appInstanceHandle, appName, entry);
-
-        free(appName);
-        free(entry);
-        free(name);
-
-        if (appInstanceHandle >= 0) {
-            return_id(appInstanceHandle);
-        }
-
-        return -1;
-    }
-
-    memcpy(&(entry->appInfo), appInfo, sizeof(entry->appInfo));
-    memcpy(appName, appInfo->name->app_name, appInfo->name->app_name_len);
-    name->app_name = appName;
-    name->app_name_len = appInfo->name->app_name_len;
-    entry->appInfo.name = name;
-    entry->truncName = 0;
-    memcpy(&(entry->truncName), name->app_name,
-           sizeof(entry->truncName) < name->app_name_len ?
-           sizeof(entry->truncName) : name->app_name_len);
-
-    // Not checking for sanity of hubId
-    entry->hubHandle = hubHandle;
-    entry->instanceId = appInstanceHandle;
-    db.appInstances[appInstanceHandle] = entry;
-
-    // Finally - let the service know of this app instance
-    env->CallIntMethod(db.jniInfo.jContextHubService,
-                       db.jniInfo.contextHubServiceAddAppInstance,
-                       hubHandle, entry->instanceId, entry->truncName,
-                       entry->appInfo.version);
-
-    ALOGW("Added App 0x%" PRIx64 " on hub Handle %" PRId32
-          " as appInstance %d, original name_length %" PRId32, entry->truncName,
-          entry->hubHandle, appInstanceHandle, name->app_name_len);
-
-    return appInstanceHandle;
-}
-
-int delete_app_instance(int id) {
-    if (db.appInstances.find(id) == db.appInstances.end()) {
-        return -1;
-    }
-
-    return_id(id);
-
-    if (db.appInstances[id]) {
-        // Losing the const cast below. This is intentional.
-        free((void *)db.appInstances[id]->appInfo.name->app_name);
-        free((void *)db.appInstances[id]->appInfo.name);
-        free(db.appInstances[id]);
-        db.appInstances.erase(id);
-    }
-
-    return 0;
-}
-
-
 static void initContextHubService() {
     int err = 0;
-    db.hubInfo.hubs = nullptr;
+    db.hubInfo.hubs = NULL;
     db.hubInfo.numHubs = 0;
+    db.hubInfo.cookie = 0;
     int i;
 
     err = hw_get_module(CONTEXT_HUB_MODULE_ID,
@@ -291,45 +103,26 @@
             strerror(-err));
     }
 
-    // Prep for storing app info
-    for(i = MIN_APP_ID; i <= MAX_APP_ID; i++) {
-        db.freeIds.push(i);
-    }
-
     if (db.hubInfo.contextHubModule) {
-        int retNumHubs = db.hubInfo.contextHubModule->get_hubs(db.hubInfo.contextHubModule,
+      ALOGD("Fetching hub info");
+      db.hubInfo.numHubs = db.hubInfo.contextHubModule->get_hubs(db.hubInfo.contextHubModule,
                                                                  &db.hubInfo.hubs);
-        ALOGD("ContextHubModule returned %d hubs ", retNumHubs);
-        db.hubInfo.numHubs = retNumHubs;
 
-        if (db.hubInfo.numHubs > 0) {
-            db.hubInfo.numHubs = retNumHubs;
-            db.hubInfo.cookies = (uint32_t *)malloc(sizeof(uint32_t) * db.hubInfo.numHubs);
-
-            if (!db.hubInfo.cookies) {
-                ALOGW("Ran out of memory allocating cookies, bailing");
-                return;
-            }
-
-            for (i = 0; i < db.hubInfo.numHubs; i++) {
-                db.hubInfo.cookies[i] = db.hubInfo.hubs[i].hub_id;
-                if (db.hubInfo.contextHubModule->subscribe_messages(db.hubInfo.hubs[i].hub_id,
-                                                                    context_hub_callback,
-                                                                    &db.hubInfo.cookies[i]) == 0) {
-                }
-            }
+      if (db.hubInfo.numHubs > 0) {
+        for (i = 0; i < db.hubInfo.numHubs; i++) {
+          // TODO : Event though one cookie is OK for now, lets change
+          // this to be one per hub
+          db.hubInfo.contextHubModule->subscribe_messages(db.hubInfo.hubs[i].hub_id,
+                                                          context_hub_callback,
+                                                          &db.hubInfo.cookie);
         }
-
-        send_query_for_apps();
-    } else {
-        ALOGW("No Context Hub Module present");
+      }
     }
 }
 
 static int onMessageReceipt(int *header, int headerLen, char *msg, int msgLen) {
     JNIEnv *env;
-
-    if ((db.jniInfo.vm)->AttachCurrentThread(&env, nullptr) != JNI_OK) {
+    if ((db.jniInfo.vm)->AttachCurrentThread(&env, NULL) != JNI_OK) {
       return -1;
     }
 
@@ -339,130 +132,28 @@
     env->SetByteArrayRegion(jmsg, 0, msgLen, (jbyte *)msg);
     env->SetIntArrayRegion(jheader, 0, headerLen, (jint *)header);
 
-    return (env->CallIntMethod(db.jniInfo.jContextHubService,
+
+    return env->CallIntMethod(db.jniInfo.jContextHubService,
                           db.jniInfo.contextHubServiceMsgReceiptCallback,
-                          jheader, jmsg) != 0);
+                          jheader, jmsg);
 }
 
-int handle_query_apps_response(char *msg, int msgLen, uint32_t hubHandle) {
-    int i;
-    JNIEnv *env;
-    if ((db.jniInfo.vm)->AttachCurrentThread(&env, nullptr) != JNI_OK) {
-            return -1;
-    }
-
-    int numApps = msgLen/sizeof(hub_app_info);
-    hub_app_info *info = (hub_app_info *)malloc(msgLen); // handle possible alignment
-
-    if (!info) {
-        return -1;
-    }
-
-    memcpy(info, msg, msgLen);
-    for (i = 0; i < numApps; i++) {
-        add_app_instance(&info[i], hubHandle, env);
-    }
-
-    free(info);
-
-    return 0;
-}
-
-
-int handle_os_message(uint32_t msgType, uint32_t hubHandle,
-                      char *msg, int msgLen) {
-    int retVal;
-
-    switch(msgType) {
-        case CONTEXT_HUB_APPS_ENABLE:
-            retVal = 0;
-            break;
-
-        case CONTEXT_HUB_APPS_DISABLE:
-            retVal = 0;
-            break;
-
-        case CONTEXT_HUB_LOAD_APP:
-            retVal = 0;
-            break;
-
-        case CONTEXT_HUB_UNLOAD_APP:
-            retVal = 0;
-            break;
-
-        case CONTEXT_HUB_QUERY_APPS:
-            retVal = handle_query_apps_response(msg, msgLen, hubHandle);
-            break;
-
-        case CONTEXT_HUB_QUERY_MEMORY:
-            retVal = 0;
-            break;
-
-        case CONTEXT_HUB_LOAD_OS:
-            retVal = 0;
-            break;
-
-        default:
-            retVal = -1;
-            break;
-
-    }
-
-    return retVal;
-}
-
-static bool sanity_check_cookie(void *cookie, uint32_t hub_id) {
-    int *ptr = (int *)cookie;
-
-    if (!ptr || *ptr >= db.hubInfo.numHubs) {
-        return false;
-    }
-
-    if (db.hubInfo.hubs[*ptr].hub_id != hub_id) {
-        return false;
-    } else {
-        return true;
-    }
-}
-
-int context_hub_callback(uint32_t hubId,
-                         const struct hub_message_t *msg,
+int context_hub_callback(uint32_t hub_id, const struct hub_message_t *msg,
                          void *cookie) {
-    int msgHeader[MSG_HEADER_SIZE];
+  int msgHeader[4];
 
-    if (!msg) {
-        return -1;
-    }
+  msgHeader[0] = msg->message_type;
+  msgHeader[1] = 0; // TODO : HAL does not have a version field
+  msgHeader[2] = hub_id;
 
-    msgHeader[HEADER_FIELD_MSG_TYPE] = msg->message_type;
-
-    if (!sanity_check_cookie(cookie, hubId)) {
-        ALOGW("Incorrect cookie %" PRId32 " for cookie %p! Bailing",
-              hubId, cookie);
-
-        return -1;
-    }
-
-    msgHeader[HEADER_FIELD_HUB_HANDLE] = *(uint32_t*)cookie;
-
-    if (msgHeader[HEADER_FIELD_MSG_TYPE] < CONTEXT_HUB_TYPE_PRIVATE_MSG_BASE &&
-        msgHeader[HEADER_FIELD_MSG_TYPE] != 0 ) {
-        handle_os_message(msgHeader[HEADER_FIELD_MSG_TYPE],
-                          msgHeader[HEADER_FIELD_HUB_HANDLE],
-                          (char *)msg->message,
-                          msg->message_len);
-    } else {
-        onMessageReceipt(msgHeader, sizeof(msgHeader),
-                         (char *)msg->message, msg->message_len);
-    }
-
-    return 0;
+  onMessageReceipt(msgHeader, sizeof(msgHeader), (char *)msg->message, msg->message_len); // TODO : Populate this
+  return 0;
 }
 
 static int init_jni(JNIEnv *env, jobject instance) {
 
     if (env->GetJavaVM(&db.jniInfo.vm) != JNI_OK) {
-        return -1;
+      return -1;
     }
 
     db.jniInfo.jContextHubService = env->NewGlobalRef(instance);
@@ -476,6 +167,7 @@
     db.jniInfo.memoryRegionsClass =
             env->FindClass("android/hardware/location/MemoryRegion");
 
+    //TODO :: Add error checking
     db.jniInfo.contextHubInfoCtor =
             env->GetMethodID(db.jniInfo.contextHubInfoClass, "<init>", "()V");
     db.jniInfo.contextHubInfoSetId =
@@ -517,9 +209,6 @@
     db.jniInfo.contextHubInfoSetMemoryRegions =
             env->GetMethodID(db.jniInfo.contextHubInfoClass,
                                 "setMemoryRegions", "([Landroid/hardware/location/MemoryRegion;)V");
-    db.jniInfo.contextHubInfoSetMaxPacketLenBytes =
-             env->GetMethodID(db.jniInfo.contextHubInfoClass,
-                                "setMaxPacketLenBytes", "(I)V");
 
 
     db.jniInfo.contextHubServiceMsgReceiptCallback =
@@ -529,11 +218,6 @@
             env->GetMethodID(db.jniInfo.contextHubInfoClass, "setName",
             "(Ljava/lang/String;)V");
 
-    db.jniInfo.contextHubServiceAddAppInstance =
-                 env->GetMethodID(db.jniInfo.contextHubServiceClass,
-                                    "addAppInstance", "(IIJI)I");
-
-
 
     return 0;
 }
@@ -561,28 +245,20 @@
     env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetPlatformVersion, hub->platform_version);
     env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetToolchainVersion, hub->toolchain_version);
     env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetPeakMips, hub->peak_mips);
-    env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetStoppedPowerDrawMw,
-                        hub->stopped_power_draw_mw);
-    env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetSleepPowerDrawMw,
-                        hub->sleep_power_draw_mw);
-    env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetPeakPowerDrawMw,
-                        hub->peak_power_draw_mw);
-    env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetMaxPacketLenBytes,
-                        hub->max_supported_msg_len);
-
+    env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetStoppedPowerDrawMw, hub->stopped_power_draw_mw);
+    env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetSleepPowerDrawMw, hub->sleep_power_draw_mw);
+    env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetPeakPowerDrawMw, hub->peak_power_draw_mw);
 
     // TODO : jintBuf = env->NewIntArray(hub->num_connected_sensors);
-    // TODO : env->SetIntArrayRegion(jintBuf, 0, hub->num_connected_sensors,
-    //                               hub->connected_sensors);
+    // TODO : env->SetIntArrayRegion(jintBuf, 0, hub->num_connected_sensors, hub->connected_sensors);
     jintBuf = env->NewIntArray(array_length(dummyConnectedSensors));
     env->SetIntArrayRegion(jintBuf, 0, hub->num_connected_sensors, dummyConnectedSensors);
 
     // We are not getting the memory regions from the CH Hal - change this when it is available
-    jmemBuf = env->NewObjectArray(0, db.jniInfo.memoryRegionsClass, nullptr);
+    jmemBuf = env->NewObjectArray(0, db.jniInfo.memoryRegionsClass, NULL);
     // Note the zero size above. We do not need to set any elements
     env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetMemoryRegions, jmemBuf);
 
-
     return jHub;
 }
 
@@ -591,18 +267,18 @@
     jobject hub;
     jobjectArray retArray;
 
+    initContextHubService();
+
     if (init_jni(env, instance) < 0) {
-        return nullptr;
+        return NULL;
     }
 
+    // Note : The service is clamping the number of hubs to 1
+    db.hubInfo.numHubs = 1;
+
     initContextHubService();
 
-    if (db.hubInfo.numHubs > 1) {
-      ALOGW("Clamping the number of hubs to 1");
-      db.hubInfo.numHubs = 1;
-    }
-
-    retArray = env->NewObjectArray(db.hubInfo.numHubs, db.jniInfo.contextHubInfoClass, nullptr);
+    retArray = env->NewObjectArray(db.hubInfo.numHubs, db.jniInfo.contextHubInfoClass, NULL);
 
     for(int i = 0; i < db.hubInfo.numHubs; i++) {
         hub = constructJContextHubInfo(env, &db.hubInfo.hubs[i]);
@@ -615,27 +291,28 @@
 static jint nativeSendMessage(JNIEnv *env, jobject instance, jintArray header_,
                               jbyteArray data_) {
     hub_message_t msg;
-    jint retVal = -1; // Default to failure
+    hub_app_name_t dest;
+    uint8_t os_name[8];
+
+    memset(os_name, 0, sizeof(os_name));
 
     jint *header = env->GetIntArrayElements(header_, 0);
-    unsigned int numHeaderElements = env->GetArrayLength(header_);
+    //int numHeaderElements = env->GetArrayLength(header_);
     jbyte *data = env->GetByteArrayElements(data_, 0);
     int dataBufferLength = env->GetArrayLength(data_);
 
-    if (numHeaderElements >= MSG_HEADER_SIZE) {
-        if (set_dest_app(&msg, header[HEADER_FIELD_APP_INSTANCE]) == 0) {
-          msg.message_type = header[HEADER_FIELD_MSG_TYPE];
-          msg.message_len = dataBufferLength;
-          msg.message = data;
-          retVal = db.hubInfo.contextHubModule->send_message(
-                  get_hub_id_for_app_instance(header[HEADER_FIELD_APP_INSTANCE]),
-                  &msg);
-        } else {
-          ALOGD("Could not find app instance %d", header[HEADER_FIELD_APP_INSTANCE]);
-        }
-    } else {
-        ALOGD("Malformed header len");
-    }
+    /* Assume an int - thats all we understand */
+    dest.app_name_len = array_length(os_name); // TODO : Check this
+    //dest.app_name = &header[1];
+    dest.app_name = os_name;
+
+    msg.app = &dest;
+
+    msg.message_type = header[3];
+    msg.message_len = dataBufferLength;
+    msg.message = data;
+
+    jint retVal = db.hubInfo.contextHubModule->send_message(header[0], &msg);
 
     env->ReleaseIntArrayElements(header_, header, 0);
     env->ReleaseByteArrayElements(data_, data, 0);
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index e03183b..30a5993 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -845,14 +845,14 @@
     -->
     <permission android:name="android.permission.ACCESS_UCE_PRESENCE_SERVICE"
         android:permissionGroup="android.permission-group.PHONE"
-        android:protectionLevel="dangerous"/>
+        android:protectionLevel="signatureOrSystem"/>
 
     <!-- @hide Allows an application to Access UCE-OPTIONS.
          <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.ACCESS_UCE_OPTIONS_SERVICE"
         android:permissionGroup="android.permission-group.PHONE"
-        android:protectionLevel="dangerous"/>
+        android:protectionLevel="signatureOrSystem"/>
 
 
 
@@ -2004,6 +2004,11 @@
     <permission android:name="android.permission.GET_ACCOUNTS_PRIVILEGED"
         android:protectionLevel="signature|privileged" />
 
+    <!-- @SystemApi Allows but does not guarantee access to user passwords at the conclusion of add
+         account -->
+    <permission android:name="android.permission.GET_PASSWORD_PRIVILEGED"
+        android:protectionLevel="signature|privileged" />
+
     <!-- @SystemApi Allows applications to RW to diagnostic resources.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.DIAGNOSTIC"
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 0a8c692..00eff91 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -2157,7 +2157,7 @@
                                 final RecordConfigChangeCallbackData cbData =
                                         (RecordConfigChangeCallbackData) msg.obj;
                                 if (cbData.mCb != null) {
-                                    cbData.mCb.onRecordConfigChanged(cbData.mConfigs);
+                                    cbData.mCb.onRecordingConfigChanged(cbData.mConfigs);
                                 }
                                 break;
                             default:
@@ -2746,7 +2746,7 @@
          * @param configs array containing the results of
          *      {@link AudioManager#getActiveRecordingConfigurations()}.
          */
-        public void onRecordConfigChanged(AudioRecordingConfiguration[] configs) {}
+        public void onRecordingConfigChanged(AudioRecordingConfiguration[] configs) {}
     }
 
     private static class AudioRecordingCallbackInfo {
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index b6ff41e..0ea4ec5 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -596,14 +596,14 @@
      * AudioTrack player = new AudioTrack.Builder()
      *         .setAudioAttributes(new AudioAttributes.Builder()
      *                  .setUsage(AudioAttributes.USAGE_ALARM)
-     *                  .setContentType(CONTENT_TYPE_MUSIC)
+     *                  .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
      *                  .build())
      *         .setAudioFormat(new AudioFormat.Builder()
      *                 .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
      *                 .setSampleRate(441000)
      *                 .setChannelMask(AudioFormat.CHANNEL_OUT_STEREO)
      *                 .build())
-     *         .setBufferSize(minBuffSize)
+     *         .setBufferSizeInBytes(minBuffSize)
      *         .build();
      * </pre>
      * <p>
diff --git a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
index 9606eab54..87136ef3 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
@@ -636,10 +636,12 @@
                 return true;
             }
         } else if (keyCode == KeyEvent.KEYCODE_TAB) {
+            Metrics.logKeyboardAction(this, keyCode);
             // Tab toggles focus on the navigation drawer.
             toggleNavDrawerFocus();
             return true;
         } else if (keyCode == KeyEvent.KEYCODE_DEL) {
+            Metrics.logKeyboardAction(this, keyCode);
             popDir();
             return true;
         }
diff --git a/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java b/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
index e7d7ec4..d4439d8 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
@@ -349,18 +349,21 @@
             case KeyEvent.KEYCODE_A:
                 dir = getDirectoryFragment();
                 if (dir != null) {
+                    Metrics.logKeyboardAction(this, keyCode);
                     dir.selectAllFiles();
                 }
                 return true;
             case KeyEvent.KEYCODE_C:
                 dir = getDirectoryFragment();
                 if (dir != null) {
+                    Metrics.logKeyboardAction(this, keyCode);
                     dir.copySelectedToClipboard();
                 }
                 return true;
             case KeyEvent.KEYCODE_V:
                 dir = getDirectoryFragment();
                 if (dir != null) {
+                    Metrics.logKeyboardAction(this, keyCode);
                     dir.pasteFromClipboard();
                 }
                 return true;
diff --git a/packages/DocumentsUI/src/com/android/documentsui/Metrics.java b/packages/DocumentsUI/src/com/android/documentsui/Metrics.java
index 1e01c22..a4a67f9 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/Metrics.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/Metrics.java
@@ -29,6 +29,7 @@
 import android.net.Uri;
 import android.provider.DocumentsContract;
 import android.util.Log;
+import android.view.KeyEvent;
 
 import com.android.documentsui.State.ActionType;
 import com.android.documentsui.model.DocumentInfo;
@@ -70,6 +71,7 @@
     private static final String COUNT_DRAG_N_DROP = "docsui_drag_n_drop";
     private static final String COUNT_SEARCH = "docsui_search";
     private static final String COUNT_MENU_ACTION = "docsui_menu_action";
+    private static final String COUNT_KEYBOARD_ACTION = "docsui_keyboard_action";
 
     // Indices for bucketing roots in the roots histogram. "Other" is the catch-all index for any
     // root that is not explicitly recognized by the Metrics code (see {@link
@@ -289,6 +291,31 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface MetricsAction {}
 
+    // Codes representing different keyboard shortcut triggered actions. These are used for
+    // bucketing stats in the COUNT_KEYBOARD_ACTION histogram.
+    // Do not change or rearrange these values, that will break historical data. Only add to the
+    // list.
+    // Do not use negative numbers or zero; clearcut only handles positive integers.
+    private static final int ACTION_KEYBOARD_OTHER = 1;
+    private static final int ACTION_KEYBOARD_PASTE = 2;
+    private static final int ACTION_KEYBOARD_COPY = 3;
+    private static final int ACTION_KEYBOARD_DELETE = 4;
+    private static final int ACTION_KEYBOARD_SELECT_ALL = 5;
+    private static final int ACTION_KEYBOARD_BACK = 6;
+    private static final int ACTION_KEYBOARD_SWITCH_FOCUS = 7;
+
+    @IntDef(flag = false, value = {
+            ACTION_KEYBOARD_OTHER,
+            ACTION_KEYBOARD_PASTE,
+            ACTION_KEYBOARD_COPY,
+            ACTION_KEYBOARD_DELETE,
+            ACTION_KEYBOARD_SELECT_ALL,
+            ACTION_KEYBOARD_BACK,
+            ACTION_KEYBOARD_SWITCH_FOCUS
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface KeyboardAction {}
+
     // Codes representing different actions to open the drawer. They are used for bucketing stats in
     // the COUNT_DRAWER_OPENED histogram.
     // Do not change or rearrange these values, that will break historical data. Only add to the
@@ -493,6 +520,39 @@
     }
 
     /**
+     * Logs keyboard shortcut actions. Since keyboard shortcuts have their corresponding menu items,
+     * they are identified by menu item resource id for convenience.
+     * @param context
+     * @param keyCode
+     */
+    public static void logKeyboardAction(Context context, int keyCode) {
+        @KeyboardAction int keyboardAction = ACTION_KEYBOARD_OTHER;
+        switch (keyCode) {
+            case KeyEvent.KEYCODE_V:
+                keyboardAction = ACTION_KEYBOARD_PASTE;
+                break;
+            case KeyEvent.KEYCODE_C:
+                keyboardAction = ACTION_KEYBOARD_COPY;
+                break;
+            case KeyEvent.KEYCODE_FORWARD_DEL:
+                keyboardAction = ACTION_KEYBOARD_DELETE;
+                break;
+            case KeyEvent.KEYCODE_A:
+                keyboardAction = ACTION_KEYBOARD_SELECT_ALL;
+                break;
+            case KeyEvent.KEYCODE_DEL:
+                keyboardAction = ACTION_KEYBOARD_BACK;
+                break;
+            case KeyEvent.KEYCODE_TAB:
+                keyboardAction = ACTION_KEYBOARD_SWITCH_FOCUS;
+                break;
+            default:
+                break;
+        }
+        logHistogram(context, COUNT_KEYBOARD_ACTION, keyboardAction);
+    }
+
+    /**
      * Logs startup time in milliseconds.
      * @param context
      * @param startupMs Startup time in milliseconds.
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
index d70a899..20316ff 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
@@ -1339,6 +1339,7 @@
                     // This has to be handled here instead of in a keyboard shortcut, because
                     // keyboard shortcuts all have to be modified with the 'Ctrl' key.
                     if (mSelectionManager.hasSelection()) {
+                        Metrics.logKeyboardAction(getContext(), keyCode);
                         deleteDocuments(mSelectionManager.getSelection());
                     }
                     // Always handle the key, even if there was nothing to delete. This is a
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityModel.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityModel.java
index 454221a..2b549f1 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityModel.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityModel.java
@@ -77,6 +77,7 @@
             case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
             case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
             case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
+            case DevicePolicyManager.PASSWORD_QUALITY_MANAGED:
                 return SecurityMode.Password;
 
             case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
index 3eeabc7..e5ac0d3 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
@@ -141,9 +141,9 @@
             return;
         }
 
+        int viewWidth = mTaskViewRect.width();
+        int viewHeight = mTaskViewRect.height();
         if (mBitmapShader != null) {
-            int viewWidth = mTaskViewRect.width();
-            int viewHeight = mTaskViewRect.height();
 
             // We are drawing the thumbnail in the same orientation, so just fit the width
             int thumbnailWidth = (int) (mThumbnailRect.width() * mThumbnailScale);
@@ -180,6 +180,9 @@
 
                 canvas.restoreToCount(count);
             }
+        } else {
+            canvas.drawRoundRect(0, 0, viewWidth, viewHeight, mCornerRadius, mCornerRadius,
+                    mBgFillPaint);
         }
     }
 
@@ -319,12 +322,12 @@
         mDisabledInSafeMode = disabledInSafeMode;
         if (t.thumbnail != null) {
             setThumbnail(t.thumbnail, thumbnailInfo);
-            if (t.colorBackground != 0) {
-                mBgFillPaint.setColor(t.colorBackground);
-            }
         } else {
             setThumbnail(null, null);
         }
+        if (t.colorBackground != 0) {
+            mBgFillPaint.setColor(t.colorBackground);
+        }
     }
 
     /** Unbinds the thumbnail view from the task */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 0e21517..4ed6426 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -19,7 +19,9 @@
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.app.ActivityManager;
+import android.app.ActivityManager.StackId;
 import android.app.ActivityManagerNative;
+import android.app.ActivityOptions;
 import android.app.KeyguardManager;
 import android.app.Notification;
 import android.app.NotificationManager;
@@ -347,7 +349,7 @@
                 }, afterKeyguardGone);
                 return true;
             } else {
-                return super.onClickHandler(view, pendingIntent, fillInIntent);
+                return superOnClickHandler(view, pendingIntent, fillInIntent);
             }
         }
 
@@ -384,7 +386,8 @@
 
         private boolean superOnClickHandler(View view, PendingIntent pendingIntent,
                 Intent fillInIntent) {
-            return super.onClickHandler(view, pendingIntent, fillInIntent);
+            return super.onClickHandler(view, pendingIntent, fillInIntent,
+                    StackId.FULLSCREEN_WORKSPACE_STACK_ID);
         }
 
         private boolean handleRemoteInput(View view, PendingIntent pendingIntent, Intent fillInIntent) {
@@ -990,7 +993,7 @@
                             }
                             TaskStackBuilder.create(mContext)
                                     .addNextIntentWithParentStack(intent)
-                                    .startActivities(null,
+                                    .startActivities(getActivityOptions(),
                                             new UserHandle(UserHandle.getUserId(appUid)));
                             overrideActivityPendingAppTransition(keyguardShowing);
                         } catch (RemoteException e) {
@@ -1740,7 +1743,7 @@
                         } catch (RemoteException e) {
                         }
                         try {
-                            intent.send();
+                            intent.send(null, 0, null, null, null, null, getActivityOptions());
                         } catch (PendingIntent.CanceledException e) {
                             // the stack trace isn't very helpful here.
                             // Just log the exception message.
@@ -1848,7 +1851,8 @@
                                     }
                                 }
                                 try {
-                                    intent.send();
+                                    intent.send(null, 0, null, null, null, null,
+                                            getActivityOptions());
                                 } catch (PendingIntent.CanceledException e) {
                                     // the stack trace isn't very helpful here.
                                     // Just log the exception message.
@@ -1924,6 +1928,14 @@
         }
     }
 
+    protected Bundle getActivityOptions() {
+        // Anything launched from the notification shade should always go into the
+        // fullscreen stack.
+        ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchStackId(StackId.FULLSCREEN_WORKSPACE_STACK_ID);
+        return options.toBundle();
+    }
+
     protected void visibilityChanged(boolean visible) {
         if (mVisible != visible) {
             mVisible = visible;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 4c5c843..c563eb6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -21,7 +21,9 @@
 import android.animation.AnimatorListenerAdapter;
 import android.annotation.NonNull;
 import android.app.ActivityManager;
+import android.app.ActivityManager.StackId;
 import android.app.ActivityManagerNative;
+import android.app.ActivityOptions;
 import android.app.IActivityManager;
 import android.app.Notification;
 import android.app.PendingIntent;
@@ -3091,8 +3093,8 @@
                             null, mContext.getBasePackageName(),
                             intent,
                             intent.resolveTypeIfNeeded(mContext.getContentResolver()),
-                            null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, null,
-                            UserHandle.CURRENT.getIdentifier());
+                            null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null,
+                            getActivityOptions(), UserHandle.CURRENT.getIdentifier());
                 } catch (RemoteException e) {
                     Log.w(TAG, "Unable to start activity", e);
                 }
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 799a763..0a814ab 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -92,6 +92,7 @@
     private static final int MESSAGE_BLUETOOTH_STATE_CHANGE = 60;
     private static final int MESSAGE_TIMEOUT_BIND = 100;
     private static final int MESSAGE_TIMEOUT_UNBIND = 101;
+    private static final int MESSAGE_GET_NAME_AND_ADDRESS = 200;
     private static final int MESSAGE_USER_SWITCHED = 300;
     private static final int MESSAGE_USER_UNLOCKED = 301;
     private static final int MESSAGE_ADD_PROXY_DELAYED = 400;
@@ -599,8 +600,8 @@
             sendEnableMsg(true);
         }
         return true;
-
     }
+
     public boolean enable() {
         if ((Binder.getCallingUid() != Process.SYSTEM_UID) &&
             (!checkIfCallerIsForegroundUser())) {
@@ -763,9 +764,8 @@
             sendEnableMsg(mQuietEnableExternal);
         } else if (!isNameAndAddressSet()) {
             if (DBG) Slog.d(TAG, "Getting adapter name and address");
-            enable();
-            waitForOnOff(true, false);
-            disable(true);
+            Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);
+            mHandler.sendMessage(getMsg);
         }
     }
 
@@ -1076,6 +1076,8 @@
     private BluetoothServiceConnection mConnection = new BluetoothServiceConnection();
 
     private class BluetoothHandler extends Handler {
+        boolean mGetNameAddressOnly = false;
+
         public BluetoothHandler(Looper looper) {
             super(looper);
         }
@@ -1084,6 +1086,37 @@
         public void handleMessage(Message msg) {
             if (DBG) Slog.d (TAG, "Message: " + msg.what);
             switch (msg.what) {
+                case MESSAGE_GET_NAME_AND_ADDRESS:
+                    if (DBG) Slog.d(TAG, "MESSAGE_GET_NAME_AND_ADDRESS");
+                    synchronized(mConnection) {
+                        if ((mBluetooth == null) && (!mBinding)) {
+                            if (DBG) Slog.d(TAG, "Binding to service to get name and address");
+                            mGetNameAddressOnly = true;
+                            Message timeoutMsg = mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);
+                            mHandler.sendMessageDelayed(timeoutMsg, TIMEOUT_BIND_MS);
+                            Intent i = new Intent(IBluetooth.class.getName());
+                            if (!doBind(i, mConnection,
+                                Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
+                                UserHandle.CURRENT)) {
+                                mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
+                            } else {
+                                mBinding = true;
+                            }
+                        } else if (mBluetooth != null) {
+                            try {
+                                storeNameAndAddress(mBluetooth.getName(),
+                                                    mBluetooth.getAddress());
+                            } catch (RemoteException re) {
+                                Slog.e(TAG, "Unable to grab names", re);
+                            }
+                            if (mGetNameAddressOnly && !mEnable) {
+                                unbindAndFinish();
+                            }
+                            mGetNameAddressOnly = false;
+                        }
+                    }
+                    break;
+
                 case MESSAGE_ENABLE:
                     if (DBG) {
                         Slog.d(TAG, "MESSAGE_ENABLE: mBluetooth = " + mBluetooth);
@@ -1177,6 +1210,12 @@
                         mBluetoothBinder = service;
                         mBluetooth = IBluetooth.Stub.asInterface(service);
 
+                        if (!isNameAndAddressSet()) {
+                            Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);
+                            mHandler.sendMessage(getMsg);
+                            if (mGetNameAddressOnly) return;
+                        }
+
                         try {
                             boolean enableHciSnoopLog = (Settings.Secure.getInt(mContentResolver,
                                 Settings.Secure.BLUETOOTH_HCI_LOG, 0) == 1);
@@ -1187,15 +1226,6 @@
                             Slog.e(TAG,"Unable to call configHciSnoopLog", e);
                         }
 
-                        if (!isNameAndAddressSet()) {
-                            try {
-                                storeNameAndAddress(mBluetooth.getName(),
-                                                    mBluetooth.getAddress());
-                            } catch (RemoteException re) {
-                                Slog.e(TAG, "Unable to grab names", re);
-                            }
-                        }
-
                         //Register callback object
                         try {
                             mBluetooth.registerCallback(mBluetoothCallback);
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index bb32303..b8b7638 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -2500,21 +2500,31 @@
                     userId);
             return;
         }
-
         final int pid = Binder.getCallingPid();
         final Bundle options = (optionsIn == null) ? new Bundle() : optionsIn;
         options.putInt(AccountManager.KEY_CALLER_UID, uid);
         options.putInt(AccountManager.KEY_CALLER_PID, pid);
 
+        // Check to see if the Password should be included to the caller.
+        String callerPkg = optionsIn.getString(AccountManager.KEY_ANDROID_PACKAGE_NAME);
+        boolean isPasswordForwardingAllowed = isPermitted(
+                callerPkg, uid, Manifest.permission.GET_PASSWORD_PRIVILEGED);
+
         int usrId = UserHandle.getCallingUserId();
         long identityToken = clearCallingIdentity();
         try {
             UserAccounts accounts = getUserAccounts(usrId);
             logRecordWithUid(accounts, DebugDbHelper.ACTION_CALLED_START_ACCOUNT_ADD,
                     TABLE_ACCOUNTS, uid);
-            new StartAccountSession(accounts, response, accountType, expectActivityLaunch,
-                    null /* accountName */, false /* authDetailsRequired */,
-                    true /* updateLastAuthenticationTime */) {
+            new StartAccountSession(
+                    accounts,
+                    response,
+                    accountType,
+                    expectActivityLaunch,
+                    null /* accountName */,
+                    false /* authDetailsRequired */,
+                    true /* updateLastAuthenticationTime */,
+                    isPasswordForwardingAllowed) {
                 @Override
                 public void run() throws RemoteException {
                     mAuthenticator.startAddAccountSession(this, mAccountType, authTokenType,
@@ -2537,12 +2547,21 @@
     /** Session that will encrypt the KEY_ACCOUNT_SESSION_BUNDLE in result. */
     private abstract class StartAccountSession extends Session {
 
-        public StartAccountSession(UserAccounts accounts, IAccountManagerResponse response,
-                String accountType, boolean expectActivityLaunch, String accountName,
-                boolean authDetailsRequired, boolean updateLastAuthenticationTime) {
+        private final boolean mIsPasswordForwardingAllowed;
+
+        public StartAccountSession(
+                UserAccounts accounts,
+                IAccountManagerResponse response,
+                String accountType,
+                boolean expectActivityLaunch,
+                String accountName,
+                boolean authDetailsRequired,
+                boolean updateLastAuthenticationTime,
+                boolean isPasswordForwardingAllowed) {
             super(accounts, response, accountType, expectActivityLaunch,
                     true /* stripAuthTokenFromResult */, accountName, authDetailsRequired,
                     updateLastAuthenticationTime);
+            mIsPasswordForwardingAllowed = isPasswordForwardingAllowed;
         }
 
         @Override
@@ -2555,6 +2574,10 @@
                 checkKeyIntent(
                         Binder.getCallingUid(),
                         intent);
+                // Omit passwords if the caller isn't permitted to see them.
+                if (!mIsPasswordForwardingAllowed) {
+                    result.remove(AccountManager.KEY_PASSWORD);
+                }
             }
             IAccountManagerResponse response;
             if (mExpectActivityLaunch && result != null
@@ -2901,6 +2924,12 @@
         }
 
         int userId = UserHandle.getCallingUserId();
+
+        // Check to see if the Password should be included to the caller.
+        String callerPkg = loginOptions.getString(AccountManager.KEY_ANDROID_PACKAGE_NAME);
+        boolean isPasswordForwardingAllowed = isPermitted(
+                callerPkg, uid, Manifest.permission.GET_PASSWORD_PRIVILEGED);
+
         long identityToken = clearCallingIdentity();
         try {
             UserAccounts accounts = getUserAccounts(userId);
@@ -2911,7 +2940,8 @@
                     expectActivityLaunch,
                     account.name,
                     false /* authDetailsRequired */,
-                    true /* updateLastCredentialTime */) {
+                    true /* updateLastCredentialTime */,
+                    isPasswordForwardingAllowed) {
                 @Override
                 public void run() throws RemoteException {
                     mAuthenticator.startUpdateCredentialsSession(this, account, authTokenType,
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 39df999..ef05773 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -18045,6 +18045,9 @@
             ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
         int changes = 0;
 
+        if (mWindowManager != null) {
+            mWindowManager.deferSurfaceLayout();
+        }
         if (values != null) {
             Configuration newConfig = new Configuration(mConfiguration);
             changes = newConfig.updateFrom(values);
@@ -18145,6 +18148,20 @@
                             null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
                 }
             }
+            // Update the configuration with WM first and check if any of the stacks need to be
+            // resized due to the configuration change. If so, resize the stacks now and do any
+            // relaunches if necessary. This way we don't need to relaunch again below in
+            // ensureActivityConfigurationLocked().
+            if (mWindowManager != null) {
+                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
+                if (resizedStacks != null) {
+                    for (int stackId : resizedStacks) {
+                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
+                        mStackSupervisor.resizeStackLocked(
+                                stackId, newBounds, null, null, false, false);
+                    }
+                }
+            }
         }
 
         boolean kept = true;
@@ -18166,11 +18183,9 @@
                         !PRESERVE_WINDOWS);
             }
         }
-
-        if (values != null && mWindowManager != null) {
-            mWindowManager.setNewConfiguration(mConfiguration);
+        if (mWindowManager != null) {
+            mWindowManager.continueSurfaceLayout();
         }
-
         return kept;
     }
 
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 022b10f..124d7f1 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -120,6 +120,7 @@
 import android.widget.Toast;
 
 import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.statusbar.NotificationVisibility;
 import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.Preconditions;
@@ -226,7 +227,7 @@
     private VrManagerInternal mVrManagerInternal;
 
     final IBinder mForegroundToken = new Binder();
-    private WorkerHandler mHandler;
+    private Handler mHandler;
     private final HandlerThread mRankingThread = new HandlerThread("ranker",
             Process.THREAD_PRIORITY_BACKGROUND);
 
@@ -572,33 +573,9 @@
         public void clearEffects() {
             synchronized (mNotificationList) {
                 if (DBG) Slog.d(TAG, "clearEffects");
-
-                // sound
-                mSoundNotificationKey = null;
-
-                long identity = Binder.clearCallingIdentity();
-                try {
-                    final IRingtonePlayer player = mAudioManager.getRingtonePlayer();
-                    if (player != null) {
-                        player.stopAsync();
-                    }
-                } catch (RemoteException e) {
-                } finally {
-                    Binder.restoreCallingIdentity(identity);
-                }
-
-                // vibrate
-                mVibrateNotificationKey = null;
-                identity = Binder.clearCallingIdentity();
-                try {
-                    mVibrator.cancel();
-                } finally {
-                    Binder.restoreCallingIdentity(identity);
-                }
-
-                // light
-                mLights.clear();
-                updateLightsLocked();
+                clearSoundLocked();
+                clearVibrateLocked();
+                clearLightsLocked();
             }
         }
 
@@ -658,6 +635,36 @@
         }
     };
 
+    private void clearSoundLocked() {
+        mSoundNotificationKey = null;
+        long identity = Binder.clearCallingIdentity();
+        try {
+            final IRingtonePlayer player = mAudioManager.getRingtonePlayer();
+            if (player != null) {
+                player.stopAsync();
+            }
+        } catch (RemoteException e) {
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    private void clearVibrateLocked() {
+        mVibrateNotificationKey = null;
+        long identity = Binder.clearCallingIdentity();
+        try {
+            mVibrator.cancel();
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    private void clearLightsLocked() {
+        // light
+        mLights.clear();
+        updateLightsLocked();
+    }
+
     private final BroadcastReceiver mPackageIntentReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
@@ -863,6 +870,26 @@
         super(context);
     }
 
+    @VisibleForTesting
+    void setAudioManager(AudioManager audioMananger) {
+        mAudioManager = audioMananger;
+    }
+
+    @VisibleForTesting
+    void setVibrator(Vibrator vibrator) {
+        mVibrator = vibrator;
+    }
+
+    @VisibleForTesting
+    void setSystemReady(boolean systemReady) {
+        mSystemReady = systemReady;
+    }
+
+    @VisibleForTesting
+    void setHandler(Handler handler) {
+        mHandler = handler;
+    }
+
     @Override
     public void onStart() {
         Resources resources = getContext().getResources();
@@ -2492,12 +2519,14 @@
         return false;
     }
 
-    private void buzzBeepBlinkLocked(NotificationRecord record) {
+    @VisibleForTesting
+    void buzzBeepBlinkLocked(NotificationRecord record) {
         boolean buzz = false;
         boolean beep = false;
         boolean blink = false;
 
         final Notification notification = record.sbn.getNotification();
+        final String key = record.getKey();
 
         // Should this notification make noise, vibe, or use the LED?
         final boolean aboveThreshold = record.getImportance() >= IMPORTANCE_DEFAULT;
@@ -2521,9 +2550,15 @@
         if (disableEffects != null) {
             ZenLog.traceDisableEffects(record, disableEffects);
         }
+
+        // Remember if this notification already owns the notification channels.
+        boolean wasBeep = key != null && key.equals(mSoundNotificationKey);
+        boolean wasBuzz = key != null && key.equals(mVibrateNotificationKey);
+
+        // These are set inside the conditional if the notification is allowed to make noise.
+        boolean hasValidVibrate = false;
+        boolean hasValidSound = false;
         if (disableEffects == null
-                && (!(record.isUpdate
-                    && (notification.flags & Notification.FLAG_ONLY_ALERT_ONCE) != 0 ))
                 && (record.getUserId() == UserHandle.USER_ALL ||
                     record.getUserId() == currentUser ||
                     mUserProfiles.isCurrentProfile(record.getUserId()))
@@ -2532,10 +2567,6 @@
                 && mAudioManager != null) {
             if (DBG) Slog.v(TAG, "Interrupting!");
 
-            sendAccessibilityEvent(notification, record.sbn.getPackageName());
-
-            // sound
-
             // should we use the default notification sound? (indicated either by
             // DEFAULT_SOUND or because notification.sound is pointing at
             // Settings.System.NOTIFICATION_SOUND)
@@ -2545,8 +2576,6 @@
                                    .equals(notification.sound);
 
             Uri soundUri = null;
-            boolean hasValidSound = false;
-
             if (useDefaultSound) {
                 soundUri = Settings.System.DEFAULT_NOTIFICATION_URI;
 
@@ -2559,88 +2588,105 @@
                 hasValidSound = (soundUri != null);
             }
 
-            if (hasValidSound) {
-                boolean looping =
-                        (notification.flags & Notification.FLAG_INSISTENT) != 0;
-                AudioAttributes audioAttributes = audioAttributesForNotification(notification);
-                mSoundNotificationKey = record.getKey();
-                // do not play notifications if stream volume is 0 (typically because
-                // ringer mode is silent) or if there is a user of exclusive audio focus
-                if ((mAudioManager.getStreamVolume(
-                        AudioAttributes.toLegacyStreamType(audioAttributes)) != 0)
-                            && !mAudioManager.isAudioFocusExclusive()) {
-                    final long identity = Binder.clearCallingIdentity();
-                    try {
-                        final IRingtonePlayer player =
-                                mAudioManager.getRingtonePlayer();
-                        if (player != null) {
-                            if (DBG) Slog.v(TAG, "Playing sound " + soundUri
-                                    + " with attributes " + audioAttributes);
-                            player.playAsync(soundUri, record.sbn.getUser(), looping,
-                                    audioAttributes);
-                            beep = true;
-                        }
-                    } catch (RemoteException e) {
-                    } finally {
-                        Binder.restoreCallingIdentity(identity);
-                    }
-                }
-            }
-
-            // vibrate
             // Does the notification want to specify its own vibration?
             final boolean hasCustomVibrate = notification.vibrate != null;
 
             // new in 4.2: if there was supposed to be a sound and we're in vibrate
             // mode, and no other vibration is specified, we fall back to vibration
             final boolean convertSoundToVibration =
-                       !hasCustomVibrate
-                    && hasValidSound
-                    && (mAudioManager.getRingerModeInternal()
-                               == AudioManager.RINGER_MODE_VIBRATE);
+                    !hasCustomVibrate
+                            && hasValidSound
+                            && (mAudioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_VIBRATE);
 
             // The DEFAULT_VIBRATE flag trumps any custom vibration AND the fallback.
             final boolean useDefaultVibrate =
                     (notification.defaults & Notification.DEFAULT_VIBRATE) != 0;
 
-            if ((useDefaultVibrate || convertSoundToVibration || hasCustomVibrate)
-                    && !(mAudioManager.getRingerModeInternal()
-                            == AudioManager.RINGER_MODE_SILENT)) {
-                mVibrateNotificationKey = record.getKey();
+            hasValidVibrate = useDefaultVibrate || convertSoundToVibration ||
+                    hasCustomVibrate;
 
-                if (useDefaultVibrate || convertSoundToVibration) {
-                    // Escalate privileges so we can use the vibrator even if the
-                    // notifying app does not have the VIBRATE permission.
-                    long identity = Binder.clearCallingIdentity();
-                    try {
-                        mVibrator.vibrate(record.sbn.getUid(), record.sbn.getOpPkg(),
-                            useDefaultVibrate ? mDefaultVibrationPattern
-                                : mFallbackVibrationPattern,
-                            ((notification.flags & Notification.FLAG_INSISTENT) != 0)
-                                ? 0: -1, audioAttributesForNotification(notification));
-                        buzz = true;
-                    } finally {
-                        Binder.restoreCallingIdentity(identity);
+            // We can alert, and we're allowed to alert, but if the developer asked us to only do
+            // it once, and we already have, then don't.
+            if (!(record.isUpdate
+                    && (notification.flags & Notification.FLAG_ONLY_ALERT_ONCE) != 0)) {
+
+                sendAccessibilityEvent(notification, record.sbn.getPackageName());
+
+                if (hasValidSound) {
+                    boolean looping =
+                            (notification.flags & Notification.FLAG_INSISTENT) != 0;
+                    AudioAttributes audioAttributes = audioAttributesForNotification(notification);
+                    mSoundNotificationKey = key;
+                    // do not play notifications if stream volume is 0 (typically because
+                    // ringer mode is silent) or if there is a user of exclusive audio focus
+                    if ((mAudioManager.getStreamVolume(
+                            AudioAttributes.toLegacyStreamType(audioAttributes)) != 0)
+                            && !mAudioManager.isAudioFocusExclusive()) {
+                        final long identity = Binder.clearCallingIdentity();
+                        try {
+                            final IRingtonePlayer player =
+                                    mAudioManager.getRingtonePlayer();
+                            if (player != null) {
+                                if (DBG) Slog.v(TAG, "Playing sound " + soundUri
+                                        + " with attributes " + audioAttributes);
+                                player.playAsync(soundUri, record.sbn.getUser(), looping,
+                                        audioAttributes);
+                                beep = true;
+                            }
+                        } catch (RemoteException e) {
+                        } finally {
+                            Binder.restoreCallingIdentity(identity);
+                        }
                     }
-                } else if (notification.vibrate.length > 1) {
-                    // If you want your own vibration pattern, you need the VIBRATE
-                    // permission
-                    mVibrator.vibrate(record.sbn.getUid(), record.sbn.getOpPkg(),
-                            notification.vibrate,
-                        ((notification.flags & Notification.FLAG_INSISTENT) != 0)
-                                ? 0: -1, audioAttributesForNotification(notification));
-                    buzz = true;
+                }
+
+                if (hasValidVibrate && !(mAudioManager.getRingerModeInternal()
+                        == AudioManager.RINGER_MODE_SILENT)) {
+                    mVibrateNotificationKey = key;
+
+                    if (useDefaultVibrate || convertSoundToVibration) {
+                        // Escalate privileges so we can use the vibrator even if the
+                        // notifying app does not have the VIBRATE permission.
+                        long identity = Binder.clearCallingIdentity();
+                        try {
+                            mVibrator.vibrate(record.sbn.getUid(), record.sbn.getOpPkg(),
+                                    useDefaultVibrate ? mDefaultVibrationPattern
+                                            : mFallbackVibrationPattern,
+                                    ((notification.flags & Notification.FLAG_INSISTENT) != 0)
+                                            ? 0: -1, audioAttributesForNotification(notification));
+                            buzz = true;
+                        } finally {
+                            Binder.restoreCallingIdentity(identity);
+                        }
+                    } else if (notification.vibrate.length > 1) {
+                        // If you want your own vibration pattern, you need the VIBRATE
+                        // permission
+                        mVibrator.vibrate(record.sbn.getUid(), record.sbn.getOpPkg(),
+                                notification.vibrate,
+                                ((notification.flags & Notification.FLAG_INSISTENT) != 0)
+                                        ? 0: -1, audioAttributesForNotification(notification));
+                        buzz = true;
+                    }
                 }
             }
+
+        }
+        // If a notification is updated to remove the actively playing sound or vibrate,
+        // cancel that feedback now
+        if (wasBeep && !hasValidSound) {
+            clearSoundLocked();
+        }
+        if (wasBuzz && !hasValidVibrate) {
+            clearVibrateLocked();
         }
 
         // light
         // release the light
-        boolean wasShowLights = mLights.remove(record.getKey());
+        boolean wasShowLights = mLights.remove(key);
         if ((notification.flags & Notification.FLAG_SHOW_LIGHTS) != 0 && aboveThreshold
                 && ((record.getSuppressedVisualEffects()
                 & NotificationListenerService.SUPPRESSED_EFFECT_SCREEN_OFF) == 0)) {
-            mLights.add(record.getKey());
+            mLights.add(key);
             updateLightsLocked();
             if (mUseAttentionLight) {
                 mAttentionLight.pulse();
@@ -2654,7 +2700,7 @@
                     & NotificationListenerService.SUPPRESSED_EFFECT_SCREEN_OFF) != 0)) {
                 if (DBG) Slog.v(TAG, "Suppressed SystemUI from triggering screen on");
             } else {
-                EventLogTags.writeNotificationAlert(record.getKey(),
+                EventLogTags.writeNotificationAlert(key,
                         buzz ? 1 : 0, beep ? 1 : 0, blink ? 1 : 0);
                 mHandler.post(mBuzzBeepBlinked);
             }
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 0bf7102..bb0ec4c 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -128,6 +128,10 @@
     // in which case a second window animation would cause jitter.
     private boolean mFreezeMovementAnimations = false;
 
+    // Temporary storage for the new bounds that should be used after the configuration change.
+    // Will be cleared once the client retrieves the new bounds via getBoundsForNewConfiguration().
+    private final Rect mBoundsAfterRotation = new Rect();
+
     TaskStack(WindowManagerService service, int stackId) {
         mService = service;
         mStackId = stackId;
@@ -343,28 +347,28 @@
             setBounds(mTmpRect2);
         } else {
             mLastUpdateDisplayInfoRotation = newRotation;
-            updateBoundsAfterRotation();
+            updateBoundsAfterRotation(true);
         }
     }
 
-    void onConfigurationChanged() {
+    boolean onConfigurationChanged() {
         mLastConfigChangedRotation = getDisplayInfo().rotation;
-        updateBoundsAfterRotation();
+        return updateBoundsAfterRotation(false);
     }
 
-    void updateBoundsAfterRotation() {
+    boolean updateBoundsAfterRotation(boolean scheduleResize) {
         if (mLastConfigChangedRotation != mLastUpdateDisplayInfoRotation) {
             // We wait for the rotation values after configuration change and display info. update
             // to be equal before updating the bounds due to rotation change otherwise things might
             // get out of alignment...
-            return;
+            return false;
         }
 
         final int newRotation = getDisplayInfo().rotation;
 
         if (mRotation == newRotation) {
             // Nothing to do here if the rotation didn't change
-            return;
+            return false;
         }
 
         mDisplayContent.rotateBounds(mRotation, newRotation, mTmpRect2);
@@ -373,11 +377,22 @@
             snapDockedStackAfterRotation(mTmpRect2);
         }
 
-        // Post message to inform activity manager of the bounds change simulating
-        // a one-way call. We do this to prevent a deadlock between window manager
-        // lock and activity manager lock been held.
-        mService.mH.obtainMessage(
-                RESIZE_STACK, mStackId, 0 /*allowResizeInDockedMode*/, mTmpRect2).sendToTarget();
+        if (scheduleResize) {
+            // Post message to inform activity manager of the bounds change simulating
+            // a one-way call. We do this to prevent a deadlock between window manager
+            // lock and activity manager lock been held.
+            mService.mH.obtainMessage(RESIZE_STACK, mStackId,
+                    0 /*allowResizeInDockedMode*/, mTmpRect2).sendToTarget();
+        } else {
+            mBoundsAfterRotation.set(mTmpRect2);
+        }
+
+        return true;
+    }
+
+    void getBoundsForNewConfiguration(Rect outBounds) {
+        outBounds.set(mBoundsAfterRotation);
+        mBoundsAfterRotation.setEmpty();
     }
 
     /**
@@ -869,6 +884,10 @@
         }
     }
 
+    boolean isAdjustedForMinimizedDock() {
+        return mMinimizeAmount != 0f;
+    }
+
     private boolean adjustForIME(final WindowState imeWin) {
         final int dockedSide = getDockSide();
         final boolean dockedTopOrBottom = dockedSide == DOCKED_TOP || dockedSide == DOCKED_BOTTOM;
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index dcb4a63..14ae74f 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -125,6 +125,7 @@
 import com.android.internal.app.IAssistScreenshotReceiver;
 import com.android.internal.os.IResultReceiver;
 import com.android.internal.policy.IShortcutService;
+import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.FastPrintWriter;
 import com.android.internal.view.IInputContext;
 import com.android.internal.view.IInputMethodClient;
@@ -515,6 +516,8 @@
 
     private final SparseIntArray mTmpTaskIds = new SparseIntArray();
 
+    private final ArrayList<Integer> mChangedStackList = new ArrayList();
+
     boolean mForceResizableTasks = false;
 
     int getDragLayerLocked() {
@@ -3398,7 +3401,8 @@
             }
         }
 
-        if (isStackVisibleLocked(DOCKED_STACK_ID)
+        if ((isStackVisibleLocked(DOCKED_STACK_ID)
+                && !mStackIdToStack.get(DOCKED_STACK_ID).isAdjustedForMinimizedDock())
                 || isStackVisibleLocked(FREEFORM_WORKSPACE_STACK_ID)) {
             // We don't let app affect the system orientation when in freeform or docked mode since
             // they don't occupy the entire display and their request can conflict with other apps.
@@ -3580,7 +3584,7 @@
     }
 
     @Override
-    public void setNewConfiguration(Configuration config) {
+    public int[] setNewConfiguration(Configuration config) {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                 "setNewConfiguration()")) {
             throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
@@ -3592,16 +3596,30 @@
                 mWaitingForConfig = false;
                 mLastFinishedFreezeSource = "new-config";
             }
-            onConfigurationChanged();
-            mWindowPlacerLocked.performSurfacePlacement();
+            return onConfigurationChanged();
         }
     }
 
-    private void onConfigurationChanged() {
+    @Override
+    public Rect getBoundsForNewConfiguration(int stackId) {
+        synchronized(mWindowMap) {
+            final TaskStack stack = mStackIdToStack.get(stackId);
+            final Rect outBounds = new Rect();
+            stack.getBoundsForNewConfiguration(outBounds);
+            return outBounds;
+        }
+    }
+
+    private int[] onConfigurationChanged() {
+        mChangedStackList.clear();
         for (int stackNdx = mStackIdToStack.size() - 1; stackNdx >= 0; stackNdx--) {
             final TaskStack stack = mStackIdToStack.valueAt(stackNdx);
-            stack.onConfigurationChanged();
+            if (stack.onConfigurationChanged()) {
+                mChangedStackList.add(stack.mStackId);
+            }
         }
+        return mChangedStackList.isEmpty() ?
+                null : ArrayUtils.convertToIntArray(mChangedStackList);
     }
 
     @Override
diff --git a/services/tests/servicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java b/services/tests/servicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
new file mode 100644
index 0000000..83a59fd
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
@@ -0,0 +1,541 @@
+/*
+ * Copyright (C) 2016 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.server.notification;
+
+
+import android.app.ActivityManager;
+import android.app.Notification;
+import android.app.Notification.Builder;
+import android.media.AudioAttributes;
+import android.media.AudioManager;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.os.Vibrator;
+import android.service.notification.NotificationListenerService.Ranking;
+import android.service.notification.StatusBarNotification;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyObject;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class BuzzBeepBlinkTest extends AndroidTestCase {
+
+    @Mock AudioManager mAudioManager;
+    @Mock Vibrator mVibrator;
+    @Mock android.media.IRingtonePlayer mRingtonePlayer;
+    @Mock Handler mHandler;
+
+    private NotificationManagerService mService;
+    private String mPkg = "com.android.server.notification";
+    private int mId = 1001;
+    private int mOtherId = 1002;
+    private String mTag = null;
+    private int mUid = 1000;
+    private int mPid = 2000;
+    private int mScore = 10;
+    private android.os.UserHandle mUser = UserHandle.of(ActivityManager.getCurrentUser());
+
+    @Override
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        when(mAudioManager.isAudioFocusExclusive()).thenReturn(false);
+        when(mAudioManager.getRingtonePlayer()).thenReturn(mRingtonePlayer);
+        when(mAudioManager.getStreamVolume(anyInt())).thenReturn(10);
+        when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
+
+        mService = new NotificationManagerService(getContext());
+        mService.setAudioManager(mAudioManager);
+        mService.setVibrator(mVibrator);
+        mService.setSystemReady(true);
+        mService.setHandler(mHandler);
+    }
+
+    //
+    // Convenience functions for creating notification records
+    //
+
+    private NotificationRecord getNoisyOtherNotification() {
+        return getNotificationRecord(mOtherId, false /* insistent */, false /* once */,
+                true /* noisy */, true /* buzzy*/);
+    }
+
+    private NotificationRecord getBeepyNotification() {
+        return getNotificationRecord(mId, false /* insistent */, false /* once */,
+                true /* noisy */, false /* buzzy*/);
+    }
+
+    private NotificationRecord getBeepyOnceNotification() {
+        return getNotificationRecord(mId, false /* insistent */, true /* once */,
+                true /* noisy */, false /* buzzy*/);
+    }
+
+    private NotificationRecord getQuietNotification() {
+        return getNotificationRecord(mId, false /* insistent */, false /* once */,
+                false /* noisy */, false /* buzzy*/);
+    }
+
+    private NotificationRecord getQuietOtherNotification() {
+        return getNotificationRecord(mOtherId, false /* insistent */, false /* once */,
+                false /* noisy */, false /* buzzy*/);
+    }
+
+    private NotificationRecord getQuietOnceNotification() {
+        return getNotificationRecord(mId, false /* insistent */, true /* once */,
+                false /* noisy */, false /* buzzy*/);
+    }
+
+    private NotificationRecord getInsistentBeepyNotification() {
+        return getNotificationRecord(mId, true /* insistent */, false /* once */,
+                true /* noisy */, false /* buzzy*/);
+    }
+
+    private NotificationRecord getBuzzyNotification() {
+        return getNotificationRecord(mId, false /* insistent */, false /* once */,
+                false /* noisy */, true /* buzzy*/);
+    }
+
+    private NotificationRecord getBuzzyOnceNotification() {
+        return getNotificationRecord(mId, false /* insistent */, true /* once */,
+                false /* noisy */, true /* buzzy*/);
+    }
+
+    private NotificationRecord getInsistentBuzzyNotification() {
+        return getNotificationRecord(mId, true /* insistent */, false /* once */,
+                false /* noisy */, true /* buzzy*/);
+    }
+
+    private NotificationRecord getNotificationRecord(int id, boolean insistent, boolean once,
+            boolean noisy, boolean buzzy) {
+        final Builder builder = new Builder(getContext())
+                .setContentTitle("foo")
+                .setSmallIcon(android.R.drawable.sym_def_app_icon)
+                .setPriority(Notification.PRIORITY_HIGH)
+                .setOnlyAlertOnce(once);
+
+        int defaults = 0;
+        if (noisy) {
+            defaults |= Notification.DEFAULT_SOUND;
+        }
+        if (buzzy) {
+            defaults |= Notification.DEFAULT_VIBRATE;
+        }
+        builder.setDefaults(defaults);
+
+        Notification n = builder.build();
+        if (insistent) {
+            n.flags |= Notification.FLAG_INSISTENT;
+        }
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, id, mTag, mUid, mPid,
+                mScore, n, mUser, System.currentTimeMillis());
+        return new NotificationRecord(getContext(), sbn);
+    }
+
+    //
+    // Convenience functions for interacting with mocks
+    //
+
+    private void verifyNeverBeep() throws RemoteException {
+        verify(mRingtonePlayer, never()).playAsync((Uri) anyObject(), (UserHandle) anyObject(),
+                anyBoolean(), (AudioAttributes) anyObject());
+    }
+
+    private void verifyBeep() throws RemoteException {
+        verify(mRingtonePlayer, times(1)).playAsync((Uri) anyObject(), (UserHandle) anyObject(),
+                eq(true), (AudioAttributes) anyObject());
+    }
+
+    private void verifyBeepLooped() throws RemoteException {
+        verify(mRingtonePlayer, times(1)).playAsync((Uri) anyObject(), (UserHandle) anyObject(),
+                eq(false), (AudioAttributes) anyObject());
+    }
+
+    private void verifyNeverStopAudio() throws RemoteException {
+        verify(mRingtonePlayer, never()).stopAsync();
+    }
+
+    private void verifyStopAudio() throws RemoteException {
+        verify(mRingtonePlayer, times(1)).stopAsync();
+    }
+
+    private void verifyNeverVibrate() {
+        verify(mVibrator, never()).vibrate(anyInt(), anyString(), (long[]) anyObject(),
+                anyInt(), (AudioAttributes) anyObject());
+    }
+
+    private void verifyVibrate() {
+        verify(mVibrator, times(1)).vibrate(anyInt(), anyString(), (long[]) anyObject(),
+                eq(-1), (AudioAttributes) anyObject());
+    }
+
+    private void verifyVibrateLooped() {
+        verify(mVibrator, times(1)).vibrate(anyInt(), anyString(), (long[]) anyObject(),
+                eq(0), (AudioAttributes) anyObject());
+    }
+
+    private void verifyStopVibrate() {
+        verify(mVibrator, times(1)).cancel();
+    }
+
+    private void verifyNeverStopVibrate() throws RemoteException {
+        verify(mVibrator, never()).cancel();
+    }
+
+    @SmallTest
+    public void testBeep() throws Exception {
+        NotificationRecord r = getBeepyNotification();
+
+        mService.buzzBeepBlinkLocked(r);
+
+        verifyBeepLooped();
+        verifyNeverVibrate();
+    }
+
+    //
+    // Tests
+    //
+
+    @SmallTest
+    public void testBeepInsistently() throws Exception {
+        NotificationRecord r = getInsistentBeepyNotification();
+
+        mService.buzzBeepBlinkLocked(r);
+
+        verifyBeep();
+    }
+
+    @SmallTest
+    public void testNoInterruptionForMin() throws Exception {
+        NotificationRecord r = getBeepyNotification();
+        r.setImportance(Ranking.IMPORTANCE_MIN, "foo");
+
+        mService.buzzBeepBlinkLocked(r);
+
+        verifyNeverBeep();
+        verifyNeverVibrate();
+    }
+
+    @SmallTest
+    public void testNoInterruptionForIntercepted() throws Exception {
+        NotificationRecord r = getBeepyNotification();
+        r.setIntercepted(true);
+
+        mService.buzzBeepBlinkLocked(r);
+
+        verifyNeverBeep();
+        verifyNeverVibrate();
+    }
+
+    @SmallTest
+    public void testBeepTwice() throws Exception {
+        NotificationRecord r = getBeepyNotification();
+
+        // set up internal state
+        mService.buzzBeepBlinkLocked(r);
+        Mockito.reset(mRingtonePlayer);
+
+        // update should beep
+        r.isUpdate = true;
+        mService.buzzBeepBlinkLocked(r);
+        verifyBeepLooped();
+    }
+
+    @SmallTest
+    public void testHonorAlertOnlyOnceForBeep() throws Exception {
+        NotificationRecord r = getBeepyNotification();
+        NotificationRecord s = getBeepyOnceNotification();
+        s.isUpdate = true;
+
+        // set up internal state
+        mService.buzzBeepBlinkLocked(r);
+        Mockito.reset(mRingtonePlayer);
+
+        // update should not beep
+        mService.buzzBeepBlinkLocked(s);
+        verifyNeverBeep();
+    }
+
+    @SmallTest
+    public void testNoisyUpdateDoesNotCancelAudio() throws Exception {
+        NotificationRecord r = getBeepyNotification();
+
+        mService.buzzBeepBlinkLocked(r);
+        r.isUpdate = true;
+        mService.buzzBeepBlinkLocked(r);
+
+        verifyNeverStopAudio();
+    }
+
+    @SmallTest
+    public void testNoisyOnceUpdateDoesNotCancelAudio() throws Exception {
+        NotificationRecord r = getBeepyNotification();
+        NotificationRecord s = getBeepyOnceNotification();
+        s.isUpdate = true;
+
+        mService.buzzBeepBlinkLocked(r);
+        mService.buzzBeepBlinkLocked(s);
+
+        verifyNeverStopAudio();
+    }
+
+    @SmallTest
+    public void testQuietUpdateDoesNotCancelAudioFromOther() throws Exception {
+        NotificationRecord r = getBeepyNotification();
+        NotificationRecord s = getQuietNotification();
+        s.isUpdate = true;
+        NotificationRecord other = getNoisyOtherNotification();
+
+        // set up internal state
+        mService.buzzBeepBlinkLocked(r);
+        mService.buzzBeepBlinkLocked(other); // this takes the audio stream
+        Mockito.reset(mRingtonePlayer);
+
+        // should not stop noise, since we no longer own it
+        mService.buzzBeepBlinkLocked(s); // this no longer owns the stream
+        verifyNeverStopAudio();
+    }
+
+    @SmallTest
+    public void testQuietInterloperDoesNotCancelAudio() throws Exception {
+        NotificationRecord r = getBeepyNotification();
+        NotificationRecord other = getQuietOtherNotification();
+
+        // set up internal state
+        mService.buzzBeepBlinkLocked(r);
+        Mockito.reset(mRingtonePlayer);
+
+        // should not stop noise, since it does not own it
+        mService.buzzBeepBlinkLocked(other);
+        verifyNeverStopAudio();
+    }
+
+    @SmallTest
+    public void testQuietUpdateCancelsAudio() throws Exception {
+        NotificationRecord r = getBeepyNotification();
+        NotificationRecord s = getQuietNotification();
+        s.isUpdate = true;
+
+        // set up internal state
+        mService.buzzBeepBlinkLocked(r);
+        Mockito.reset(mRingtonePlayer);
+
+        // quiet update should stop making noise
+        mService.buzzBeepBlinkLocked(s);
+        verifyStopAudio();
+    }
+
+    @SmallTest
+    public void testQuietOnceUpdateCancelsAudio() throws Exception {
+        NotificationRecord r = getBeepyNotification();
+        NotificationRecord s = getQuietOnceNotification();
+        s.isUpdate = true;
+
+        // set up internal state
+        mService.buzzBeepBlinkLocked(r);
+        Mockito.reset(mRingtonePlayer);
+
+        // stop making noise - this is a weird corner case, but quiet should override once
+        mService.buzzBeepBlinkLocked(s);
+        verifyStopAudio();
+    }
+
+    @SmallTest
+    public void testDemoteSoundToVibrate() throws Exception {
+        NotificationRecord r = getBeepyNotification();
+
+        // the phone is quiet
+        when(mAudioManager.getStreamVolume(anyInt())).thenReturn(0);
+        when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_VIBRATE);
+
+        mService.buzzBeepBlinkLocked(r);
+
+        verifyNeverBeep();
+        verifyVibrate();
+    }
+
+    @SmallTest
+    public void testDemotInsistenteSoundToVibrate() throws Exception {
+        NotificationRecord r = getInsistentBeepyNotification();
+
+        // the phone is quiet
+        when(mAudioManager.getStreamVolume(anyInt())).thenReturn(0);
+        when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_VIBRATE);
+
+        mService.buzzBeepBlinkLocked(r);
+
+        verifyVibrateLooped();
+    }
+
+    @SmallTest
+    public void testVibrate() throws Exception {
+        NotificationRecord r = getBuzzyNotification();
+
+        mService.buzzBeepBlinkLocked(r);
+
+        verifyNeverBeep();
+        verifyVibrate();
+    }
+
+    @SmallTest
+    public void testInsistenteVibrate() throws Exception {
+        NotificationRecord r = getInsistentBuzzyNotification();
+
+        mService.buzzBeepBlinkLocked(r);
+        verifyVibrateLooped();
+    }
+
+    @SmallTest
+    public void testVibratTwice() throws Exception {
+        NotificationRecord r = getBuzzyNotification();
+
+        // set up internal state
+        mService.buzzBeepBlinkLocked(r);
+        Mockito.reset(mVibrator);
+
+        // update should vibrate
+        r.isUpdate = true;
+        mService.buzzBeepBlinkLocked(r);
+        verifyVibrate();
+    }
+
+    @SmallTest
+    public void testHonorAlertOnlyOnceForBuzz() throws Exception {
+        NotificationRecord r = getBuzzyNotification();
+        NotificationRecord s = getBuzzyOnceNotification();
+        s.isUpdate = true;
+
+        // set up internal state
+        mService.buzzBeepBlinkLocked(r);
+        Mockito.reset(mVibrator);
+
+        // update should not beep
+        mService.buzzBeepBlinkLocked(s);
+        verifyNeverVibrate();
+    }
+
+    @SmallTest
+    public void testNoisyUpdateDoesNotCancelVibrate() throws Exception {
+        NotificationRecord r = getBuzzyNotification();
+
+        mService.buzzBeepBlinkLocked(r);
+        r.isUpdate = true;
+        mService.buzzBeepBlinkLocked(r);
+
+        verifyNeverStopVibrate();
+    }
+
+    @SmallTest
+    public void testNoisyOnceUpdateDoesNotCancelVibrate() throws Exception {
+        NotificationRecord r = getBuzzyNotification();
+        NotificationRecord s = getBuzzyOnceNotification();
+        s.isUpdate = true;
+
+        mService.buzzBeepBlinkLocked(r);
+        mService.buzzBeepBlinkLocked(s);
+
+        verifyNeverStopVibrate();
+    }
+
+    @SmallTest
+    public void testQuietUpdateDoesNotCancelVibrateFromOther() throws Exception {
+        NotificationRecord r = getBuzzyNotification();
+        NotificationRecord s = getQuietNotification();
+        s.isUpdate = true;
+        NotificationRecord other = getNoisyOtherNotification();
+
+        // set up internal state
+        mService.buzzBeepBlinkLocked(r);
+        mService.buzzBeepBlinkLocked(other); // this takes the vibrate stream
+        Mockito.reset(mVibrator);
+
+        // should not stop vibrate, since we no longer own it
+        mService.buzzBeepBlinkLocked(s); // this no longer owns the stream
+        verifyNeverStopVibrate();
+    }
+
+    @SmallTest
+    public void testQuietInterloperDoesNotCancelVibrate() throws Exception {
+        NotificationRecord r = getBuzzyNotification();
+        NotificationRecord other = getQuietOtherNotification();
+
+        // set up internal state
+        mService.buzzBeepBlinkLocked(r);
+        Mockito.reset(mVibrator);
+
+        // should not stop noise, since it does not own it
+        mService.buzzBeepBlinkLocked(other);
+        verifyNeverStopVibrate();
+    }
+
+    @SmallTest
+    public void testQuietUpdateCancelsVibrate() throws Exception {
+        NotificationRecord r = getBuzzyNotification();
+        NotificationRecord s = getQuietNotification();
+        s.isUpdate = true;
+
+        // set up internal state
+        mService.buzzBeepBlinkLocked(r);
+
+        // quiet update should stop making noise
+        mService.buzzBeepBlinkLocked(s);
+        verifyStopVibrate();
+    }
+
+    @SmallTest
+    public void testQuietOnceUpdateCancelsvibrate() throws Exception {
+        NotificationRecord r = getBuzzyNotification();
+        NotificationRecord s = getQuietOnceNotification();
+        s.isUpdate = true;
+
+        // set up internal state
+        mService.buzzBeepBlinkLocked(r);
+        Mockito.reset(mVibrator);
+
+        // stop making noise - this is a weird corner case, but quiet should override once
+        mService.buzzBeepBlinkLocked(s);
+        verifyStopVibrate();
+    }
+
+    @SmallTest
+    public void testQuietUpdateCancelsDemotedVibrate() throws Exception {
+        NotificationRecord r = getBeepyNotification();
+        NotificationRecord s = getQuietNotification();
+
+        // the phone is quiet
+        when(mAudioManager.getStreamVolume(anyInt())).thenReturn(0);
+        when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_VIBRATE);
+
+        mService.buzzBeepBlinkLocked(r);
+
+        // quiet update should stop making noise
+        mService.buzzBeepBlinkLocked(s);
+        verifyStopVibrate();
+    }
+}
diff --git a/tests/SoundTriggerTests/src/android/hardware/soundtrigger/stubhal/GenericSoundModelTest.java b/tests/SoundTriggerTests/src/android/hardware/soundtrigger/stubhal/GenericSoundModelTest.java
index ad02d2b..c0583ce 100644
--- a/tests/SoundTriggerTests/src/android/hardware/soundtrigger/stubhal/GenericSoundModelTest.java
+++ b/tests/SoundTriggerTests/src/android/hardware/soundtrigger/stubhal/GenericSoundModelTest.java
@@ -18,6 +18,7 @@
 
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.timeout;
 import static org.mockito.Mockito.verify;
@@ -40,6 +41,7 @@
 import java.net.InetAddress;
 import java.net.Socket;
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.Random;
 import java.util.UUID;
 
@@ -53,7 +55,7 @@
     static final int MSG_GENERIC_TRIGGER = 4;
 
     private Random random = new Random();
-    private ArrayList<UUID> loadedModelUuids;
+    private HashSet<UUID> loadedModelUuids;
     private ISoundTriggerService soundTriggerService;
     private SoundTriggerManager soundTriggerManager;
 
@@ -68,7 +70,7 @@
         soundTriggerManager = (SoundTriggerManager) context.getSystemService(
                 Context.SOUND_TRIGGER_SERVICE);
 
-        loadedModelUuids = new ArrayList<UUID>();
+        loadedModelUuids = new HashSet<UUID>();
     }
 
     @Override
@@ -170,6 +172,101 @@
         verify(spyCallback, timeout(100)).onGenericSoundTriggerDetected(any());
     }
 
+    /**
+     * Tests a more complicated pattern of loading, unloading, triggering, starting and stopping
+     * recognition. Intended to find unexpected errors that occur in unexpected states.
+     */
+    @LargeTest
+    public void testFuzzGenericSoundModel() throws Exception {
+        int numModels = 2;
+
+        final int STATUS_UNLOADED = 0;
+        final int STATUS_LOADED = 1;
+        final int STATUS_STARTED = 2;
+
+        class ModelInfo {
+            int status;
+            GenericSoundModel model;
+
+            public ModelInfo(GenericSoundModel model, int status) {
+                this.status = status;
+                this.model = model;
+            }
+        }
+
+        Random predictableRandom = new Random(100);
+
+        ArrayList modelInfos = new ArrayList<ModelInfo>();
+        for(int i=0; i<numModels; i++) {
+            // Create sound model
+            byte[] data = new byte[1024];
+            predictableRandom.nextBytes(data);
+            UUID modelUuid = UUID.randomUUID();
+            UUID mVendorUuid = UUID.randomUUID();
+            GenericSoundModel model = new GenericSoundModel(modelUuid, mVendorUuid, data);
+            ModelInfo modelInfo = new ModelInfo(model, STATUS_UNLOADED);
+            modelInfos.add(modelInfo);
+        }
+
+        boolean captureTriggerAudio = true;
+        boolean allowMultipleTriggers = true;
+        RecognitionConfig config = new RecognitionConfig(captureTriggerAudio, allowMultipleTriggers,
+                null, null);
+        TestRecognitionStatusCallback spyCallback = spy(new TestRecognitionStatusCallback());
+
+
+        int numOperationsToRun = 100;
+        for(int i=0; i<numOperationsToRun; i++) {
+            // Select a random model
+            int modelInfoIndex = predictableRandom.nextInt(modelInfos.size());
+            ModelInfo modelInfo = (ModelInfo) modelInfos.get(modelInfoIndex);
+
+            // Perform a random operation
+            int operation = predictableRandom.nextInt(5);
+
+            if (operation == 0 && modelInfo.status == STATUS_UNLOADED) {
+                // Update and start sound model
+                soundTriggerService.updateSoundModel(modelInfo.model);
+                loadedModelUuids.add(modelInfo.model.uuid);
+                modelInfo.status = STATUS_LOADED;
+            } else if (operation == 1 && modelInfo.status == STATUS_LOADED) {
+                // Start the sound model
+                int r = soundTriggerService.startRecognition(new ParcelUuid(modelInfo.model.uuid),
+                        spyCallback, config);
+                assertEquals("Could Not Start Recognition with code: " + r,
+                        android.hardware.soundtrigger.SoundTrigger.STATUS_OK, r);
+                modelInfo.status = STATUS_STARTED;
+            } else if (operation == 2 && modelInfo.status == STATUS_STARTED) {
+                // Send trigger to stub HAL
+                Socket socket = new Socket(InetAddress.getLocalHost(), 14035);
+                DataOutputStream out = new DataOutputStream(socket.getOutputStream());
+                out.writeBytes("trig " + modelInfo.model.uuid + "\r\n");
+                out.flush();
+                socket.close();
+
+                // Verify trigger was received
+                verify(spyCallback, timeout(100)).onGenericSoundTriggerDetected(any());
+                reset(spyCallback);
+            } else if (operation == 3 && modelInfo.status == STATUS_STARTED) {
+                // Stop recognition
+                int r = soundTriggerService.stopRecognition(new ParcelUuid(modelInfo.model.uuid),
+                        spyCallback);
+                assertEquals("Could Not Stop Recognition with code: " + r,
+                        android.hardware.soundtrigger.SoundTrigger.STATUS_OK, r);
+                modelInfo.status = STATUS_LOADED;
+            } else if (operation == 4 && modelInfo.status != STATUS_UNLOADED) {
+                // Delete sound model
+                soundTriggerService.deleteSoundModel(new ParcelUuid(modelInfo.model.uuid));
+                loadedModelUuids.remove(modelInfo.model.uuid);
+
+                // Confirm it was deleted
+                GenericSoundModel returnedModel =
+                        soundTriggerService.getSoundModel(new ParcelUuid(modelInfo.model.uuid));
+                assertEquals(null, returnedModel);
+                modelInfo.status = STATUS_UNLOADED;
+            }
+        }
+    }
 
     public class TestRecognitionStatusCallback extends IRecognitionStatusCallback.Stub {
         @Override
diff --git a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
index 7faee1b..f9e008e 100644
--- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
+++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
@@ -403,8 +403,15 @@
     }
 
     @Override
-    public void setNewConfiguration(Configuration arg0) throws RemoteException {
+    public int[] setNewConfiguration(Configuration arg0) throws RemoteException {
         // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Rect getBoundsForNewConfiguration(int stackId) throws RemoteException {
+        // TODO Auto-generated method stub
+        return null;
     }
 
     @Override