Merge "Fix rotation displays frame N-1 briefly while rotating" into ics-mr1
diff --git a/api/current.txt b/api/current.txt
index 4e41c29..cc7f0798 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -3235,6 +3235,7 @@
     method public final android.app.Fragment getTargetFragment();
     method public final int getTargetRequestCode();
     method public final java.lang.CharSequence getText(int);
+    method public boolean getUserVisibleHint();
     method public android.view.View getView();
     method public final int hashCode();
     method public static android.app.Fragment instantiate(android.content.Context, java.lang.String);
@@ -3245,7 +3246,6 @@
     method public final boolean isInLayout();
     method public final boolean isRemoving();
     method public final boolean isResumed();
-    method public boolean isStartDeferred();
     method public final boolean isVisible();
     method public void onActivityCreated(android.os.Bundle);
     method public void onActivityResult(int, int, android.content.Intent);
@@ -3281,8 +3281,8 @@
     method public void setInitialSavedState(android.app.Fragment.SavedState);
     method public void setMenuVisibility(boolean);
     method public void setRetainInstance(boolean);
-    method public void setStartDeferred(boolean);
     method public void setTargetFragment(android.app.Fragment, int);
+    method public void setUserVisibleHint(boolean);
     method public void startActivity(android.content.Intent);
     method public void startActivityForResult(android.content.Intent, int);
     method public void unregisterForContextMenu(android.view.View);
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index 9b01b7f..473a2d1 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -458,6 +458,9 @@
     // have been started and their loaders are finished.
     boolean mDeferStart;
 
+    // Hint provided by the app that this fragment is currently visible to the user.
+    boolean mUserVisibleHint = true;
+
     LoaderManagerImpl mLoaderManager;
     boolean mLoadersStarted;
     boolean mCheckedForLoaderManager;
@@ -915,31 +918,32 @@
     }
 
     /**
-     * Set whether this fragment should enter the started state as normal or if
-     * start should be deferred until a system-determined convenient time, such
-     * as after any loaders have completed their work.
+     * Set a hint to the system about whether this fragment's UI is currently visible
+     * to the user. This hint defaults to true and is persistent across fragment instance
+     * state save and restore.
      *
-     * <p>This option is not sticky across fragment starts; after a deferred start
-     * completes this option will be set to false.</p>
+     * <p>An app may set this to false to indicate that the fragment's UI is
+     * scrolled out of visibility or is otherwise not directly visible to the user.
+     * This may be used by the system to prioritize operations such as fragment lifecycle updates
+     * or loader ordering behavior.</p>
      *
-     * @param deferResume true if this fragment can defer its resume until after others
+     * @param isVisibleToUser true if this fragment's UI is currently visible to the user (default),
+     *                        false if it is not.
      */
-    public void setStartDeferred(boolean deferResume) {
-        if (mDeferStart && !deferResume) {
+    public void setUserVisibleHint(boolean isVisibleToUser) {
+        if (!mUserVisibleHint && isVisibleToUser && mState < STARTED) {
             mFragmentManager.performPendingDeferredStart(this);
         }
-        mDeferStart = deferResume;
+        mUserVisibleHint = isVisibleToUser;
+        mDeferStart = !isVisibleToUser;
     }
 
     /**
-     * Returns true if this fragment's move to the started state has been deferred.
-     * If this returns true it will be started once other fragments' loaders
-     * have finished running.
-     *
-     * @return true if this fragment's start has been deferred.
+     * @return The current value of the user-visible hint on this fragment.
+     * @see #setUserVisibleHint(boolean)
      */
-    public boolean isStartDeferred() {
-        return mDeferStart;
+    public boolean getUserVisibleHint() {
+        return mUserVisibleHint;
     }
 
     /**
@@ -1477,7 +1481,8 @@
                 writer.print(" mMenuVisible="); writer.print(mMenuVisible);
                 writer.print(" mHasMenu="); writer.println(mHasMenu);
         writer.print(prefix); writer.print("mRetainInstance="); writer.print(mRetainInstance);
-                writer.print(" mRetaining="); writer.println(mRetaining);
+                writer.print(" mRetaining="); writer.print(mRetaining);
+                writer.print(" mUserVisibleHint="); writer.println(mUserVisibleHint);
         if (mFragmentManager != null) {
             writer.print(prefix); writer.print("mFragmentManager=");
                     writer.println(mFragmentManager);
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index c4ba778..a8c9cba 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -382,6 +382,7 @@
     static final String TARGET_REQUEST_CODE_STATE_TAG = "android:target_req_state";
     static final String TARGET_STATE_TAG = "android:target_state";
     static final String VIEW_STATE_TAG = "android:view_state";
+    static final String USER_VISIBLE_HINT_TAG = "android:user_visible_hint";
 
     ArrayList<Runnable> mPendingActions;
     Runnable[] mTmpActions;
@@ -406,6 +407,7 @@
     boolean mStateSaved;
     boolean mDestroyed;
     String mNoTransactionsBecause;
+    boolean mHavePendingDeferredStart;
     
     // Temporary vars for state save and restore.
     Bundle mStateBundle = null;
@@ -711,6 +713,11 @@
     
     public void performPendingDeferredStart(Fragment f) {
         if (f.mDeferStart) {
+            if (mExecutingActions) {
+                // Wait until we're done executing our pending transactions
+                mHavePendingDeferredStart = true;
+                return;
+            }
             f.mDeferStart = false;
             moveToState(f, mCurState, 0, 0);
         }
@@ -757,6 +764,14 @@
                             f.mTargetRequestCode = f.mSavedFragmentState.getInt(
                                     FragmentManagerImpl.TARGET_REQUEST_CODE_STATE_TAG, 0);
                         }
+                        f.mUserVisibleHint = f.mSavedFragmentState.getBoolean(
+                                FragmentManagerImpl.USER_VISIBLE_HINT_TAG, true);
+                        if (!f.mUserVisibleHint) {
+                            f.mDeferStart = true;
+                            if (newState > Fragment.STOPPED) {
+                                newState = Fragment.STOPPED;
+                            }
+                        }
                     }
                     f.mActivity = mActivity;
                     f.mFragmentManager = mActivity.mFragments;
@@ -1343,7 +1358,7 @@
             
             synchronized (this) {
                 if (mPendingActions == null || mPendingActions.size() == 0) {
-                    return didSomething;
+                    break;
                 }
                 
                 numActions = mPendingActions.size();
@@ -1363,8 +1378,23 @@
             mExecutingActions = false;
             didSomething = true;
         }
+
+        if (mHavePendingDeferredStart) {
+            boolean loadersRunning = false;
+            for (int i=0; i<mActive.size(); i++) {
+                Fragment f = mActive.get(i);
+                if (f != null && f.mLoaderManager != null) {
+                    loadersRunning |= f.mLoaderManager.hasRunningLoaders();
+                }
+            }
+            if (!loadersRunning) {
+                mHavePendingDeferredStart = false;
+                startPendingDeferredFragments();
+            }
+        }
+        return didSomething;
     }
-    
+
     void reportBackStackChanged() {
         if (mBackStackChangeListeners != null) {
             for (int i=0; i<mBackStackChangeListeners.size(); i++) {
@@ -1500,6 +1530,10 @@
             result.putSparseParcelableArray(
                     FragmentManagerImpl.VIEW_STATE_TAG, f.mSavedViewState);
         }
+        if (!f.mUserVisibleHint) {
+            // Only add this if it's not the default value
+            result.putBoolean(FragmentManagerImpl.USER_VISIBLE_HINT_TAG, f.mUserVisibleHint);
+        }
 
         return result;
     }
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index be87946..6ecc640 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -105,6 +105,18 @@
     void removeRoute(String iface, in RouteInfo route);
 
     /**
+     * Add the specified route to a secondary interface
+     * This will go into a special route table to be accessed
+     * via ip rules
+     */
+    void addSecondaryRoute(String iface, in RouteInfo route);
+
+    /**
+     * Remove the specified secondary route.
+     */
+    void removeSecondaryRoute(String iface, in RouteInfo route);
+
+    /**
      * Shuts down the service
      */
     void shutdown();
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 58b63fe..f0dc732 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -4119,20 +4119,6 @@
     }
 
     private void drawContent(Canvas canvas, boolean drawRings) {
-        // Update the buttons in the picture, so when we draw the picture
-        // to the screen, they are in the correct state.
-        // Tell the native side if user is a) touching the screen,
-        // b) pressing the trackball down, or c) pressing the enter key
-        // If the cursor is on a button, we need to draw it in the pressed
-        // state.
-        // If mNativeClass is 0, we should not reach here, so we do not
-        // need to check it again.
-        boolean pressed = (mTouchMode == TOUCH_SHORTPRESS_START_MODE
-                || mTouchMode == TOUCH_INIT_MODE
-                || mTouchMode == TOUCH_SHORTPRESS_MODE);
-        recordButtons(canvas,
-                hasFocus() && hasWindowFocus(), (pressed && !USE_WEBKIT_RINGS)
-                || mTrackballDown || mGotCenterDown, false);
         drawCoreAndCursorRing(canvas, mBackgroundColor,
                 mDrawCursorRing && drawRings);
     }
@@ -5193,9 +5179,6 @@
                 mGotCenterDown = true;
                 mPrivateHandler.sendMessageDelayed(mPrivateHandler
                         .obtainMessage(LONG_PRESS_CENTER), LONG_PRESS_TIMEOUT);
-                // Already checked mNativeClass, so we do not need to check it
-                // again.
-                recordButtons(null, hasFocus() && hasWindowFocus(), true, true);
                 if (!wantsKeyEvents) return true;
             }
             // Bubble up the key event as WebView doesn't handle it
@@ -5631,9 +5614,6 @@
                 // drawing the cursor ring
                 mDrawCursorRing = true;
                 setFocusControllerActive(true);
-                if (mNativeClass != 0) {
-                    recordButtons(null, true, false, true);
-                }
             } else {
                 if (!inEditingMode()) {
                     // If our window gained focus, but we do not have it, do not
@@ -5659,9 +5639,6 @@
             mKeysPressed.clear();
             mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
             mTouchMode = TOUCH_DONE_MODE;
-            if (mNativeClass != 0) {
-                recordButtons(null, false, false, true);
-            }
             setFocusControllerActive(false);
         }
         invalidate();
@@ -5717,9 +5694,6 @@
             // the cursor ring
             if (hasWindowFocus()) {
                 mDrawCursorRing = true;
-                if (mNativeClass != 0) {
-                    recordButtons(null, true, false, true);
-                }
                 setFocusControllerActive(true);
             //} else {
                 // The WebView has gained focus while we do not have
@@ -5731,9 +5705,6 @@
             // true if we are in editing mode), stop drawing the cursor ring.
             if (!inEditingMode()) {
                 mDrawCursorRing = false;
-                if (mNativeClass != 0) {
-                    recordButtons(null, false, false, true);
-                }
                 setFocusControllerActive(false);
             }
             mKeysPressed.clear();
@@ -6847,7 +6818,6 @@
             if (mNativeClass == 0) {
                 return false;
             }
-            recordButtons(null, hasFocus() && hasWindowFocus(), true, true);
             if (time - mLastCursorTime <= TRACKBALL_TIMEOUT
                     && !mLastCursorBounds.equals(nativeGetCursorRingBounds())) {
                 nativeSelectBestAt(mLastCursorBounds);
@@ -9442,24 +9412,6 @@
         return nativeTileProfilingGetFloat(frame, tile, key);
     }
 
-    /**
-     * Helper method to deal with differences between hardware and software rendering
-     */
-    private void recordButtons(Canvas canvas, boolean focus, boolean pressed,
-            boolean inval) {
-        boolean isHardwareAccel = canvas != null
-                ? canvas.isHardwareAccelerated()
-                : isHardwareAccelerated();
-        if (isHardwareAccel) {
-            // We never want to change button state if we are hardware accelerated,
-            // but we DO want to invalidate as necessary so that the GL ring
-            // can be drawn
-            nativeRecordButtons(mNativeClass, false, false, inval);
-        } else {
-            nativeRecordButtons(mNativeClass, focus, pressed, inval);
-        }
-    }
-
     private native int nativeCacheHitFramePointer();
     private native boolean  nativeCacheHitIsPlugin();
     private native Rect nativeCacheHitNodeBounds();
@@ -9556,8 +9508,6 @@
     private native boolean  nativePointInNavCache(int x, int y, int slop);
     // Like many other of our native methods, you must make sure that
     // mNativeClass is not null before calling this method.
-    private native void     nativeRecordButtons(int nativeInstance,
-            boolean focused, boolean pressed, boolean invalidate);
     private native void     nativeResetSelection();
     private native Point    nativeSelectableText();
     private native void     nativeSelectAll();
diff --git a/core/java/android/widget/SearchView.java b/core/java/android/widget/SearchView.java
index e84ae97..f524ef0 100644
--- a/core/java/android/widget/SearchView.java
+++ b/core/java/android/widget/SearchView.java
@@ -728,7 +728,8 @@
 
     private void updateSubmitButton(boolean hasText) {
         int visibility = GONE;
-        if (isSubmitAreaEnabled() && hasFocus() && (hasText || !mVoiceButtonEnabled)) {
+        if (mSubmitButtonEnabled && isSubmitAreaEnabled() && hasFocus()
+                && (hasText || !mVoiceButtonEnabled)) {
             visibility = VISIBLE;
         }
         mSubmitButton.setVisibility(visibility);
@@ -1082,9 +1083,7 @@
         CharSequence text = mQueryTextView.getText();
         mUserQuery = text;
         boolean hasText = !TextUtils.isEmpty(text);
-        if (isSubmitButtonEnabled()) {
-            updateSubmitButton(hasText);
-        }
+        updateSubmitButton(hasText);
         updateVoiceButton(!hasText);
         updateCloseButton();
         updateSubmitArea();
diff --git a/core/res/res/drawable-hdpi/btn_default_disabled_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_default_disabled_focused_holo_dark.9.png
index f57126b..13ab8f7 100644
--- a/core/res/res/drawable-hdpi/btn_default_disabled_focused_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_default_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_disabled_focused_holo_light.9.png b/core/res/res/drawable-hdpi/btn_default_disabled_focused_holo_light.9.png
index f57126b..13ab8f7 100644
--- a/core/res/res/drawable-hdpi/btn_default_disabled_focused_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_default_disabled_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_disabled_holo.9.png b/core/res/res/drawable-hdpi/btn_default_disabled_holo.9.png
index c5adc38..1d76bb5 100644
--- a/core/res/res/drawable-hdpi/btn_default_disabled_holo.9.png
+++ b/core/res/res/drawable-hdpi/btn_default_disabled_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_default_disabled_holo_dark.9.png
index 05cb4e4..8ebd761 100644
--- a/core/res/res/drawable-hdpi/btn_default_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_default_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/btn_default_disabled_holo_light.9.png
index 05cb4e4..8ebd761 100644
--- a/core/res/res/drawable-hdpi/btn_default_disabled_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_default_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_focused_holo.9.png b/core/res/res/drawable-hdpi/btn_default_focused_holo.9.png
index efcfa26..b405d81 100644
--- a/core/res/res/drawable-hdpi/btn_default_focused_holo.9.png
+++ b/core/res/res/drawable-hdpi/btn_default_focused_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_default_focused_holo_dark.9.png
index 3b9d734..fee599a 100644
--- a/core/res/res/drawable-hdpi/btn_default_focused_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_default_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_focused_holo_light.9.png b/core/res/res/drawable-hdpi/btn_default_focused_holo_light.9.png
index 3b9d734..fee599a 100644
--- a/core/res/res/drawable-hdpi/btn_default_focused_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_default_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_normal_holo.9.png b/core/res/res/drawable-hdpi/btn_default_normal_holo.9.png
index 490b6f5..dddfc26 100644
--- a/core/res/res/drawable-hdpi/btn_default_normal_holo.9.png
+++ b/core/res/res/drawable-hdpi/btn_default_normal_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_normal_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_default_normal_holo_dark.9.png
index b2851834..ab40fa7 100644
--- a/core/res/res/drawable-hdpi/btn_default_normal_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_default_normal_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_normal_holo_light.9.png b/core/res/res/drawable-hdpi/btn_default_normal_holo_light.9.png
index b2851834..8077921 100644
--- a/core/res/res/drawable-hdpi/btn_default_normal_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_default_normal_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_pressed_holo.9.png b/core/res/res/drawable-hdpi/btn_default_pressed_holo.9.png
index 57f2026..0d8f8ba 100644
--- a/core/res/res/drawable-hdpi/btn_default_pressed_holo.9.png
+++ b/core/res/res/drawable-hdpi/btn_default_pressed_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_pressed_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_default_pressed_holo_dark.9.png
index 13d154f..baf7018 100644
--- a/core/res/res/drawable-hdpi/btn_default_pressed_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_default_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_default_pressed_holo_light.9.png b/core/res/res/drawable-hdpi/btn_default_pressed_holo_light.9.png
index 13d154f..baf7018 100644
--- a/core/res/res/drawable-hdpi/btn_default_pressed_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_default_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_off_disabled_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_toggle_off_disabled_focused_holo_dark.9.png
index 15b9fb9..7a24c9b 100644
--- a/core/res/res/drawable-hdpi/btn_toggle_off_disabled_focused_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_off_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_off_disabled_focused_holo_light.9.png b/core/res/res/drawable-hdpi/btn_toggle_off_disabled_focused_holo_light.9.png
index 4d83d65..7a24c9b 100644
--- a/core/res/res/drawable-hdpi/btn_toggle_off_disabled_focused_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_off_disabled_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_off_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_toggle_off_disabled_holo_dark.9.png
index e06aef0..93c6d1b 100644
--- a/core/res/res/drawable-hdpi/btn_toggle_off_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_off_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_off_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/btn_toggle_off_disabled_holo_light.9.png
index d81d346..93c6d1b 100644
--- a/core/res/res/drawable-hdpi/btn_toggle_off_disabled_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_off_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_off_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_toggle_off_focused_holo_dark.9.png
index 9f027b7..120f963 100644
--- a/core/res/res/drawable-hdpi/btn_toggle_off_focused_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_off_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_off_focused_holo_light.9.png b/core/res/res/drawable-hdpi/btn_toggle_off_focused_holo_light.9.png
index a7582d6..120f963 100644
--- a/core/res/res/drawable-hdpi/btn_toggle_off_focused_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_off_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_off_normal_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_toggle_off_normal_holo_dark.9.png
index 21be9f4..6b106fb 100644
--- a/core/res/res/drawable-hdpi/btn_toggle_off_normal_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_off_normal_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_off_normal_holo_light.9.png b/core/res/res/drawable-hdpi/btn_toggle_off_normal_holo_light.9.png
index 791b318..6b106fb 100644
--- a/core/res/res/drawable-hdpi/btn_toggle_off_normal_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_off_normal_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_off_pressed_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_toggle_off_pressed_holo_dark.9.png
index 8cf35b2..a1b7003 100644
--- a/core/res/res/drawable-hdpi/btn_toggle_off_pressed_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_off_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_off_pressed_holo_light.9.png b/core/res/res/drawable-hdpi/btn_toggle_off_pressed_holo_light.9.png
index e475b49..a1b7003 100644
--- a/core/res/res/drawable-hdpi/btn_toggle_off_pressed_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_off_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_on_disabled_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_toggle_on_disabled_focused_holo_dark.9.png
index 7996db4..7176a6b 100644
--- a/core/res/res/drawable-hdpi/btn_toggle_on_disabled_focused_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_on_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_on_disabled_focused_holo_light.9.png b/core/res/res/drawable-hdpi/btn_toggle_on_disabled_focused_holo_light.9.png
index 7996db4..7176a6b 100644
--- a/core/res/res/drawable-hdpi/btn_toggle_on_disabled_focused_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_on_disabled_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_on_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_toggle_on_disabled_holo_dark.9.png
index 906a229..7fba6a5 100644
--- a/core/res/res/drawable-hdpi/btn_toggle_on_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_on_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_on_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/btn_toggle_on_disabled_holo_light.9.png
index 906a229..7fba6a5 100644
--- a/core/res/res/drawable-hdpi/btn_toggle_on_disabled_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_on_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_on_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_toggle_on_focused_holo_dark.9.png
index 56bd325..8bbfe9f 100644
--- a/core/res/res/drawable-hdpi/btn_toggle_on_focused_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_on_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_on_focused_holo_light.9.png b/core/res/res/drawable-hdpi/btn_toggle_on_focused_holo_light.9.png
index 56bd325..8bbfe9f 100644
--- a/core/res/res/drawable-hdpi/btn_toggle_on_focused_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_on_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_on_normal_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_toggle_on_normal_holo_dark.9.png
index 61b2efc..28f0ee6 100644
--- a/core/res/res/drawable-hdpi/btn_toggle_on_normal_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_on_normal_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_on_normal_holo_light.9.png b/core/res/res/drawable-hdpi/btn_toggle_on_normal_holo_light.9.png
index 61b2efc..28f0ee6 100644
--- a/core/res/res/drawable-hdpi/btn_toggle_on_normal_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_on_normal_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_on_pressed_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_toggle_on_pressed_holo_dark.9.png
index d2e4ca8..c4c41a3 100644
--- a/core/res/res/drawable-hdpi/btn_toggle_on_pressed_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_on_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_toggle_on_pressed_holo_light.9.png b/core/res/res/drawable-hdpi/btn_toggle_on_pressed_holo_light.9.png
index d2e4ca8..c4c41a3 100644
--- a/core/res/res/drawable-hdpi/btn_toggle_on_pressed_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_toggle_on_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_next.png b/core/res/res/drawable-hdpi/ic_media_next.png
index f5ba824..6e27b81 100644
--- a/core/res/res/drawable-hdpi/ic_media_next.png
+++ b/core/res/res/drawable-hdpi/ic_media_next.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_pause.png b/core/res/res/drawable-hdpi/ic_media_pause.png
index 671148e..1d465a4 100644
--- a/core/res/res/drawable-hdpi/ic_media_pause.png
+++ b/core/res/res/drawable-hdpi/ic_media_pause.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_play.png b/core/res/res/drawable-hdpi/ic_media_play.png
index c2e366a..2746d17 100644
--- a/core/res/res/drawable-hdpi/ic_media_play.png
+++ b/core/res/res/drawable-hdpi/ic_media_play.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_previous.png b/core/res/res/drawable-hdpi/ic_media_previous.png
index 40ecb00..85b3766 100644
--- a/core/res/res/drawable-hdpi/ic_media_previous.png
+++ b/core/res/res/drawable-hdpi/ic_media_previous.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_stop.png b/core/res/res/drawable-hdpi/ic_media_stop.png
index ec0c1ea..a0ff136 100644
--- a/core/res/res/drawable-hdpi/ic_media_stop.png
+++ b/core/res/res/drawable-hdpi/ic_media_stop.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/list_focused_holo.9.png b/core/res/res/drawable-hdpi/list_focused_holo.9.png
index 516f5c7..5552708 100644
--- a/core/res/res/drawable-hdpi/list_focused_holo.9.png
+++ b/core/res/res/drawable-hdpi/list_focused_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_down_focused_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_down_focused_holo_dark.png
index 9ff4cce..5717bee 100644
--- a/core/res/res/drawable-hdpi/numberpicker_down_focused_holo_dark.png
+++ b/core/res/res/drawable-hdpi/numberpicker_down_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_down_focused_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_down_focused_holo_light.png
index a556e00..e874330 100644
--- a/core/res/res/drawable-hdpi/numberpicker_down_focused_holo_light.png
+++ b/core/res/res/drawable-hdpi/numberpicker_down_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_down_longpressed_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_down_longpressed_holo_dark.png
index 9353511..96a6c8a 100644
--- a/core/res/res/drawable-hdpi/numberpicker_down_longpressed_holo_dark.png
+++ b/core/res/res/drawable-hdpi/numberpicker_down_longpressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_down_longpressed_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_down_longpressed_holo_light.png
index 9353511..96a6c8a 100644
--- a/core/res/res/drawable-hdpi/numberpicker_down_longpressed_holo_light.png
+++ b/core/res/res/drawable-hdpi/numberpicker_down_longpressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_down_normal_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_down_normal_holo_dark.png
index 2ca591f..4631d85 100644
--- a/core/res/res/drawable-hdpi/numberpicker_down_normal_holo_dark.png
+++ b/core/res/res/drawable-hdpi/numberpicker_down_normal_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_down_normal_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_down_normal_holo_light.png
index 1275a2f..39c7af4 100644
--- a/core/res/res/drawable-hdpi/numberpicker_down_normal_holo_light.png
+++ b/core/res/res/drawable-hdpi/numberpicker_down_normal_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_up_focused_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_up_focused_holo_dark.png
index df374c4..b06017e 100644
--- a/core/res/res/drawable-hdpi/numberpicker_up_focused_holo_dark.png
+++ b/core/res/res/drawable-hdpi/numberpicker_up_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_up_focused_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_up_focused_holo_light.png
index d6b9c67..a1000f8 100644
--- a/core/res/res/drawable-hdpi/numberpicker_up_focused_holo_light.png
+++ b/core/res/res/drawable-hdpi/numberpicker_up_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_up_longpressed_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_up_longpressed_holo_dark.png
index 69474e3..b3d6706 100644
--- a/core/res/res/drawable-hdpi/numberpicker_up_longpressed_holo_dark.png
+++ b/core/res/res/drawable-hdpi/numberpicker_up_longpressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_up_longpressed_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_up_longpressed_holo_light.png
index 69474e3..b3d6706 100644
--- a/core/res/res/drawable-hdpi/numberpicker_up_longpressed_holo_light.png
+++ b/core/res/res/drawable-hdpi/numberpicker_up_longpressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_up_normal_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_up_normal_holo_dark.png
index a2fc32a..9ee35c7 100644
--- a/core/res/res/drawable-hdpi/numberpicker_up_normal_holo_dark.png
+++ b/core/res/res/drawable-hdpi/numberpicker_up_normal_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_up_normal_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_up_normal_holo_light.png
index c4b58b7..4da4fa7 100644
--- a/core/res/res/drawable-hdpi/numberpicker_up_normal_holo_light.png
+++ b/core/res/res/drawable-hdpi/numberpicker_up_normal_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/presence_away.png b/core/res/res/drawable-hdpi/presence_away.png
index 455fec1..c39d3a8 100644
--- a/core/res/res/drawable-hdpi/presence_away.png
+++ b/core/res/res/drawable-hdpi/presence_away.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/quickcontact_badge_overlay_focused_dark.9.png b/core/res/res/drawable-hdpi/quickcontact_badge_overlay_focused_dark.9.png
new file mode 100644
index 0000000..cbd8c5c
--- /dev/null
+++ b/core/res/res/drawable-hdpi/quickcontact_badge_overlay_focused_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/quickcontact_badge_overlay_focused_light.9.png b/core/res/res/drawable-hdpi/quickcontact_badge_overlay_focused_light.9.png
new file mode 100644
index 0000000..f7f4ba3
--- /dev/null
+++ b/core/res/res/drawable-hdpi/quickcontact_badge_overlay_focused_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/quickcontact_badge_overlay_normal_dark.9.png b/core/res/res/drawable-hdpi/quickcontact_badge_overlay_normal_dark.9.png
index db23635..a82e7ac 100644
--- a/core/res/res/drawable-hdpi/quickcontact_badge_overlay_normal_dark.9.png
+++ b/core/res/res/drawable-hdpi/quickcontact_badge_overlay_normal_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/quickcontact_badge_overlay_normal_light.9.png b/core/res/res/drawable-hdpi/quickcontact_badge_overlay_normal_light.9.png
index 269a456..db4ce80 100644
--- a/core/res/res/drawable-hdpi/quickcontact_badge_overlay_normal_light.9.png
+++ b/core/res/res/drawable-hdpi/quickcontact_badge_overlay_normal_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/quickcontact_badge_overlay_pressed_dark.9.png b/core/res/res/drawable-hdpi/quickcontact_badge_overlay_pressed_dark.9.png
index d997b36..0c689ff 100644
--- a/core/res/res/drawable-hdpi/quickcontact_badge_overlay_pressed_dark.9.png
+++ b/core/res/res/drawable-hdpi/quickcontact_badge_overlay_pressed_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/quickcontact_badge_overlay_pressed_light.9.png b/core/res/res/drawable-hdpi/quickcontact_badge_overlay_pressed_light.9.png
index 8ed5eb7..f3999204 100644
--- a/core/res/res/drawable-hdpi/quickcontact_badge_overlay_pressed_light.9.png
+++ b/core/res/res/drawable-hdpi/quickcontact_badge_overlay_pressed_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_ab_default_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_ab_default_holo_dark.9.png
index b306f22..eb28ff9 100644
--- a/core/res/res/drawable-hdpi/spinner_ab_default_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/spinner_ab_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_ab_default_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_ab_default_holo_light.9.png
index 21cf17e..d281adb 100644
--- a/core/res/res/drawable-hdpi/spinner_ab_default_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/spinner_ab_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_ab_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_ab_disabled_holo_dark.9.png
index b9833f3..b298586 100644
--- a/core/res/res/drawable-hdpi/spinner_ab_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/spinner_ab_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_ab_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_ab_disabled_holo_light.9.png
index f68b662..4215396 100644
--- a/core/res/res/drawable-hdpi/spinner_ab_disabled_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/spinner_ab_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_ab_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_ab_focused_holo_dark.9.png
index a76f4ab..a280eab 100644
--- a/core/res/res/drawable-hdpi/spinner_ab_focused_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/spinner_ab_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_ab_focused_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_ab_focused_holo_light.9.png
index ecfe9cc..f8d619b 100644
--- a/core/res/res/drawable-hdpi/spinner_ab_focused_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/spinner_ab_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_ab_pressed_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_ab_pressed_holo_dark.9.png
index 51a5226..955a2f3 100644
--- a/core/res/res/drawable-hdpi/spinner_ab_pressed_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/spinner_ab_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_ab_pressed_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_ab_pressed_holo_light.9.png
index a24da91..6c22e22 100644
--- a/core/res/res/drawable-hdpi/spinner_ab_pressed_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/spinner_ab_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_default_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_default_holo_dark.9.png
index 09fc9c3..34a88df 100644
--- a/core/res/res/drawable-hdpi/spinner_default_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/spinner_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_default_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_default_holo_light.9.png
index bb257b9..b03842d 100644
--- a/core/res/res/drawable-hdpi/spinner_default_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/spinner_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_disabled_holo_dark.9.png
index df49a4d..2d306d9 100644
--- a/core/res/res/drawable-hdpi/spinner_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/spinner_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_disabled_holo_light.9.png
index a6cb992..720c417 100644
--- a/core/res/res/drawable-hdpi/spinner_disabled_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/spinner_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_focused_holo_dark.9.png
index 09f8cef..b038fba 100644
--- a/core/res/res/drawable-hdpi/spinner_focused_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/spinner_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_focused_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_focused_holo_light.9.png
index 58c67a0..ccffda9 100644
--- a/core/res/res/drawable-hdpi/spinner_focused_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/spinner_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_pressed_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_pressed_holo_dark.9.png
index a472338..f638d5e 100644
--- a/core/res/res/drawable-hdpi/spinner_pressed_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/spinner_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_pressed_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_pressed_holo_light.9.png
index ed9f6f6..0aedd25 100644
--- a/core/res/res/drawable-hdpi/spinner_pressed_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/spinner_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/switch_bg_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/switch_bg_disabled_holo_dark.9.png
index e886812..f2196fd 100644
--- a/core/res/res/drawable-hdpi/switch_bg_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/switch_bg_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/switch_bg_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/switch_bg_disabled_holo_light.9.png
index 3e92cf0..f111d82 100644
--- a/core/res/res/drawable-hdpi/switch_bg_disabled_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/switch_bg_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/switch_bg_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/switch_bg_focused_holo_dark.9.png
index 962cefb..4e2ae0f 100644
--- a/core/res/res/drawable-hdpi/switch_bg_focused_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/switch_bg_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/switch_bg_focused_holo_light.9.png b/core/res/res/drawable-hdpi/switch_bg_focused_holo_light.9.png
index e05b345..479e504 100644
--- a/core/res/res/drawable-hdpi/switch_bg_focused_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/switch_bg_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/switch_thumb_activated_holo_dark.9.png b/core/res/res/drawable-hdpi/switch_thumb_activated_holo_dark.9.png
index 0bce767..2fc475b 100644
--- a/core/res/res/drawable-hdpi/switch_thumb_activated_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/switch_thumb_activated_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/switch_thumb_activated_holo_light.9.png b/core/res/res/drawable-hdpi/switch_thumb_activated_holo_light.9.png
index 3b9c048..5adecf1 100644
--- a/core/res/res/drawable-hdpi/switch_thumb_activated_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/switch_thumb_activated_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/switch_thumb_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/switch_thumb_disabled_holo_dark.9.png
index a4bd074..457fa84 100644
--- a/core/res/res/drawable-hdpi/switch_thumb_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/switch_thumb_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/switch_thumb_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/switch_thumb_disabled_holo_light.9.png
index 587bf4e..c3cfc29 100644
--- a/core/res/res/drawable-hdpi/switch_thumb_disabled_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/switch_thumb_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/switch_thumb_holo_dark.9.png b/core/res/res/drawable-hdpi/switch_thumb_holo_dark.9.png
index a86be03..d0e1806 100644
--- a/core/res/res/drawable-hdpi/switch_thumb_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/switch_thumb_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/switch_thumb_holo_light.9.png b/core/res/res/drawable-hdpi/switch_thumb_holo_light.9.png
index e3b0729..c30506d 100644
--- a/core/res/res/drawable-hdpi/switch_thumb_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/switch_thumb_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/switch_thumb_pressed_holo_dark.9.png b/core/res/res/drawable-hdpi/switch_thumb_pressed_holo_dark.9.png
index 4b56420..9106687 100644
--- a/core/res/res/drawable-hdpi/switch_thumb_pressed_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/switch_thumb_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/switch_thumb_pressed_holo_light.9.png b/core/res/res/drawable-hdpi/switch_thumb_pressed_holo_light.9.png
index 741674d..2bdda56 100644
--- a/core/res/res/drawable-hdpi/switch_thumb_pressed_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/switch_thumb_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/sym_keyboard_num0_no_plus.png b/core/res/res/drawable-hdpi/sym_keyboard_num0_no_plus.png
index 2aad23c..0e5f1e2 100644
--- a/core/res/res/drawable-hdpi/sym_keyboard_num0_no_plus.png
+++ b/core/res/res/drawable-hdpi/sym_keyboard_num0_no_plus.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_disabled_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_default_disabled_focused_holo_dark.9.png
index 74ed9b5..38d00db 100644
--- a/core/res/res/drawable-mdpi/btn_default_disabled_focused_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_default_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_disabled_focused_holo_light.9.png b/core/res/res/drawable-mdpi/btn_default_disabled_focused_holo_light.9.png
index 74ed9b5..38d00db 100644
--- a/core/res/res/drawable-mdpi/btn_default_disabled_focused_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_default_disabled_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_disabled_holo.9.png b/core/res/res/drawable-mdpi/btn_default_disabled_holo.9.png
index abf6493..85c2c4f 100644
--- a/core/res/res/drawable-mdpi/btn_default_disabled_holo.9.png
+++ b/core/res/res/drawable-mdpi/btn_default_disabled_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_default_disabled_holo_dark.9.png
index 3b5d850..4a6351a 100644
--- a/core/res/res/drawable-mdpi/btn_default_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_default_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/btn_default_disabled_holo_light.9.png
index 3b5d850..4a6351a 100644
--- a/core/res/res/drawable-mdpi/btn_default_disabled_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_default_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_focused_holo.9.png b/core/res/res/drawable-mdpi/btn_default_focused_holo.9.png
index 71b052b..89d7a0e 100644
--- a/core/res/res/drawable-mdpi/btn_default_focused_holo.9.png
+++ b/core/res/res/drawable-mdpi/btn_default_focused_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_default_focused_holo_dark.9.png
index 215002b..39950f6 100644
--- a/core/res/res/drawable-mdpi/btn_default_focused_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_default_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_focused_holo_light.9.png b/core/res/res/drawable-mdpi/btn_default_focused_holo_light.9.png
index 215002b..39950f6 100644
--- a/core/res/res/drawable-mdpi/btn_default_focused_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_default_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_normal_holo.9.png b/core/res/res/drawable-mdpi/btn_default_normal_holo.9.png
index 87c62ff..0895d57 100644
--- a/core/res/res/drawable-mdpi/btn_default_normal_holo.9.png
+++ b/core/res/res/drawable-mdpi/btn_default_normal_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_normal_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_default_normal_holo_dark.9.png
index dd8ee9d..54c6354 100644
--- a/core/res/res/drawable-mdpi/btn_default_normal_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_default_normal_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_normal_holo_light.9.png b/core/res/res/drawable-mdpi/btn_default_normal_holo_light.9.png
index dd8ee9d..50070ed 100644
--- a/core/res/res/drawable-mdpi/btn_default_normal_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_default_normal_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_pressed_holo.9.png b/core/res/res/drawable-mdpi/btn_default_pressed_holo.9.png
index 51821fa..6a1b6a1 100644
--- a/core/res/res/drawable-mdpi/btn_default_pressed_holo.9.png
+++ b/core/res/res/drawable-mdpi/btn_default_pressed_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_pressed_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_default_pressed_holo_dark.9.png
index 2ca4c3b..13a1fdd 100644
--- a/core/res/res/drawable-mdpi/btn_default_pressed_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_default_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_pressed_holo_light.9.png b/core/res/res/drawable-mdpi/btn_default_pressed_holo_light.9.png
index 2ca4c3b..13a1fdd 100644
--- a/core/res/res/drawable-mdpi/btn_default_pressed_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_default_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_off_disabled_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_toggle_off_disabled_focused_holo_dark.9.png
index 0fa2859..88da06e 100644
--- a/core/res/res/drawable-mdpi/btn_toggle_off_disabled_focused_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_off_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_off_disabled_focused_holo_light.9.png b/core/res/res/drawable-mdpi/btn_toggle_off_disabled_focused_holo_light.9.png
index bdc0330..88da06e 100644
--- a/core/res/res/drawable-mdpi/btn_toggle_off_disabled_focused_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_off_disabled_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_off_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_toggle_off_disabled_holo_dark.9.png
index 35aca07..ae2c2c4 100644
--- a/core/res/res/drawable-mdpi/btn_toggle_off_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_off_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_off_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/btn_toggle_off_disabled_holo_light.9.png
index 3a07479..ae2c2c4 100644
--- a/core/res/res/drawable-mdpi/btn_toggle_off_disabled_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_off_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_off_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_toggle_off_focused_holo_dark.9.png
index 5755584..db0f9ab 100644
--- a/core/res/res/drawable-mdpi/btn_toggle_off_focused_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_off_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_off_focused_holo_light.9.png b/core/res/res/drawable-mdpi/btn_toggle_off_focused_holo_light.9.png
index b0af68f..db0f9ab 100644
--- a/core/res/res/drawable-mdpi/btn_toggle_off_focused_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_off_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_off_normal_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_toggle_off_normal_holo_dark.9.png
index 7c725b2..7abaf3e 100644
--- a/core/res/res/drawable-mdpi/btn_toggle_off_normal_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_off_normal_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_off_normal_holo_light.9.png b/core/res/res/drawable-mdpi/btn_toggle_off_normal_holo_light.9.png
index 93696aa..7abaf3e 100644
--- a/core/res/res/drawable-mdpi/btn_toggle_off_normal_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_off_normal_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_off_pressed_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_toggle_off_pressed_holo_dark.9.png
index 6dc4f1e..354fd0e 100644
--- a/core/res/res/drawable-mdpi/btn_toggle_off_pressed_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_off_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_off_pressed_holo_light.9.png b/core/res/res/drawable-mdpi/btn_toggle_off_pressed_holo_light.9.png
index 3a7e25c..354fd0e 100644
--- a/core/res/res/drawable-mdpi/btn_toggle_off_pressed_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_off_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_on_disabled_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_toggle_on_disabled_focused_holo_dark.9.png
index 5ddcc42..d311c80 100644
--- a/core/res/res/drawable-mdpi/btn_toggle_on_disabled_focused_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_on_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_on_disabled_focused_holo_light.9.png b/core/res/res/drawable-mdpi/btn_toggle_on_disabled_focused_holo_light.9.png
index 5ddcc42..d311c80 100644
--- a/core/res/res/drawable-mdpi/btn_toggle_on_disabled_focused_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_on_disabled_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_on_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_toggle_on_disabled_holo_dark.9.png
index 6f19f49..d0fd585 100644
--- a/core/res/res/drawable-mdpi/btn_toggle_on_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_on_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_on_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/btn_toggle_on_disabled_holo_light.9.png
index 6f19f49..d0fd585 100644
--- a/core/res/res/drawable-mdpi/btn_toggle_on_disabled_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_on_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_on_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_toggle_on_focused_holo_dark.9.png
index 1087fe3..e27b3de 100644
--- a/core/res/res/drawable-mdpi/btn_toggle_on_focused_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_on_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_on_focused_holo_light.9.png b/core/res/res/drawable-mdpi/btn_toggle_on_focused_holo_light.9.png
index 1087fe3..e27b3de 100644
--- a/core/res/res/drawable-mdpi/btn_toggle_on_focused_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_on_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_on_normal_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_toggle_on_normal_holo_dark.9.png
index 7db7486..cbed62f 100644
--- a/core/res/res/drawable-mdpi/btn_toggle_on_normal_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_on_normal_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_on_normal_holo_light.9.png b/core/res/res/drawable-mdpi/btn_toggle_on_normal_holo_light.9.png
index 7db7486..cbed62f 100644
--- a/core/res/res/drawable-mdpi/btn_toggle_on_normal_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_on_normal_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_on_pressed_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_toggle_on_pressed_holo_dark.9.png
index 842d967f..16fa332 100644
--- a/core/res/res/drawable-mdpi/btn_toggle_on_pressed_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_on_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_toggle_on_pressed_holo_light.9.png b/core/res/res/drawable-mdpi/btn_toggle_on_pressed_holo_light.9.png
index 842d967f..16fa332 100644
--- a/core/res/res/drawable-mdpi/btn_toggle_on_pressed_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_toggle_on_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_next.png b/core/res/res/drawable-mdpi/ic_media_next.png
index acef506..fcd73d9 100644
--- a/core/res/res/drawable-mdpi/ic_media_next.png
+++ b/core/res/res/drawable-mdpi/ic_media_next.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_pause.png b/core/res/res/drawable-mdpi/ic_media_pause.png
index 548ba02..3e6b2a1 100644
--- a/core/res/res/drawable-mdpi/ic_media_pause.png
+++ b/core/res/res/drawable-mdpi/ic_media_pause.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_play.png b/core/res/res/drawable-mdpi/ic_media_play.png
index 0fe6806..7966bbc 100644
--- a/core/res/res/drawable-mdpi/ic_media_play.png
+++ b/core/res/res/drawable-mdpi/ic_media_play.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_previous.png b/core/res/res/drawable-mdpi/ic_media_previous.png
index 940d6a4..b653d05 100644
--- a/core/res/res/drawable-mdpi/ic_media_previous.png
+++ b/core/res/res/drawable-mdpi/ic_media_previous.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_stop.png b/core/res/res/drawable-mdpi/ic_media_stop.png
index 24bcb70..8ea7efee 100644
--- a/core/res/res/drawable-mdpi/ic_media_stop.png
+++ b/core/res/res/drawable-mdpi/ic_media_stop.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/list_focused_holo.9.png b/core/res/res/drawable-mdpi/list_focused_holo.9.png
index 7c0599e..00f05d8 100644
--- a/core/res/res/drawable-mdpi/list_focused_holo.9.png
+++ b/core/res/res/drawable-mdpi/list_focused_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_down_disabled_focused_holo_dark.png b/core/res/res/drawable-mdpi/numberpicker_down_disabled_focused_holo_dark.png
index 7d9637a..50f6e98 100644
--- a/core/res/res/drawable-mdpi/numberpicker_down_disabled_focused_holo_dark.png
+++ b/core/res/res/drawable-mdpi/numberpicker_down_disabled_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_down_disabled_focused_holo_light.png b/core/res/res/drawable-mdpi/numberpicker_down_disabled_focused_holo_light.png
index f7409e4..67434f6 100644
--- a/core/res/res/drawable-mdpi/numberpicker_down_disabled_focused_holo_light.png
+++ b/core/res/res/drawable-mdpi/numberpicker_down_disabled_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_down_pressed_holo_dark.png b/core/res/res/drawable-mdpi/numberpicker_down_pressed_holo_dark.png
index 081ea4e..eb16f8d 100644
--- a/core/res/res/drawable-mdpi/numberpicker_down_pressed_holo_dark.png
+++ b/core/res/res/drawable-mdpi/numberpicker_down_pressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_down_pressed_holo_light.png b/core/res/res/drawable-mdpi/numberpicker_down_pressed_holo_light.png
index 081ea4e..eb16f8d 100644
--- a/core/res/res/drawable-mdpi/numberpicker_down_pressed_holo_light.png
+++ b/core/res/res/drawable-mdpi/numberpicker_down_pressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_up_disabled_focused_holo_dark.png b/core/res/res/drawable-mdpi/numberpicker_up_disabled_focused_holo_dark.png
index 739a8d7..58a3b64 100644
--- a/core/res/res/drawable-mdpi/numberpicker_up_disabled_focused_holo_dark.png
+++ b/core/res/res/drawable-mdpi/numberpicker_up_disabled_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_up_disabled_focused_holo_light.png b/core/res/res/drawable-mdpi/numberpicker_up_disabled_focused_holo_light.png
index bd440f2..382943b 100644
--- a/core/res/res/drawable-mdpi/numberpicker_up_disabled_focused_holo_light.png
+++ b/core/res/res/drawable-mdpi/numberpicker_up_disabled_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_up_pressed_holo_dark.png b/core/res/res/drawable-mdpi/numberpicker_up_pressed_holo_dark.png
index 0318c5f..bc5e3fa 100644
--- a/core/res/res/drawable-mdpi/numberpicker_up_pressed_holo_dark.png
+++ b/core/res/res/drawable-mdpi/numberpicker_up_pressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_up_pressed_holo_light.png b/core/res/res/drawable-mdpi/numberpicker_up_pressed_holo_light.png
index 0318c5f..bc5e3fa 100644
--- a/core/res/res/drawable-mdpi/numberpicker_up_pressed_holo_light.png
+++ b/core/res/res/drawable-mdpi/numberpicker_up_pressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/quickcontact_badge_overlay_focused_dark.9.png b/core/res/res/drawable-mdpi/quickcontact_badge_overlay_focused_dark.9.png
new file mode 100644
index 0000000..d12a196
--- /dev/null
+++ b/core/res/res/drawable-mdpi/quickcontact_badge_overlay_focused_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/quickcontact_badge_overlay_focused_light.9.png b/core/res/res/drawable-mdpi/quickcontact_badge_overlay_focused_light.9.png
new file mode 100644
index 0000000..27c7977
--- /dev/null
+++ b/core/res/res/drawable-mdpi/quickcontact_badge_overlay_focused_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/quickcontact_badge_overlay_normal_dark.9.png b/core/res/res/drawable-mdpi/quickcontact_badge_overlay_normal_dark.9.png
index 84d4c11..99c42c5 100644
--- a/core/res/res/drawable-mdpi/quickcontact_badge_overlay_normal_dark.9.png
+++ b/core/res/res/drawable-mdpi/quickcontact_badge_overlay_normal_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/quickcontact_badge_overlay_normal_light.9.png b/core/res/res/drawable-mdpi/quickcontact_badge_overlay_normal_light.9.png
index d922ef1..886b044 100644
--- a/core/res/res/drawable-mdpi/quickcontact_badge_overlay_normal_light.9.png
+++ b/core/res/res/drawable-mdpi/quickcontact_badge_overlay_normal_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/quickcontact_badge_overlay_pressed_dark.9.png b/core/res/res/drawable-mdpi/quickcontact_badge_overlay_pressed_dark.9.png
index 8c37c8d..eee058f 100644
--- a/core/res/res/drawable-mdpi/quickcontact_badge_overlay_pressed_dark.9.png
+++ b/core/res/res/drawable-mdpi/quickcontact_badge_overlay_pressed_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/quickcontact_badge_overlay_pressed_light.9.png b/core/res/res/drawable-mdpi/quickcontact_badge_overlay_pressed_light.9.png
index e442c28..1ac24be 100644
--- a/core/res/res/drawable-mdpi/quickcontact_badge_overlay_pressed_light.9.png
+++ b/core/res/res/drawable-mdpi/quickcontact_badge_overlay_pressed_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_ab_default_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_ab_default_holo_dark.9.png
index 9c99bda..29aff4d 100644
--- a/core/res/res/drawable-mdpi/spinner_ab_default_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/spinner_ab_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_ab_default_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_ab_default_holo_light.9.png
index 81b205a..4055f70 100644
--- a/core/res/res/drawable-mdpi/spinner_ab_default_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/spinner_ab_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_ab_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_ab_disabled_holo_dark.9.png
index 3ad6687..ea4ee04 100644
--- a/core/res/res/drawable-mdpi/spinner_ab_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/spinner_ab_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_ab_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_ab_disabled_holo_light.9.png
index fab4c67..f74c02b 100644
--- a/core/res/res/drawable-mdpi/spinner_ab_disabled_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/spinner_ab_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_ab_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_ab_focused_holo_dark.9.png
index f3ef482..09a2992 100644
--- a/core/res/res/drawable-mdpi/spinner_ab_focused_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/spinner_ab_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_ab_focused_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_ab_focused_holo_light.9.png
index d677278..6536ee6 100644
--- a/core/res/res/drawable-mdpi/spinner_ab_focused_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/spinner_ab_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_ab_pressed_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_ab_pressed_holo_dark.9.png
index 6255e2e..202b5b7 100644
--- a/core/res/res/drawable-mdpi/spinner_ab_pressed_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/spinner_ab_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_ab_pressed_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_ab_pressed_holo_light.9.png
index 1085248..6de0ba8 100644
--- a/core/res/res/drawable-mdpi/spinner_ab_pressed_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/spinner_ab_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_default_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_default_holo_dark.9.png
index f88dcba..48af192 100644
--- a/core/res/res/drawable-mdpi/spinner_default_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/spinner_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_default_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_default_holo_light.9.png
index c75eece..b3180cb 100644
--- a/core/res/res/drawable-mdpi/spinner_default_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/spinner_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_disabled_holo_dark.9.png
index eb23155..22eddd8 100644
--- a/core/res/res/drawable-mdpi/spinner_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/spinner_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_disabled_holo_light.9.png
index 4318af5..dad0ec9a 100644
--- a/core/res/res/drawable-mdpi/spinner_disabled_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/spinner_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_focused_holo_dark.9.png
index dc8f01e..2cdd273 100644
--- a/core/res/res/drawable-mdpi/spinner_focused_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/spinner_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_focused_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_focused_holo_light.9.png
index 7d3af87..f605db8 100644
--- a/core/res/res/drawable-mdpi/spinner_focused_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/spinner_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_pressed_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_pressed_holo_dark.9.png
index 2f00be8..a699924 100644
--- a/core/res/res/drawable-mdpi/spinner_pressed_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/spinner_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_pressed_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_pressed_holo_light.9.png
index 9c48ced..f3c12d7 100644
--- a/core/res/res/drawable-mdpi/spinner_pressed_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/spinner_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/switch_bg_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/switch_bg_disabled_holo_dark.9.png
index a161b03..76ccb8e 100644
--- a/core/res/res/drawable-mdpi/switch_bg_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/switch_bg_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/switch_bg_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/switch_bg_disabled_holo_light.9.png
index c637dd1..1e56c32 100644
--- a/core/res/res/drawable-mdpi/switch_bg_disabled_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/switch_bg_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/switch_bg_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/switch_bg_focused_holo_dark.9.png
index 680d1a0..914e433 100644
--- a/core/res/res/drawable-mdpi/switch_bg_focused_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/switch_bg_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/switch_bg_focused_holo_light.9.png b/core/res/res/drawable-mdpi/switch_bg_focused_holo_light.9.png
index 70da7b3..89b0273 100644
--- a/core/res/res/drawable-mdpi/switch_bg_focused_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/switch_bg_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/switch_thumb_activated_holo_dark.9.png b/core/res/res/drawable-mdpi/switch_thumb_activated_holo_dark.9.png
index 3d786c0..0787d16 100644
--- a/core/res/res/drawable-mdpi/switch_thumb_activated_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/switch_thumb_activated_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/switch_thumb_activated_holo_light.9.png b/core/res/res/drawable-mdpi/switch_thumb_activated_holo_light.9.png
index 2bad2b8..0157e68 100644
--- a/core/res/res/drawable-mdpi/switch_thumb_activated_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/switch_thumb_activated_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/switch_thumb_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/switch_thumb_disabled_holo_dark.9.png
index f6ed0bf..51b14d0 100644
--- a/core/res/res/drawable-mdpi/switch_thumb_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/switch_thumb_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/switch_thumb_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/switch_thumb_disabled_holo_light.9.png
index a430b77..d68568a 100644
--- a/core/res/res/drawable-mdpi/switch_thumb_disabled_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/switch_thumb_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/switch_thumb_holo_dark.9.png b/core/res/res/drawable-mdpi/switch_thumb_holo_dark.9.png
index 6312c59..6bf153a 100644
--- a/core/res/res/drawable-mdpi/switch_thumb_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/switch_thumb_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/switch_thumb_holo_light.9.png b/core/res/res/drawable-mdpi/switch_thumb_holo_light.9.png
index 2086722..0d98983 100644
--- a/core/res/res/drawable-mdpi/switch_thumb_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/switch_thumb_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/switch_thumb_pressed_holo_dark.9.png b/core/res/res/drawable-mdpi/switch_thumb_pressed_holo_dark.9.png
index e44b1d8..3cee7b8 100644
--- a/core/res/res/drawable-mdpi/switch_thumb_pressed_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/switch_thumb_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/switch_thumb_pressed_holo_light.9.png b/core/res/res/drawable-mdpi/switch_thumb_pressed_holo_light.9.png
index ee7e37b..43a7c4c 100644
--- a/core/res/res/drawable-mdpi/switch_thumb_pressed_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/switch_thumb_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/sym_keyboard_num0_no_plus.png b/core/res/res/drawable-mdpi/sym_keyboard_num0_no_plus.png
index 91332b1..d23114d 100644
--- a/core/res/res/drawable-mdpi/sym_keyboard_num0_no_plus.png
+++ b/core/res/res/drawable-mdpi/sym_keyboard_num0_no_plus.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_default_disabled_focused_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_default_disabled_focused_holo_dark.9.png
index b534256..b7707c6f 100644
--- a/core/res/res/drawable-xhdpi/btn_default_disabled_focused_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/btn_default_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_default_disabled_focused_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_default_disabled_focused_holo_light.9.png
index b534256..b7707c6f 100644
--- a/core/res/res/drawable-xhdpi/btn_default_disabled_focused_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/btn_default_disabled_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_default_disabled_holo.9.png b/core/res/res/drawable-xhdpi/btn_default_disabled_holo.9.png
index aca0a23..2ed6386 100644
--- a/core/res/res/drawable-xhdpi/btn_default_disabled_holo.9.png
+++ b/core/res/res/drawable-xhdpi/btn_default_disabled_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_default_disabled_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_default_disabled_holo_dark.9.png
index 137d726..ffee5e2 100644
--- a/core/res/res/drawable-xhdpi/btn_default_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/btn_default_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_default_disabled_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_default_disabled_holo_light.9.png
index 137d726..ffee5e2 100644
--- a/core/res/res/drawable-xhdpi/btn_default_disabled_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/btn_default_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_default_focused_holo.9.png b/core/res/res/drawable-xhdpi/btn_default_focused_holo.9.png
index 7dc088a..702ebc6 100644
--- a/core/res/res/drawable-xhdpi/btn_default_focused_holo.9.png
+++ b/core/res/res/drawable-xhdpi/btn_default_focused_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_default_focused_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_default_focused_holo_dark.9.png
index c5bc3ec..30bfa30 100644
--- a/core/res/res/drawable-xhdpi/btn_default_focused_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/btn_default_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_default_focused_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_default_focused_holo_light.9.png
index c5bc3ec..30bfa30 100644
--- a/core/res/res/drawable-xhdpi/btn_default_focused_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/btn_default_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_default_normal_holo.9.png b/core/res/res/drawable-xhdpi/btn_default_normal_holo.9.png
index a97c1d3..89ce2df 100644
--- a/core/res/res/drawable-xhdpi/btn_default_normal_holo.9.png
+++ b/core/res/res/drawable-xhdpi/btn_default_normal_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_default_normal_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_default_normal_holo_dark.9.png
index ed7e0f4..745d53e 100644
--- a/core/res/res/drawable-xhdpi/btn_default_normal_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/btn_default_normal_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_default_normal_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_default_normal_holo_light.9.png
index ed7e0f4..c509934 100644
--- a/core/res/res/drawable-xhdpi/btn_default_normal_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/btn_default_normal_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_default_pressed_holo.9.png b/core/res/res/drawable-xhdpi/btn_default_pressed_holo.9.png
index 25d139a..b1eab79 100644
--- a/core/res/res/drawable-xhdpi/btn_default_pressed_holo.9.png
+++ b/core/res/res/drawable-xhdpi/btn_default_pressed_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_default_pressed_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_default_pressed_holo_dark.9.png
index 61f5f6f..417152b 100644
--- a/core/res/res/drawable-xhdpi/btn_default_pressed_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/btn_default_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_default_pressed_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_default_pressed_holo_light.9.png
index 61f5f6f..417152b 100644
--- a/core/res/res/drawable-xhdpi/btn_default_pressed_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/btn_default_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_toggle_off_disabled_focused_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_toggle_off_disabled_focused_holo_dark.9.png
index 18aeac6..c271216 100644
--- a/core/res/res/drawable-xhdpi/btn_toggle_off_disabled_focused_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/btn_toggle_off_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_toggle_off_disabled_focused_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_toggle_off_disabled_focused_holo_light.9.png
index 471b6ea..c271216 100644
--- a/core/res/res/drawable-xhdpi/btn_toggle_off_disabled_focused_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/btn_toggle_off_disabled_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_toggle_off_disabled_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_toggle_off_disabled_holo_dark.9.png
index 393f967..a2d3ecd 100644
--- a/core/res/res/drawable-xhdpi/btn_toggle_off_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/btn_toggle_off_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_toggle_off_disabled_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_toggle_off_disabled_holo_light.9.png
index 87193af..a2d3ecd 100644
--- a/core/res/res/drawable-xhdpi/btn_toggle_off_disabled_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/btn_toggle_off_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_toggle_off_focused_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_toggle_off_focused_holo_dark.9.png
index 0ad8f35..80cbb05 100644
--- a/core/res/res/drawable-xhdpi/btn_toggle_off_focused_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/btn_toggle_off_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_toggle_off_focused_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_toggle_off_focused_holo_light.9.png
index fc21be1..80cbb05 100644
--- a/core/res/res/drawable-xhdpi/btn_toggle_off_focused_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/btn_toggle_off_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_toggle_off_normal_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_toggle_off_normal_holo_dark.9.png
index 5ff338d..db2cfc5 100644
--- a/core/res/res/drawable-xhdpi/btn_toggle_off_normal_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/btn_toggle_off_normal_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_toggle_off_normal_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_toggle_off_normal_holo_light.9.png
index 1321473..db2cfc5 100644
--- a/core/res/res/drawable-xhdpi/btn_toggle_off_normal_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/btn_toggle_off_normal_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_toggle_off_pressed_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_toggle_off_pressed_holo_dark.9.png
index 9c914b0..5086f46 100644
--- a/core/res/res/drawable-xhdpi/btn_toggle_off_pressed_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/btn_toggle_off_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_toggle_off_pressed_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_toggle_off_pressed_holo_light.9.png
index fe28238..5086f46 100644
--- a/core/res/res/drawable-xhdpi/btn_toggle_off_pressed_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/btn_toggle_off_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_toggle_on_disabled_focused_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_toggle_on_disabled_focused_holo_dark.9.png
index 455fdb4..0f5851b 100644
--- a/core/res/res/drawable-xhdpi/btn_toggle_on_disabled_focused_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/btn_toggle_on_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_toggle_on_disabled_focused_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_toggle_on_disabled_focused_holo_light.9.png
index 455fdb4..0f5851b 100644
--- a/core/res/res/drawable-xhdpi/btn_toggle_on_disabled_focused_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/btn_toggle_on_disabled_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_toggle_on_disabled_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_toggle_on_disabled_holo_dark.9.png
index ee8329df..74c853f 100644
--- a/core/res/res/drawable-xhdpi/btn_toggle_on_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/btn_toggle_on_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_toggle_on_disabled_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_toggle_on_disabled_holo_light.9.png
index ee8329df..74c853f 100644
--- a/core/res/res/drawable-xhdpi/btn_toggle_on_disabled_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/btn_toggle_on_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_toggle_on_focused_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_toggle_on_focused_holo_dark.9.png
index ccfb2d0..7bd7af5 100644
--- a/core/res/res/drawable-xhdpi/btn_toggle_on_focused_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/btn_toggle_on_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_toggle_on_focused_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_toggle_on_focused_holo_light.9.png
index ccfb2d0..7bd7af5 100644
--- a/core/res/res/drawable-xhdpi/btn_toggle_on_focused_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/btn_toggle_on_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_toggle_on_normal_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_toggle_on_normal_holo_dark.9.png
index ad1f4f0..71dad92 100644
--- a/core/res/res/drawable-xhdpi/btn_toggle_on_normal_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/btn_toggle_on_normal_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_toggle_on_normal_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_toggle_on_normal_holo_light.9.png
index ad1f4f0..71dad92 100644
--- a/core/res/res/drawable-xhdpi/btn_toggle_on_normal_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/btn_toggle_on_normal_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_toggle_on_pressed_holo_dark.9.png b/core/res/res/drawable-xhdpi/btn_toggle_on_pressed_holo_dark.9.png
index 97304af..1f62eff 100644
--- a/core/res/res/drawable-xhdpi/btn_toggle_on_pressed_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/btn_toggle_on_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_toggle_on_pressed_holo_light.9.png b/core/res/res/drawable-xhdpi/btn_toggle_on_pressed_holo_light.9.png
index 97304af..1f62eff 100644
--- a/core/res/res/drawable-xhdpi/btn_toggle_on_pressed_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/btn_toggle_on_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_next.png b/core/res/res/drawable-xhdpi/ic_media_next.png
index 726fee7..4def965 100644
--- a/core/res/res/drawable-xhdpi/ic_media_next.png
+++ b/core/res/res/drawable-xhdpi/ic_media_next.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_pause.png b/core/res/res/drawable-xhdpi/ic_media_pause.png
index 8614bff..6bd3d48 100644
--- a/core/res/res/drawable-xhdpi/ic_media_pause.png
+++ b/core/res/res/drawable-xhdpi/ic_media_pause.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_play.png b/core/res/res/drawable-xhdpi/ic_media_play.png
index d93e824..ccfef18 100644
--- a/core/res/res/drawable-xhdpi/ic_media_play.png
+++ b/core/res/res/drawable-xhdpi/ic_media_play.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_previous.png b/core/res/res/drawable-xhdpi/ic_media_previous.png
index 59f994d..c4472ae 100644
--- a/core/res/res/drawable-xhdpi/ic_media_previous.png
+++ b/core/res/res/drawable-xhdpi/ic_media_previous.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_stop.png b/core/res/res/drawable-xhdpi/ic_media_stop.png
index 00159aa..89f36950 100644
--- a/core/res/res/drawable-xhdpi/ic_media_stop.png
+++ b/core/res/res/drawable-xhdpi/ic_media_stop.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/list_focused_holo.9.png b/core/res/res/drawable-xhdpi/list_focused_holo.9.png
index 690cb1e..b545f8e 100644
--- a/core/res/res/drawable-xhdpi/list_focused_holo.9.png
+++ b/core/res/res/drawable-xhdpi/list_focused_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_focused_dark.9.png b/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_focused_dark.9.png
new file mode 100644
index 0000000..6927834
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_focused_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_focused_light.9.png b/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_focused_light.9.png
new file mode 100644
index 0000000..4bce527
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_focused_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_normal_dark.9.png b/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_normal_dark.9.png
index 9cf9173..99dbfcc 100644
--- a/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_normal_dark.9.png
+++ b/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_normal_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_normal_light.9.png b/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_normal_light.9.png
index c8d8a17..2d3e5c8 100644
--- a/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_normal_light.9.png
+++ b/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_normal_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_pressed_dark.9.png b/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_pressed_dark.9.png
index e3793f7..75c5996 100644
--- a/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_pressed_dark.9.png
+++ b/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_pressed_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_pressed_light.9.png b/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_pressed_light.9.png
index c0be34f0..a2d6ca1 100644
--- a/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_pressed_light.9.png
+++ b/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_pressed_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_ab_default_holo_dark.9.png b/core/res/res/drawable-xhdpi/spinner_ab_default_holo_dark.9.png
index 5e7551d..d8929fc 100644
--- a/core/res/res/drawable-xhdpi/spinner_ab_default_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/spinner_ab_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_ab_default_holo_light.9.png b/core/res/res/drawable-xhdpi/spinner_ab_default_holo_light.9.png
index f4586f8..9174c4e 100644
--- a/core/res/res/drawable-xhdpi/spinner_ab_default_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/spinner_ab_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_ab_disabled_holo_dark.9.png b/core/res/res/drawable-xhdpi/spinner_ab_disabled_holo_dark.9.png
index 86d369d..3015d30 100644
--- a/core/res/res/drawable-xhdpi/spinner_ab_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/spinner_ab_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_ab_disabled_holo_light.9.png b/core/res/res/drawable-xhdpi/spinner_ab_disabled_holo_light.9.png
index 1c4983b..126637d 100644
--- a/core/res/res/drawable-xhdpi/spinner_ab_disabled_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/spinner_ab_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_ab_focused_holo_dark.9.png b/core/res/res/drawable-xhdpi/spinner_ab_focused_holo_dark.9.png
index edf2573..d45c7a8 100644
--- a/core/res/res/drawable-xhdpi/spinner_ab_focused_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/spinner_ab_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_ab_focused_holo_light.9.png b/core/res/res/drawable-xhdpi/spinner_ab_focused_holo_light.9.png
index 3a16579..29036b90 100644
--- a/core/res/res/drawable-xhdpi/spinner_ab_focused_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/spinner_ab_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_ab_pressed_holo_dark.9.png b/core/res/res/drawable-xhdpi/spinner_ab_pressed_holo_dark.9.png
index 5253673..2cb34d7 100644
--- a/core/res/res/drawable-xhdpi/spinner_ab_pressed_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/spinner_ab_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_ab_pressed_holo_light.9.png b/core/res/res/drawable-xhdpi/spinner_ab_pressed_holo_light.9.png
index cfb4a9c..82f752f 100644
--- a/core/res/res/drawable-xhdpi/spinner_ab_pressed_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/spinner_ab_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_default_holo_dark.9.png b/core/res/res/drawable-xhdpi/spinner_default_holo_dark.9.png
index fab743d..e94ce80 100644
--- a/core/res/res/drawable-xhdpi/spinner_default_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/spinner_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_default_holo_light.9.png b/core/res/res/drawable-xhdpi/spinner_default_holo_light.9.png
index 9987f74..f006541 100644
--- a/core/res/res/drawable-xhdpi/spinner_default_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/spinner_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_disabled_holo_dark.9.png b/core/res/res/drawable-xhdpi/spinner_disabled_holo_dark.9.png
index 6dcd2d4..7bfab99 100644
--- a/core/res/res/drawable-xhdpi/spinner_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/spinner_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_disabled_holo_light.9.png b/core/res/res/drawable-xhdpi/spinner_disabled_holo_light.9.png
index bfddedb..1edcc81 100644
--- a/core/res/res/drawable-xhdpi/spinner_disabled_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/spinner_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_focused_holo_dark.9.png b/core/res/res/drawable-xhdpi/spinner_focused_holo_dark.9.png
index eb1e1b7..ff7b959 100644
--- a/core/res/res/drawable-xhdpi/spinner_focused_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/spinner_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_focused_holo_light.9.png b/core/res/res/drawable-xhdpi/spinner_focused_holo_light.9.png
index 00c440c..156b5ab 100644
--- a/core/res/res/drawable-xhdpi/spinner_focused_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/spinner_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_pressed_holo_dark.9.png b/core/res/res/drawable-xhdpi/spinner_pressed_holo_dark.9.png
index 28d170f..d0ce6e4 100644
--- a/core/res/res/drawable-xhdpi/spinner_pressed_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/spinner_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_pressed_holo_light.9.png b/core/res/res/drawable-xhdpi/spinner_pressed_holo_light.9.png
index d61be5d..9e9617e 100644
--- a/core/res/res/drawable-xhdpi/spinner_pressed_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/spinner_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/switch_bg_disabled_holo_dark.9.png b/core/res/res/drawable-xhdpi/switch_bg_disabled_holo_dark.9.png
index 911acd7..b23070c 100644
--- a/core/res/res/drawable-xhdpi/switch_bg_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/switch_bg_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/switch_bg_disabled_holo_light.9.png b/core/res/res/drawable-xhdpi/switch_bg_disabled_holo_light.9.png
index 8ba0f75..29f177a 100644
--- a/core/res/res/drawable-xhdpi/switch_bg_disabled_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/switch_bg_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/switch_bg_focused_holo_dark.9.png b/core/res/res/drawable-xhdpi/switch_bg_focused_holo_dark.9.png
index e30e34d..e85103d 100644
--- a/core/res/res/drawable-xhdpi/switch_bg_focused_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/switch_bg_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/switch_bg_focused_holo_light.9.png b/core/res/res/drawable-xhdpi/switch_bg_focused_holo_light.9.png
index b1f5b24..75978bc 100644
--- a/core/res/res/drawable-xhdpi/switch_bg_focused_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/switch_bg_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/switch_thumb_activated_holo_dark.9.png b/core/res/res/drawable-xhdpi/switch_thumb_activated_holo_dark.9.png
index ea53b5f..a0e6b20 100644
--- a/core/res/res/drawable-xhdpi/switch_thumb_activated_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/switch_thumb_activated_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/switch_thumb_activated_holo_light.9.png b/core/res/res/drawable-xhdpi/switch_thumb_activated_holo_light.9.png
index 8a4b61a..88235fe 100644
--- a/core/res/res/drawable-xhdpi/switch_thumb_activated_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/switch_thumb_activated_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/switch_thumb_disabled_holo_dark.9.png b/core/res/res/drawable-xhdpi/switch_thumb_disabled_holo_dark.9.png
index 6a280dc..04fb9a1 100644
--- a/core/res/res/drawable-xhdpi/switch_thumb_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/switch_thumb_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/switch_thumb_disabled_holo_light.9.png b/core/res/res/drawable-xhdpi/switch_thumb_disabled_holo_light.9.png
index 34a9304..06a14f3 100644
--- a/core/res/res/drawable-xhdpi/switch_thumb_disabled_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/switch_thumb_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/switch_thumb_holo_dark.9.png b/core/res/res/drawable-xhdpi/switch_thumb_holo_dark.9.png
index 757fdd4..af7d631 100644
--- a/core/res/res/drawable-xhdpi/switch_thumb_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/switch_thumb_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/switch_thumb_holo_light.9.png b/core/res/res/drawable-xhdpi/switch_thumb_holo_light.9.png
index 8873ccc..d6ab3ea 100644
--- a/core/res/res/drawable-xhdpi/switch_thumb_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/switch_thumb_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/switch_thumb_pressed_holo_dark.9.png b/core/res/res/drawable-xhdpi/switch_thumb_pressed_holo_dark.9.png
index d22226e..5a8e807 100644
--- a/core/res/res/drawable-xhdpi/switch_thumb_pressed_holo_dark.9.png
+++ b/core/res/res/drawable-xhdpi/switch_thumb_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/switch_thumb_pressed_holo_light.9.png b/core/res/res/drawable-xhdpi/switch_thumb_pressed_holo_light.9.png
index c94248c..392f3dc 100644
--- a/core/res/res/drawable-xhdpi/switch_thumb_pressed_holo_light.9.png
+++ b/core/res/res/drawable-xhdpi/switch_thumb_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/sym_keyboard_num0_no_plus.png b/core/res/res/drawable-xhdpi/sym_keyboard_num0_no_plus.png
index c477cf1..95b542d 100644
--- a/core/res/res/drawable-xhdpi/sym_keyboard_num0_no_plus.png
+++ b/core/res/res/drawable-xhdpi/sym_keyboard_num0_no_plus.png
Binary files differ
diff --git a/core/res/res/drawable/quickcontact_badge_overlay_dark.xml b/core/res/res/drawable/quickcontact_badge_overlay_dark.xml
index 972488d..6bd7403 100644
--- a/core/res/res/drawable/quickcontact_badge_overlay_dark.xml
+++ b/core/res/res/drawable/quickcontact_badge_overlay_dark.xml
@@ -16,13 +16,13 @@
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item
-        android:state_focused="false"
-        android:state_selected="false"
-        android:state_pressed="false"
-        android:drawable="@drawable/quickcontact_badge_overlay_normal_dark" />
-
-    <item
         android:state_pressed="true"
         android:drawable="@drawable/quickcontact_badge_overlay_pressed_dark" />
+    <item
+        android:state_pressed="false"
+        android:state_focused="true"
+        android:drawable="@drawable/quickcontact_badge_overlay_focused_dark" />
+    <item
+        android:drawable="@drawable/quickcontact_badge_overlay_normal_dark" />
 
 </selector>
diff --git a/core/res/res/drawable/quickcontact_badge_overlay_light.xml b/core/res/res/drawable/quickcontact_badge_overlay_light.xml
index bf95d52..cf7f916 100644
--- a/core/res/res/drawable/quickcontact_badge_overlay_light.xml
+++ b/core/res/res/drawable/quickcontact_badge_overlay_light.xml
@@ -16,13 +16,13 @@
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item
-        android:state_focused="false"
-        android:state_selected="false"
-        android:state_pressed="false"
-        android:drawable="@drawable/quickcontact_badge_overlay_normal_light" />
-
-    <item
         android:state_pressed="true"
         android:drawable="@drawable/quickcontact_badge_overlay_pressed_light" />
+    <item
+        android:state_pressed="false"
+        android:state_focused="true"
+        android:drawable="@drawable/quickcontact_badge_overlay_focused_light" />
+    <item
+        android:drawable="@drawable/quickcontact_badge_overlay_normal_light" />
 
 </selector>
diff --git a/core/res/res/drawable/tab_indicator_ab_holo.xml b/core/res/res/drawable/tab_indicator_ab_holo.xml
new file mode 100644
index 0000000..d8a5750
--- /dev/null
+++ b/core/res/res/drawable/tab_indicator_ab_holo.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <!-- Non focused states -->
+    <item android:state_focused="false" android:state_selected="false" android:state_pressed="false" android:drawable="@color/transparent" />
+    <item android:state_focused="false" android:state_selected="true"  android:state_pressed="false" android:drawable="@drawable/tab_selected_holo" />
+
+    <!-- Focused states -->
+    <item android:state_focused="true" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/list_focused_holo" />
+    <item android:state_focused="true" android:state_selected="true"  android:state_pressed="false" android:drawable="@drawable/tab_selected_focused_holo" />
+
+    <!-- Pressed -->
+    <!--    Non focused states -->
+    <item android:state_focused="false" android:state_selected="false" android:state_pressed="true" android:drawable="@drawable/list_pressed_holo_dark" />
+    <item android:state_focused="false" android:state_selected="true"  android:state_pressed="true" android:drawable="@drawable/tab_selected_pressed_holo" />
+
+    <!--    Focused states -->
+    <item android:state_focused="true" android:state_selected="false" android:state_pressed="true" android:drawable="@drawable/tab_unselected_pressed_holo" />
+    <item android:state_focused="true" android:state_selected="true"  android:state_pressed="true" android:drawable="@drawable/tab_selected_pressed_holo" />
+</selector>
diff --git a/core/res/res/layout-sw600dp/keyguard_screen_password_landscape.xml b/core/res/res/layout-sw600dp/keyguard_screen_password_landscape.xml
index ee1ce5f..b58f081 100644
--- a/core/res/res/layout-sw600dp/keyguard_screen_password_landscape.xml
+++ b/core/res/res/layout-sw600dp/keyguard_screen_password_landscape.xml
@@ -50,20 +50,56 @@
             android:layout_centerVertical="true"
             android:layout_marginRight="155dip">
 
-            <!-- Password entry field -->
-            <EditText android:id="@+id/passwordEntry"
-                android:layout_height="wrap_content"
+
+            <LinearLayout
+                android:orientation="horizontal"
                 android:layout_width="match_parent"
-                android:singleLine="true"
-                android:textStyle="normal"
-                android:inputType="textPassword"
-                android:gravity="center"
-                android:textSize="24sp"
-                android:textAppearance="?android:attr/textAppearanceMedium"
-                android:background="@drawable/lockscreen_password_field_dark"
-                android:textColor="#ffffffff"
-                android:privateImeOptions="com.google.android.inputmethod.latin.forceAscii"
-                />
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_vertical"
+                android:background="@drawable/lockscreen_password_field_dark">
+
+                <EditText android:id="@+id/passwordEntry"
+                    android:layout_height="wrap_content"
+                    android:layout_width="0dip"
+                    android:layout_weight="1"
+                    android:gravity="center"
+                    android:layout_gravity="center"
+                    android:layout_marginLeft="@dimen/keyguard_lockscreen_pin_margin_left"
+                    android:singleLine="true"
+                    android:textStyle="normal"
+                    android:inputType="textPassword"
+                    android:textSize="24sp"
+                    android:textAppearance="?android:attr/textAppearanceMedium"
+                    android:background="@null"
+                    android:textColor="#ffffffff"
+                    android:imeOptions="flagNoFullscreen|actionDone"
+                    android:privateImeOptions="com.google.android.inputmethod.latin.forceAscii"
+                    />
+
+                <!-- This delete button is only visible for numeric PIN entry -->
+                <ImageButton android:id="@+id/pinDel"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:src="@android:drawable/ic_input_delete"
+                    android:clickable="true"
+                    android:padding="8dip"
+                    android:layout_gravity="center"
+                    android:background="?android:attr/selectableItemBackground"
+                    android:visibility="gone"
+                    />
+
+                <ImageView android:id="@+id/switch_ime_button"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:src="@drawable/ic_lockscreen_ime"
+                    android:clickable="true"
+                    android:padding="8dip"
+                    android:layout_gravity="center"
+                    android:background="?android:attr/selectableItemBackground"
+                    android:visibility="gone"
+                    />
+
+            </LinearLayout>
 
             <!-- Numeric keyboard -->
             <com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboard"
@@ -71,7 +107,7 @@
                 android:layout_height="330dip"
                 android:background="#40000000"
                 android:layout_marginTop="5dip"
-                android:keyBackground="@drawable/btn_keyboard_key_fulltrans"
+                android:keyBackground="@drawable/btn_keyboard_key_ics"
                 android:visibility="gone"
             />
         </LinearLayout>
diff --git a/core/res/res/layout-sw600dp/keyguard_screen_password_portrait.xml b/core/res/res/layout-sw600dp/keyguard_screen_password_portrait.xml
index 254dd3e..cadb5f8 100644
--- a/core/res/res/layout-sw600dp/keyguard_screen_password_portrait.xml
+++ b/core/res/res/layout-sw600dp/keyguard_screen_password_portrait.xml
@@ -44,22 +44,56 @@
         android:gravity="center">
 
         <!-- Password entry field -->
-        <EditText android:id="@+id/passwordEntry"
-            android:layout_height="wrap_content"
+        <LinearLayout
+            android:orientation="horizontal"
             android:layout_width="330dip"
-            android:singleLine="true"
-            android:textStyle="normal"
-            android:inputType="textPassword"
-            android:gravity="center"
+            android:layout_height="wrap_content"
             android:layout_gravity="center"
-            android:textSize="24sp"
             android:layout_marginTop="120dip"
             android:layout_marginBottom="5dip"
-            android:textAppearance="?android:attr/textAppearanceMedium"
-            android:background="@drawable/lockscreen_password_field_dark"
-            android:textColor="#ffffffff"
-            android:privateImeOptions="com.google.android.inputmethod.latin.forceAscii"
-            />
+            android:background="@drawable/lockscreen_password_field_dark">
+
+            <EditText android:id="@+id/passwordEntry"
+                android:layout_height="wrap_content"
+                android:layout_width="0dip"
+                android:layout_weight="1"
+                android:singleLine="true"
+                android:textStyle="normal"
+                android:inputType="textPassword"
+                android:gravity="center"
+                android:layout_gravity="center"
+                android:layout_marginLeft="@dimen/keyguard_lockscreen_pin_margin_left"
+                android:textSize="24sp"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:background="@null"
+                android:textColor="#ffffffff"
+                android:privateImeOptions="com.google.android.inputmethod.latin.forceAscii"
+                />
+
+            <!-- This delete button is only visible for numeric PIN entry -->
+            <ImageButton android:id="@+id/pinDel"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:src="@android:drawable/ic_input_delete"
+                android:clickable="true"
+                android:padding="8dip"
+                android:layout_gravity="center"
+                android:background="?android:attr/selectableItemBackground"
+                android:visibility="gone"
+                />
+
+            <ImageView android:id="@+id/switch_ime_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:src="@drawable/ic_lockscreen_ime"
+                android:clickable="true"
+                android:padding="8dip"
+                android:layout_gravity="center"
+                android:background="?android:attr/selectableItemBackground"
+                android:visibility="gone"
+                />
+
+        </LinearLayout>
 
         <View
             android:layout_width="match_parent"
@@ -72,7 +106,7 @@
             android:layout_width="330dip"
             android:layout_height="260dip"
             android:background="#40000000"
-            android:keyBackground="@drawable/btn_keyboard_key_fulltrans"
+            android:keyBackground="@drawable/btn_keyboard_key_ics"
             android:layout_marginBottom="80dip"
         />
 
diff --git a/core/res/res/layout/keyguard_screen_password_landscape.xml b/core/res/res/layout/keyguard_screen_password_landscape.xml
index 62f59f6..ba0c22f 100644
--- a/core/res/res/layout/keyguard_screen_password_landscape.xml
+++ b/core/res/res/layout/keyguard_screen_password_landscape.xml
@@ -143,6 +143,8 @@
             android:layout_width="0dip"
             android:layout_weight="1"
             android:gravity="center"
+            android:layout_marginLeft="@dimen/keyguard_lockscreen_pin_margin_left"
+            android:layout_gravity="center_vertical"
             android:singleLine="true"
             android:textStyle="normal"
             android:inputType="textPassword"
diff --git a/core/res/res/layout/keyguard_screen_password_portrait.xml b/core/res/res/layout/keyguard_screen_password_portrait.xml
index 597cfe7..f6933c3 100644
--- a/core/res/res/layout/keyguard_screen_password_portrait.xml
+++ b/core/res/res/layout/keyguard_screen_password_portrait.xml
@@ -109,6 +109,8 @@
             android:layout_height="wrap_content"
             android:layout_weight="1"
             android:gravity="center_horizontal"
+            android:layout_gravity="center_vertical"
+            android:layout_marginLeft="@dimen/keyguard_lockscreen_pin_margin_left"
             android:singleLine="true"
             android:textStyle="normal"
             android:inputType="textPassword"
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 269e348..24802e2 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -1169,8 +1169,7 @@
     <string name="description_target_camera" msgid="969071997552486814">"Камера"</string>
     <string name="description_target_silent" msgid="893551287746522182">"Тих режим"</string>
     <string name="description_target_soundon" msgid="30052466675500172">"Включване на звука"</string>
-    <!-- no translation found for description_target_unlock_tablet (3833195335629795055) -->
-    <skip />
+    <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Прокарайте пръст, за да отключите."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Включете слушалки, за да чуете клавишите за паролата на висок глас."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Точка."</string>
     <string name="action_bar_home_description" msgid="5293600496601490216">"Придвижване към „Начало“"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 788b285..97ad227 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -1169,8 +1169,7 @@
     <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
     <string name="description_target_silent" msgid="893551287746522182">"Lydløs"</string>
     <string name="description_target_soundon" msgid="30052466675500172">"Lyd slået til"</string>
-    <!-- no translation found for description_target_unlock_tablet (3833195335629795055) -->
-    <skip />
+    <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Glid hurtigt henover for at låse op."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Tilslut et headset for at få læst taster højt, når du indtaster en adgangskode."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punktum."</string>
     <string name="action_bar_home_description" msgid="5293600496601490216">"Naviger hjem"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 71c6da5..b4a3c92 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -282,7 +282,7 @@
     <string name="permlab_signalPersistentProcesses" msgid="4255467255488653854">"Linux-Signale an Apps senden"</string>
     <string name="permdesc_signalPersistentProcesses" msgid="3565530463215015289">"Ermöglicht der App, das Senden des gelieferten Signals an alle anhaltenden Prozesse zu fordern"</string>
     <string name="permlab_persistentActivity" msgid="8659652042401085862">"Apps permanent ausführen"</string>
-    <string name="permdesc_persistentActivity" msgid="5037199778265006008">"Ermöglicht einer App, eigene Komponenten persistent zu machen, damit das System diese nicht für andere Anwendungen nutzen kann"</string>
+    <string name="permdesc_persistentActivity" msgid="5037199778265006008">"Ermöglicht einer App, eigene Komponenten permanent zu machen, damit das System diese nicht für andere Apps nutzen kann"</string>
     <string name="permlab_deletePackages" msgid="3343439331576348805">"Apps löschen"</string>
     <string name="permdesc_deletePackages" msgid="3634943677518723314">"Ermöglicht einer App, Android-Pakete zu löschen. Schädliche Anwendungen können so wichtige Anwendungen löschen."</string>
     <string name="permlab_clearAppUserData" msgid="2192134353540277878">"Daten anderer Apps löschen"</string>
@@ -340,7 +340,7 @@
     <string name="permlab_writeCalendar" msgid="8438874755193825647">"Ohne das Wissen der Eigentümer Kalendertermine hinzufügen oder ändern und E-Mails an Gäste senden"</string>
     <string name="permdesc_writeCalendar" msgid="5368129321997977226">"Ermöglicht einer App das Senden von Termineinladungen als Kalendereigentümer und das Hinzufügen, Entfernen und Ändern von Terminen, die Sie auf Ihrem Gerät bearbeiten können, einschließlich der Termine von Freunden oder Kollegen. Schädliche Apps mit dieser Berechtigung können Spam-E-Mails senden, die von Kalendereigentümern zu kommen scheinen, Termine ohne das Wissen der Eigentümer ändern oder falsche Termine hinzufügen."</string>
     <string name="permlab_accessMockLocation" msgid="8688334974036823330">"Simulierte Standortquellen für Testzwecke"</string>
-    <string name="permdesc_accessMockLocation" msgid="7648286063459727252">"Erstellt falsche Standortquellen für Testzwecke. Schädliche Anwendungen können so den von den echten Standortquellen wie GPS oder Netzwerkanbieter zurückgegebenen Standort und/oder Status überschreiben."</string>
+    <string name="permdesc_accessMockLocation" msgid="7648286063459727252">"Erstellt simulierte Standortquellen für Testzwecke. Schädliche Anwendungen können so den von den echten Standortquellen wie GPS oder Netzwerkanbieter zurückgegebenen Standort und/oder Status überschreiben."</string>
     <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"Auf zusätzliche Dienstanbieterbefehle für Standort zugreifen"</string>
     <string name="permdesc_accessLocationExtraCommands" msgid="1948144701382451721">"Zugriff auf zusätzliche Dienstanbieterbefehle für Standort. Schädliche Anwendungen könnten so die Funktionsweise von GPS oder anderen Standortquellen beeinträchtigen."</string>
     <string name="permlab_installLocationProvider" msgid="6578101199825193873">"Berechtigung zur Installation eines Standortanbieters"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index dfc0916..5896467 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -151,7 +151,7 @@
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Sound is OFF"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Sound is ON"</string>
     <string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Airplane mode"</string>
-    <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Aiplane mode is ON"</string>
+    <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Airplane mode is ON"</string>
     <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Airplane mode is OFF"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="safeMode" msgid="2788228061547930246">"Safe mode"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index f24e64c..f7dd60b 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -1169,7 +1169,7 @@
     <string name="description_target_camera" msgid="969071997552486814">"دوربین"</string>
     <string name="description_target_silent" msgid="893551287746522182">"ساکت"</string>
     <string name="description_target_soundon" msgid="30052466675500172">"صدا روشن"</string>
-    <string name="description_target_unlock_tablet" msgid="3833195335629795055">"برای بازگشایی قفل، انگشت خود را روی صفحه بلغزانید."</string>
+    <string name="description_target_unlock_tablet" msgid="3833195335629795055">"برای بازگشایی قفل، بلغزانید."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"برای شنیدن کلیدهای گذرواژه که با صدای بلند خوانده می‌شوند، از هدست استفاده کنید."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"نقطه."</string>
     <string name="action_bar_home_description" msgid="5293600496601490216">"رفتن به صفحه اصلی"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 3c90e09..4985388 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -1169,8 +1169,7 @@
     <string name="description_target_camera" msgid="969071997552486814">"Fotoaparat"</string>
     <string name="description_target_silent" msgid="893551287746522182">"Bešumno"</string>
     <string name="description_target_soundon" msgid="30052466675500172">"Zvuk je uključen"</string>
-    <!-- no translation found for description_target_unlock_tablet (3833195335629795055) -->
-    <skip />
+    <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Prijeđite prstima da biste otključali."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Priključite slušalice da biste čuli tipke zaporke izgovorene naglas."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Točka."</string>
     <string name="action_bar_home_description" msgid="5293600496601490216">"Kreni na početnu"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 2fd2cfc..0169ea2 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -632,7 +632,7 @@
     <string name="relationTypeSister" msgid="1735983554479076481">"Irmã"</string>
     <string name="relationTypeSpouse" msgid="394136939428698117">"Cônjuge"</string>
     <string name="sipAddressTypeCustom" msgid="2473580593111590945">"Personalizado"</string>
-    <string name="sipAddressTypeHome" msgid="6093598181069359295">"Página inicial"</string>
+    <string name="sipAddressTypeHome" msgid="6093598181069359295">"Residência"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Emprego"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Outro"</string>
     <string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Introduzir código PIN"</string>
@@ -1014,7 +1014,7 @@
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formatar"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuração USB ligada"</string>
     <string name="adb_active_notification_message" msgid="8470296818270110396">"Seleccione para desactivar depuração USB."</string>
-    <string name="select_input_method" msgid="6865512749462072765">"Seleccionar método de entrada"</string>
+    <string name="select_input_method" msgid="6865512749462072765">"Selecionar método de entrada"</string>
     <string name="configure_input_methods" msgid="6324843080254191535">"Configurar métodos de entrada"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 3670e53..6334bcd 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1169,8 +1169,7 @@
     <string name="description_target_camera" msgid="969071997552486814">"Cameră foto"</string>
     <string name="description_target_silent" msgid="893551287746522182">"Silenţios"</string>
     <string name="description_target_soundon" msgid="30052466675500172">"Sunet activat"</string>
-    <!-- no translation found for description_target_unlock_tablet (3833195335629795055) -->
-    <skip />
+    <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Glisaţi pentru a debloca."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Conectaţi un set căşti-microfon pentru a auzi tastele apăsate când introduceţi parola."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punct."</string>
     <string name="action_bar_home_description" msgid="5293600496601490216">"Navigaţi la ecranul de pornire"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 24269e7..d66c2d4 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1080,7 +1080,7 @@
     <string name="submit" msgid="1602335572089911941">"Отправить"</string>
     <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"Включен режим \"Штурман\""</string>
     <string name="car_mode_disable_notification_message" msgid="668663626721675614">"Чтобы выйти, нажмите здесь."</string>
-    <string name="tethered_notification_title" msgid="3146694234398202601">"USB-модем или точка доступа Wi-Fi активны"</string>
+    <string name="tethered_notification_title" msgid="3146694234398202601">"USB-модем/точка доступа Wi-Fi используется"</string>
     <string name="tethered_notification_message" msgid="3067108323903048927">"Нажмите для настройки"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Назад"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Далее"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 157a3fc..da78c17 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -1169,8 +1169,7 @@
     <string name="description_target_camera" msgid="969071997552486814">"Камера"</string>
     <string name="description_target_silent" msgid="893551287746522182">"Нечујно"</string>
     <string name="description_target_soundon" msgid="30052466675500172">"Укључи звук"</string>
-    <!-- no translation found for description_target_unlock_tablet (3833195335629795055) -->
-    <skip />
+    <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Превуците да бисте откључали."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Укључите слушалице да бисте чули наглас изговорене тастере за лозинку."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Тачка."</string>
     <string name="action_bar_home_description" msgid="5293600496601490216">"Кретање до Почетне"</string>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index fa18648..82ef68a 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -169,6 +169,9 @@
     <!-- Size of top margin on Clock font to edge on unlock LockScreen -->
     <dimen name="keyguard_lockscreen_status_line_clockfont_bottom_margin">12dip</dimen>
 
+    <!-- Padding on left margin of PIN text entry field to center it when del button is showing -->
+    <dimen name="keyguard_lockscreen_pin_margin_left">40dip</dimen>
+
     <!-- Minimum popup width for selecting an activity in ActivityChooserDialog/ActivityChooserView. -->
     <dimen name="activity_chooser_popup_min_width">200dip</dimen>
 
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 8d95d86e5..949f01f 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -1823,6 +1823,7 @@
     </style>
 
     <style name="Widget.Holo.Tab" parent="Widget.Holo.ActionBar.TabView">
+        <item name="android:background">@android:drawable/tab_indicator_holo</item>
         <item name="android:layout_width">0dip</item>
         <item name="android:layout_weight">1</item>
         <item name="android:minWidth">80dip</item>
@@ -1910,7 +1911,7 @@
     </style>
 
     <style name="Widget.Holo.ActionBar.TabView" parent="Widget.ActionBar.TabView">
-        <item name="android:background">@drawable/tab_indicator_holo</item>
+        <item name="android:background">@drawable/tab_indicator_ab_holo</item>
         <item name="android:paddingLeft">16dip</item>
         <item name="android:paddingRight">16dip</item>
     </style>
@@ -2277,6 +2278,10 @@
     </style>
 
     <style name="Widget.Holo.Light.Tab" parent="Widget.Holo.Light.ActionBar.TabView">
+        <item name="android:background">@android:drawable/tab_indicator_holo</item>
+        <item name="android:layout_width">0dip</item>
+        <item name="android:layout_weight">1</item>
+        <item name="android:minWidth">80dip</item>
     </style>
 
     <style name="Widget.Holo.Light.ActionBar.TabBar" parent="Widget.Holo.ActionBar.TabBar">
diff --git a/core/res/res/xml-xlarge/password_kbd_numeric.xml b/core/res/res/xml-xlarge/password_kbd_numeric.xml
index 3745672..b2704f6 100755
--- a/core/res/res/xml-xlarge/password_kbd_numeric.xml
+++ b/core/res/res/xml-xlarge/password_kbd_numeric.xml
@@ -49,12 +49,10 @@
     </Row>
 
     <Row android:rowEdgeFlags="bottom">
+        <Key android:codes="48" android:keyIcon="@drawable/sym_keyboard_num0_no_plus"
+             android:keyWidth="66.66%p" android:keyEdgeFlags="left"/>
         <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_ok"
-             android:keyEdgeFlags="left"/>
-        <Key android:codes="48" android:keyIcon="@drawable/sym_keyboard_num0_no_plus"/>
-        <Key android:codes="-5" android:keyIcon="@drawable/sym_keyboard_delete"
-             android:iconPreview="@drawable/sym_keyboard_feedback_delete"
-             android:isRepeatable="true" android:keyEdgeFlags="right"/>
+             android:keyEdgeFlags="right"/>
     </Row>
 
 </Keyboard>
diff --git a/include/binder/Parcel.h b/include/binder/Parcel.h
index 3fa2acb..33b2f00 100644
--- a/include/binder/Parcel.h
+++ b/include/binder/Parcel.h
@@ -110,7 +110,8 @@
     
     // Place a file descriptor into the parcel.  The given fd must remain
     // valid for the lifetime of the parcel.
-    status_t            writeFileDescriptor(int fd);
+    // The Parcel does not take ownership of the given fd unless you ask it to.
+    status_t            writeFileDescriptor(int fd, bool takeOwnership = false);
     
     // Place a file descriptor into the parcel.  A dup of the fd is made, which
     // will be closed once the parcel is destroyed.
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index c7180ce..6b4c1a6 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -710,24 +710,19 @@
     return err;
 }
 
-status_t Parcel::writeFileDescriptor(int fd)
+status_t Parcel::writeFileDescriptor(int fd, bool takeOwnership)
 {
     flat_binder_object obj;
     obj.type = BINDER_TYPE_FD;
     obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
     obj.handle = fd;
-    obj.cookie = (void*)0;
+    obj.cookie = (void*) (takeOwnership ? 1 : 0);
     return writeObject(obj, true);
 }
 
 status_t Parcel::writeDupFileDescriptor(int fd)
 {
-    flat_binder_object obj;
-    obj.type = BINDER_TYPE_FD;
-    obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
-    obj.handle = dup(fd);
-    obj.cookie = (void*)1;
-    return writeObject(obj, true);
+    return writeFileDescriptor(dup(fd), true /*takeOwnership*/);
 }
 
 status_t Parcel::writeBlob(size_t len, WritableBlob* outBlob)
@@ -764,7 +759,7 @@
             } else {
                 status = writeInt32(1);
                 if (!status) {
-                    status = writeFileDescriptor(fd);
+                    status = writeFileDescriptor(fd, true /*takeOwnership*/);
                     if (!status) {
                         outBlob->init(true /*mapped*/, ptr, len);
                         return NO_ERROR;
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index 24ec4e8..75b07de 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -170,8 +170,11 @@
             patchCache.clear();
             dropShadowCache.clear();
             gradientCache.clear();
+            fontRenderer.clear();
             // fall through
         case kFlushMode_Moderate:
+            fontRenderer.flush();
+            textureCache.flush();
             pathCache.clear();
             roundRectShapeCache.clear();
             circleShapeCache.clear();
diff --git a/libs/hwui/GammaFontRenderer.cpp b/libs/hwui/GammaFontRenderer.cpp
index e8362dc..eb863e9 100644
--- a/libs/hwui/GammaFontRenderer.cpp
+++ b/libs/hwui/GammaFontRenderer.cpp
@@ -67,20 +67,63 @@
     const float whiteGamma = 1.0f / gamma;
 
     for (uint32_t i = 0; i <= 255; i++) {
-        mDefault[i] = i;
+        mGammaTable[i] = i;
 
         const float v = i / 255.0f;
         const float black = pow(v, blackGamma);
         const float white = pow(v, whiteGamma);
 
-        mBlackGamma[i] = uint8_t((float)::floor(black * 255.0f + 0.5f));
-        mWhiteGamma[i] = uint8_t((float)::floor(white * 255.0f + 0.5f));
+        mGammaTable[256 + i] = uint8_t((float)::floor(black * 255.0f + 0.5f));
+        mGammaTable[512 + i] = uint8_t((float)::floor(white * 255.0f + 0.5f));
     }
 
-    // Configure the font renderers
-    mDefaultRenderer.setGammaTable(&mDefault[0]);
-    mBlackGammaRenderer.setGammaTable(&mBlackGamma[0]);
-    mWhiteGammaRenderer.setGammaTable(&mWhiteGamma[0]);
+    memset(mRenderers, 0, sizeof(FontRenderer*) * kGammaCount);
+    memset(mRenderersUsageCount, 0, sizeof(uint32_t) * kGammaCount);
+}
+
+GammaFontRenderer::~GammaFontRenderer() {
+    for (int i = 0; i < kGammaCount; i++) {
+        delete mRenderers[i];
+    }
+}
+
+void GammaFontRenderer::clear() {
+    for (int i = 0; i < kGammaCount; i++) {
+        delete mRenderers[i];
+        mRenderers[i] = NULL;
+    }
+}
+
+void GammaFontRenderer::flush() {
+    int count = 0;
+    int min = -1;
+    uint32_t minCount = UINT_MAX;
+
+    for (int i = 0; i < kGammaCount; i++) {
+        if (mRenderers[i]) {
+            count++;
+            if (mRenderersUsageCount[i] < minCount) {
+                minCount = mRenderersUsageCount[i];
+                min = i;
+            }
+        }
+    }
+
+    if (count <= 1 || min < 0) return;
+
+    delete mRenderers[min];
+    mRenderers[min] = NULL;
+}
+
+FontRenderer* GammaFontRenderer::getRenderer(Gamma gamma) {
+    FontRenderer* renderer = mRenderers[gamma];
+    if (!renderer) {
+        renderer = new FontRenderer();
+        mRenderers[gamma] = renderer;
+        renderer->setGammaTable(&mGammaTable[gamma * 256]);
+    }
+    mRenderersUsageCount[gamma]++;
+    return renderer;
 }
 
 FontRenderer& GammaFontRenderer::getFontRenderer(const SkPaint* paint) {
@@ -92,12 +135,12 @@
         const int luminance = (r * 2 + g * 5 + b) >> 3;
 
         if (luminance <= mBlackThreshold) {
-            return mBlackGammaRenderer;
+            return *getRenderer(kGammaBlack);
         } else if (luminance >= mWhiteThreshold) {
-            return mWhiteGammaRenderer;
+            return *getRenderer(kGammaWhite);
         }
     }
-    return mDefaultRenderer;
+    return *getRenderer(kGammaDefault);
 }
 
 }; // namespace uirenderer
diff --git a/libs/hwui/GammaFontRenderer.h b/libs/hwui/GammaFontRenderer.h
index 96d960c..54c208e 100644
--- a/libs/hwui/GammaFontRenderer.h
+++ b/libs/hwui/GammaFontRenderer.h
@@ -26,36 +26,43 @@
 
 struct GammaFontRenderer {
     GammaFontRenderer();
+    ~GammaFontRenderer();
+
+    enum Gamma {
+        kGammaDefault = 0,
+        kGammaBlack = 1,
+        kGammaWhite = 2,
+        kGammaCount = 3
+    };
+
+    void clear();
+    void flush();
 
     FontRenderer& getFontRenderer(const SkPaint* paint);
 
     uint32_t getFontRendererCount() const {
-        return 3;
+        return kGammaCount;
     }
 
     uint32_t getFontRendererSize(uint32_t fontRenderer) const {
-        switch (fontRenderer) {
-            case 0:
-                return mDefaultRenderer.getCacheHeight() * mDefaultRenderer.getCacheWidth();
-            case 1:
-                return mBlackGammaRenderer.getCacheHeight() * mBlackGammaRenderer.getCacheWidth();
-            case 2:
-                return mWhiteGammaRenderer.getCacheHeight() * mWhiteGammaRenderer.getCacheWidth();
-        }
-        return 0;
+        if (fontRenderer >= kGammaCount) return 0;
+
+        FontRenderer* renderer = mRenderers[fontRenderer];
+        if (!renderer) return 0;
+
+        return renderer->getCacheHeight() * renderer->getCacheWidth();
     }
 
 private:
-    FontRenderer mDefaultRenderer;
-    FontRenderer mBlackGammaRenderer;
-    FontRenderer mWhiteGammaRenderer;
+    FontRenderer* getRenderer(Gamma gamma);
+
+    uint32_t mRenderersUsageCount[kGammaCount];
+    FontRenderer* mRenderers[kGammaCount];
 
     int mBlackThreshold;
     int mWhiteThreshold;
 
-    uint8_t mDefault[256];
-    uint8_t mBlackGamma[256];
-    uint8_t mWhiteGamma[256];
+    uint8_t mGammaTable[256 * kGammaCount];
 };
 
 }; // namespace uirenderer
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index 5bd0d4f..8c01e3a 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -61,6 +61,9 @@
 #define PROPERTY_DROP_SHADOW_CACHE_SIZE "ro.hwui.drop_shadow_cache_size"
 #define PROPERTY_FBO_CACHE_SIZE "ro.hwui.fbo_cache_size"
 
+// These properties are defined in percentage (range 0..1)
+#define PROPERTY_TEXTURE_CACHE_FLUSH_RATE "ro.hwui.texture_cache_flush_rate"
+
 // These properties are defined in pixels
 #define PROPERTY_TEXT_CACHE_WIDTH "ro.hwui.text_cache_width"
 #define PROPERTY_TEXT_CACHE_HEIGHT "ro.hwui.text_cache_height"
@@ -82,6 +85,8 @@
 #define DEFAULT_DROP_SHADOW_CACHE_SIZE 2.0f
 #define DEFAULT_FBO_CACHE_SIZE 16
 
+#define DEFAULT_TEXTURE_CACHE_FLUSH_RATE 0.6f
+
 #define DEFAULT_TEXT_GAMMA 1.4f
 #define DEFAULT_TEXT_BLACK_GAMMA_THRESHOLD 64
 #define DEFAULT_TEXT_WHITE_GAMMA_THRESHOLD 192
diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp
index fbdbf92..018ce3e 100644
--- a/libs/hwui/TextureCache.cpp
+++ b/libs/hwui/TextureCache.cpp
@@ -34,7 +34,8 @@
 
 TextureCache::TextureCache():
         mCache(GenerationCache<SkBitmap*, Texture*>::kUnlimitedCapacity),
-        mSize(0), mMaxSize(MB(DEFAULT_TEXTURE_CACHE_SIZE)) {
+        mSize(0), mMaxSize(MB(DEFAULT_TEXTURE_CACHE_SIZE)),
+        mFlushRate(DEFAULT_TEXTURE_CACHE_FLUSH_RATE) {
     char property[PROPERTY_VALUE_MAX];
     if (property_get(PROPERTY_TEXTURE_CACHE_SIZE, property, NULL) > 0) {
         INIT_LOGD("  Setting texture cache size to %sMB", property);
@@ -43,6 +44,15 @@
         INIT_LOGD("  Using default texture cache size of %.2fMB", DEFAULT_TEXTURE_CACHE_SIZE);
     }
 
+    if (property_get(PROPERTY_TEXTURE_CACHE_FLUSH_RATE, property, NULL) > 0) {
+        float flushRate = atof(property);
+        INIT_LOGD("  Setting texture cache flush rate to %.2f%%", flushRate * 100.0f);
+        setFlushRate(flushRate);
+    } else {
+        INIT_LOGD("  Using default texture cache flush rate of %.2f%%",
+                DEFAULT_TEXTURE_CACHE_FLUSH_RATE * 100.0f);
+    }
+
     init();
 }
 
@@ -84,6 +94,10 @@
     }
 }
 
+void TextureCache::setFlushRate(float flushRate) {
+    mFlushRate = fmaxf(0.0f, fminf(1.0f, flushRate));
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 // Callbacks
 ///////////////////////////////////////////////////////////////////////////////
@@ -168,6 +182,21 @@
     TEXTURE_LOGD("TextureCache:clear(), mSize = %d", mSize);
 }
 
+void TextureCache::flush() {
+    if (mFlushRate >= 1.0f || mCache.size() == 0) return;
+    if (mFlushRate <= 0.0f) {
+        clear();
+        return;
+    }
+
+    uint32_t targetSize = uint32_t(mSize * mFlushRate);
+    TEXTURE_LOGD("TextureCache::flush: target size: %d", targetSize);
+
+    while (mSize > targetSize) {
+        mCache.removeOldest();
+    }
+}
+
 void TextureCache::generateTexture(SkBitmap* bitmap, Texture* texture, bool regenerate) {
     SkAutoLockPixels alp(*bitmap);
 
diff --git a/libs/hwui/TextureCache.h b/libs/hwui/TextureCache.h
index f7707f7..ce924b4 100644
--- a/libs/hwui/TextureCache.h
+++ b/libs/hwui/TextureCache.h
@@ -98,6 +98,17 @@
      */
     uint32_t getSize();
 
+    /**
+     * Partially flushes the cache. The amount of memory freed by a flush
+     * is defined by the flush rate.
+     */
+    void flush();
+    /**
+     * Indicates the percentage of the cache to retain when a
+     * memory trim is requested (see Caches::flush).
+     */
+    void setFlushRate(float flushRate);
+
 private:
     /**
      * Generates the texture from a bitmap into the specified texture structure.
@@ -119,6 +130,8 @@
     uint32_t mMaxSize;
     GLint mMaxTextureSize;
 
+    float mFlushRate;
+
     bool mDebugEnabled;
 
     Vector<SkBitmap*> mGarbage;
diff --git a/opengl/libs/Android.mk b/opengl/libs/Android.mk
index 3e66a13..5855b63 100644
--- a/opengl/libs/Android.mk
+++ b/opengl/libs/Android.mk
@@ -8,6 +8,7 @@
 
 LOCAL_SRC_FILES:= 	       \
 	EGL/egl_tls.cpp        \
+	EGL/egl_cache.cpp      \
 	EGL/egl_display.cpp    \
 	EGL/egl_object.cpp     \
 	EGL/egl.cpp 	       \
@@ -157,4 +158,3 @@
 include $(BUILD_SHARED_LIBRARY)
 
 include $(call all-makefiles-under,$(LOCAL_PATH))
-
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index 1f9ce68..60ac34b 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -858,10 +858,17 @@
         return  NULL;
     }
 
+    // The EGL_ANDROID_blob_cache extension should not be exposed to
+    // applications.  It is used internally by the Android EGL layer.
+    if (!strcmp(procname, "eglSetBlobCacheFuncs")) {
+        return NULL;
+    }
+
     __eglMustCastToProperFunctionPointerType addr;
     addr = findProcAddress(procname, sExtentionMap, NELEM(sExtentionMap));
     if (addr) return addr;
 
+
     // this protects accesses to sGLExtentionMap and sGLExtentionSlot
     pthread_mutex_lock(&sExtensionMapMutex);
 
diff --git a/opengl/libs/EGL/egl_cache.cpp b/opengl/libs/EGL/egl_cache.cpp
new file mode 100644
index 0000000..1e64302
--- /dev/null
+++ b/opengl/libs/EGL/egl_cache.cpp
@@ -0,0 +1,95 @@
+/*
+ ** Copyright 2011, 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.
+ */
+
+#include "egl_cache.h"
+#include "egl_display.h"
+#include "egl_impl.h"
+#include "egldefs.h"
+
+// ----------------------------------------------------------------------------
+namespace android {
+// ----------------------------------------------------------------------------
+
+#define BC_EXT_STR "EGL_ANDROID_blob_cache"
+
+//
+// EGL_ANDROID_blob_cache types and functions
+//
+typedef khronos_ssize_t EGLsizei;
+
+typedef void (*EGLSetBlobFunc) (const void* key, EGLsizei keySize,
+        const void* value, EGLsizei valueSize);
+
+typedef EGLsizei (*EGLGetBlobFunc) (const void* key, EGLsizei keySize,
+        void* value, EGLsizei valueSize);
+
+typedef void (EGLAPIENTRYP PFNEGLSETBLOBCACHEFUNCSPROC) (EGLDisplay dpy,
+        EGLSetBlobFunc set, EGLGetBlobFunc get);
+
+//
+// egl_cache_t definition
+//
+static void setBlob(const void* key, EGLsizei keySize, const void* value,
+        EGLsizei valueSize) {
+}
+
+static EGLsizei getBlob(const void* key, EGLsizei keySize, void* value,
+        EGLsizei valueSize) {
+    return 0;
+}
+
+egl_cache_t* egl_cache_t::get() {
+    static egl_cache_t theCache;
+    return &theCache;
+}
+
+void egl_cache_t::initialize(egl_display_t *display) {
+    for (int i = 0; i < IMPL_NUM_IMPLEMENTATIONS; i++) {
+        egl_connection_t* const cnx = &gEGLImpl[i];
+        if (cnx->dso && cnx->major >= 0 && cnx->minor >= 0) {
+            const char* exts = display->disp[i].queryString.extensions;
+            size_t bcExtLen = strlen(BC_EXT_STR);
+            size_t extsLen = strlen(exts);
+            bool equal = !strcmp(BC_EXT_STR, exts);
+            bool atStart = !strncmp(BC_EXT_STR " ", exts, bcExtLen+1);
+            bool atEnd = (bcExtLen+1) < extsLen &&
+                    !strcmp(" " BC_EXT_STR, exts + extsLen - (bcExtLen+1));
+            bool inMiddle = strstr(" " BC_EXT_STR " ", exts);
+            if (equal || atStart || atEnd || inMiddle) {
+                PFNEGLSETBLOBCACHEFUNCSPROC eglSetBlobCacheFuncs;
+                eglSetBlobCacheFuncs =
+                        reinterpret_cast<PFNEGLSETBLOBCACHEFUNCSPROC>(
+                            cnx->egl.eglGetProcAddress("eglSetBlobCacheFuncs"));
+                if (eglSetBlobCacheFuncs == NULL) {
+                    LOGE("EGL_ANDROID_blob_cache advertised by display %d, "
+                            "but unable to get eglSetBlobCacheFuncs", i);
+                    continue;
+                }
+
+                eglSetBlobCacheFuncs(display->disp[i].dpy, setBlob, getBlob);
+                EGLint err = cnx->egl.eglGetError();
+                if (err != EGL_SUCCESS) {
+                    LOGE("eglSetBlobCacheFuncs resulted in an error: %#x",
+                            err);
+                }
+            }
+        }
+    }
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+// ----------------------------------------------------------------------------
diff --git a/opengl/libs/EGL/egl_cache.h b/opengl/libs/EGL/egl_cache.h
new file mode 100644
index 0000000..1fcfacc
--- /dev/null
+++ b/opengl/libs/EGL/egl_cache.h
@@ -0,0 +1,33 @@
+/*
+ ** Copyright 2011, 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.
+ */
+
+// ----------------------------------------------------------------------------
+namespace android {
+// ----------------------------------------------------------------------------
+
+class egl_display_t;
+
+class egl_cache_t {
+public:
+
+    static egl_cache_t* get();
+
+    void initialize(egl_display_t* display);
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+// ----------------------------------------------------------------------------
diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp
index 83aafa6..0f92864 100644
--- a/opengl/libs/EGL/egl_display.cpp
+++ b/opengl/libs/EGL/egl_display.cpp
@@ -14,6 +14,7 @@
  ** limitations under the License.
  */
 
+#include "egl_cache.h"
 #include "egl_display.h"
 #include "egl_object.h"
 #include "egl_tls.h"
@@ -170,6 +171,8 @@
         }
     }
 
+    egl_cache_t::get()->initialize(this);
+
     EGLBoolean res = EGL_FALSE;
     for (int i = 0; i < IMPL_NUM_IMPLEMENTATIONS; i++) {
         egl_connection_t* const cnx = &gEGLImpl[i];
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 64c54d9..eefb9fe 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -46,6 +46,16 @@
             </intent-filter>
         </receiver>
 
+        <!-- handle dock insertion, launch screensaver instead -->
+        <activity android:name=".DreamsDockLauncher"
+                android:label="@string/dreams_dock_launcher">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.DESK_DOCK" />
+            </intent-filter>
+        </activity>
+
         <activity android:name=".usb.UsbStorageActivity"
                 android:excludeFromRecents="true">
         </activity>
diff --git a/packages/SystemUI/res/drawable-hdpi/screenshot_panel.9.png b/packages/SystemUI/res/drawable-hdpi/screenshot_panel.9.png
index 9447e01..2509321 100644
--- a/packages/SystemUI/res/drawable-hdpi/screenshot_panel.9.png
+++ b/packages/SystemUI/res/drawable-hdpi/screenshot_panel.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/screenshot_panel.9.png b/packages/SystemUI/res/drawable-mdpi/screenshot_panel.9.png
index 7f1aea1..be1cd31 100644
--- a/packages/SystemUI/res/drawable-mdpi/screenshot_panel.9.png
+++ b/packages/SystemUI/res/drawable-mdpi/screenshot_panel.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/screenshot_panel.9.png b/packages/SystemUI/res/drawable-xhdpi/screenshot_panel.9.png
index e5cfc36..c096c7a 100644
--- a/packages/SystemUI/res/drawable-xhdpi/screenshot_panel.9.png
+++ b/packages/SystemUI/res/drawable-xhdpi/screenshot_panel.9.png
Binary files differ
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_notification_panel_title.xml b/packages/SystemUI/res/layout-sw600dp/status_bar_notification_panel_title.xml
index fecef3d..46f4c39 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar_notification_panel_title.xml
+++ b/packages/SystemUI/res/layout-sw600dp/status_bar_notification_panel_title.xml
@@ -39,39 +39,39 @@
 
         <ImageView
             android:id="@+id/bluetooth"
-            android:layout_height="32dp"
-            android:layout_width="32dp"
+            android:layout_height="wrap_content"
+            android:layout_width="wrap_content"
             android:scaleType="centerInside"
-            android:baseline="22dp"
+            android:baseline="18dp"
             android:visibility="gone"
             android:contentDescription="@null"
             />
 
         <FrameLayout
             android:id="@+id/netwerk"
-            android:layout_height="32dp"
-            android:layout_width="32dp"
+            android:layout_height="wrap_content"
+            android:layout_width="wrap_content"
             android:layout_marginRight="4dp"
             >
 
             <ImageView
                 android:id="@+id/network_signal"
-                android:layout_height="match_parent"
-                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
                 android:contentDescription="@null"
                 />
 
             <ImageView
                 android:id="@+id/network_type"
-                android:layout_height="match_parent"
-                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
                 android:contentDescription="@null"
                 />
 
             <ImageView
                 android:id="@+id/network_direction"
-                android:layout_height="match_parent"
-                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
                 android:contentDescription="@null"
                 />
 
@@ -91,12 +91,14 @@
 
         <ImageView
             android:id="@+id/battery"
-            android:layout_height="32dp"
-            android:layout_width="32dp"
+            android:layout_height="wrap_content"
+            android:layout_width="wrap_content"
             android:scaleType="centerInside"
             android:layout_toRightOf="@id/network_text"
             android:layout_alignBaseline="@id/network_signal"
-            android:baseline="22dp"
+            android:baseline="18dp"
+            android:layout_marginLeft="8dp"
+            android:layout_marginRight="8dp"
             android:contentDescription="@null"
             />
 
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 947ebb4..a8e7d0d 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -110,7 +110,7 @@
     <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
     <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
     <string name="accessibility_no_sim" msgid="8274017118472455155">"SIM-карта отсутствует."</string>
-    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Общий Bluetooth-модем."</string>
+    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetooth-модем"</string>
     <string name="accessibility_airplane_mode" msgid="834748999790763092">"Режим полета."</string>
     <!-- String.format failed for translation -->
     <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 8108a90..1a6cae2 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -351,4 +351,7 @@
 
     <!-- Content description of the clear button in the notification panel for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_clear_all">Clear all notifications.</string>
+
+    <!-- Description of the desk dock action that invokes the Android Dreams screen saver feature -->
+    <string name="dreams_dock_launcher">Activate screen saver</string>
 </resources>
diff --git a/packages/SystemUI/src/com/android/systemui/DreamsDockLauncher.java b/packages/SystemUI/src/com/android/systemui/DreamsDockLauncher.java
new file mode 100644
index 0000000..b8cdd73
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/DreamsDockLauncher.java
@@ -0,0 +1,39 @@
+package com.android.systemui;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.util.Slog;
+
+public class DreamsDockLauncher extends Activity {
+    private static final String TAG = "DreamsDockLauncher";
+    @Override
+    protected void onCreate (Bundle icicle) {
+        super.onCreate(icicle);
+        try {
+            String component = Settings.Secure.getString(
+                    getContentResolver(), Settings.Secure.DREAM_COMPONENT);
+            if (component != null) {
+                ComponentName cn = ComponentName.unflattenFromString(component);
+                Intent zzz = new Intent(Intent.ACTION_MAIN)
+                    .setComponent(cn)
+                    .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+                        | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
+                        | Intent.FLAG_ACTIVITY_NO_USER_ACTION
+                        );
+                startActivity(zzz);
+            } else {
+                Slog.e(TAG, "Couldn't start screen saver: none selected");
+            }
+        } catch (android.content.ActivityNotFoundException exc) {
+            // no screensaver? give up
+            Slog.e(TAG, "Couldn't start screen saver: none installed");
+        }
+        finish();
+    }
+}
diff --git a/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java b/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java
index 3ad716b..06cd69e 100644
--- a/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java
@@ -35,15 +35,18 @@
 import android.text.TextWatcher;
 import android.text.method.DigitsKeyListener;
 import android.text.method.TextKeyListener;
+import android.view.Gravity;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.View;
+import android.view.ViewGroup.LayoutParams;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputMethodInfo;
 import android.view.inputmethod.InputMethodManager;
 import android.view.inputmethod.InputMethodSubtype;
 import android.widget.EditText;
 import android.widget.LinearLayout;
+import android.widget.Space;
 import android.widget.TextView;
 import android.widget.TextView.OnEditorActionListener;
 
@@ -114,6 +117,7 @@
                 Settings.Secure.getInt(mContext.getContentResolver(),
                         Settings.Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED, 0)
                         != 0);
+        boolean imeOrDeleteButtonVisible = false;
         if (mIsAlpha) {
             // We always use the system IME for alpha keyboard, so hide lockscreen's soft keyboard
             mKeyboardHelper.setKeyboardMode(PasswordEntryKeyboardHelper.KEYBOARD_MODE_ALPHA);
@@ -129,6 +133,7 @@
             View pinDelete = findViewById(R.id.pinDel);
             if (pinDelete != null) {
                 pinDelete.setVisibility(View.VISIBLE);
+                imeOrDeleteButtonVisible = true;
                 pinDelete.setOnClickListener(new OnClickListener() {
                     @Override
                     public void onClick(View v) {
@@ -181,6 +186,7 @@
                 Context.INPUT_METHOD_SERVICE);
         if (mIsAlpha && switchImeButton != null && hasMultipleEnabledIMEsOrSubtypes(imm, false)) {
             switchImeButton.setVisibility(View.VISIBLE);
+            imeOrDeleteButtonVisible = true;
             switchImeButton.setOnClickListener(new OnClickListener() {
                 public void onClick(View v) {
                     mCallback.pokeWakelock(); // Leave the screen on a bit longer
@@ -188,6 +194,16 @@
                 }
             });
         }
+
+        // If no icon is visible, reset the left margin on the password field so the text is
+        // still centered.
+        if (!imeOrDeleteButtonVisible) {
+            android.view.ViewGroup.LayoutParams params = mPasswordEntry.getLayoutParams();
+            if (params instanceof MarginLayoutParams) {
+                ((MarginLayoutParams)params).leftMargin = 0;
+                mPasswordEntry.setLayoutParams(params);
+            }
+        }
     }
 
     /**
diff --git a/preloaded-classes b/preloaded-classes
index 31d49ce..c29ba15 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -18,7 +18,12 @@
 android.accounts.IAccountManagerResponse$Stub
 android.animation.Animator
 android.animation.Animator$AnimatorListener
+android.animation.AnimatorInflater
 android.animation.AnimatorListenerAdapter
+android.animation.AnimatorSet
+android.animation.AnimatorSet$AnimatorSetListener
+android.animation.AnimatorSet$Builder
+android.animation.AnimatorSet$Node
 android.animation.FloatEvaluator
 android.animation.FloatKeyframeSet
 android.animation.IntEvaluator
@@ -57,6 +62,7 @@
 android.app.ActivityThread$GcIdler
 android.app.ActivityThread$H
 android.app.ActivityThread$Idler
+android.app.ActivityThread$Profiler
 android.app.ActivityThread$ProviderClientRecord
 android.app.ActivityThread$ProviderRefCount
 android.app.ActivityThread$ReceiverData
@@ -71,6 +77,8 @@
 android.app.ApplicationPackageManager
 android.app.ApplicationPackageManager$ResourceName
 android.app.ApplicationThreadNative
+android.app.BackStackRecord
+android.app.BackStackRecord$Op
 android.app.ContextImpl
 android.app.ContextImpl$1
 android.app.ContextImpl$10
@@ -111,9 +119,15 @@
 android.app.Dialog
 android.app.Dialog$1
 android.app.Dialog$ListenersHandler
+android.app.DialogFragment
+android.app.Fragment
 android.app.FragmentManager
+android.app.FragmentManager$BackStackEntry
 android.app.FragmentManagerImpl
 android.app.FragmentManagerImpl$1
+android.app.FragmentManagerImpl$2
+android.app.FragmentManagerImpl$3
+android.app.FragmentTransaction
 android.app.IActivityManager
 android.app.IActivityManager$ContentProviderHolder
 android.app.IActivityManager$ContentProviderHolder$1
@@ -134,6 +148,10 @@
 android.app.IntentReceiverLeaked
 android.app.IntentService
 android.app.IntentService$ServiceHandler
+android.app.ListActivity
+android.app.ListActivity$1
+android.app.ListActivity$2
+android.app.ListFragment
 android.app.LoadedApk
 android.app.LoadedApk$ReceiverDispatcher
 android.app.LoadedApk$ReceiverDispatcher$Args
@@ -328,6 +346,7 @@
 android.graphics.AvoidXfermode
 android.graphics.Bitmap
 android.graphics.Bitmap$1
+android.graphics.Bitmap$2
 android.graphics.Bitmap$BitmapFinalizer
 android.graphics.Bitmap$Config
 android.graphics.BitmapFactory
@@ -719,6 +738,7 @@
 android.text.style.MetricAffectingSpan
 android.text.style.ParagraphStyle
 android.text.style.ReplacementSpan
+android.text.style.SpellCheckSpan
 android.text.style.StyleSpan
 android.text.style.SuggestionSpan
 android.text.style.UpdateAppearance
@@ -870,6 +890,7 @@
 android.view.View$OnTouchListener
 android.view.View$PerformClick
 android.view.View$ScrollabilityCache
+android.view.View$TransformationInfo
 android.view.View$UnsetPressedState
 android.view.ViewConfiguration
 android.view.ViewGroup
@@ -934,6 +955,7 @@
 android.view.inputmethod.ExtractedText
 android.view.inputmethod.ExtractedText$1
 android.view.inputmethod.InputConnection
+android.view.inputmethod.InputConnectionWrapper
 android.view.inputmethod.InputMethodManager
 android.view.inputmethod.InputMethodManager$1
 android.view.inputmethod.InputMethodManager$ControlledInputConnectionWrapper
@@ -946,12 +968,16 @@
 android.widget.AbsListView
 android.widget.AbsListView$1
 android.widget.AbsListView$2
+android.widget.AbsListView$3
 android.widget.AbsListView$AdapterDataSetObserver
 android.widget.AbsListView$CheckForTap
+android.widget.AbsListView$FlingRunnable
+android.widget.AbsListView$FlingRunnable$1
 android.widget.AbsListView$LayoutParams
 android.widget.AbsListView$OnScrollListener
 android.widget.AbsListView$PerformClick
 android.widget.AbsListView$RecycleBin
+android.widget.AbsListView$RecyclerListener
 android.widget.AbsListView$SavedState
 android.widget.AbsListView$SavedState$1
 android.widget.AbsListView$SelectionBoundsAdjuster
@@ -975,13 +1001,19 @@
 android.widget.Checkable
 android.widget.CheckedTextView
 android.widget.CompoundButton
+android.widget.CompoundButton$OnCheckedChangeListener
 android.widget.CursorAdapter
 android.widget.CursorFilter$CursorFilterClient
+android.widget.EdgeEffect
 android.widget.EdgeGlow
 android.widget.EditText
 android.widget.ExpandableListView
+android.widget.FastScroller
+android.widget.FastScroller$1
+android.widget.FastScroller$ScrollFade
 android.widget.Filter
 android.widget.Filter$FilterListener
+android.widget.Filter$FilterResults
 android.widget.Filter$ResultsHandler
 android.widget.Filterable
 android.widget.FrameLayout
@@ -1030,17 +1062,30 @@
 android.widget.Spinner
 android.widget.SpinnerAdapter
 android.widget.StackView
+android.widget.Switch
 android.widget.TabHost
+android.widget.TabHost$ContentStrategy
+android.widget.TabHost$FactoryContentStrategy
+android.widget.TabHost$IndicatorStrategy
+android.widget.TabHost$LabelAndIconIndicatorStrategy
+android.widget.TabHost$OnTabChangeListener
+android.widget.TabHost$TabContentFactory
+android.widget.TabHost$TabSpec
+android.widget.TabHost$ViewIndicatorStrategy
 android.widget.TabWidget
+android.widget.TabWidget$OnTabSelectionChanged
+android.widget.TabWidget$TabClickListener
 android.widget.TableLayout
 android.widget.TableRow
 android.widget.TextView
+android.widget.TextView$2
 android.widget.TextView$3
 android.widget.TextView$Blink
 android.widget.TextView$BufferType
 android.widget.TextView$ChangeWatcher
 android.widget.TextView$CharWrapper
 android.widget.TextView$Drawables
+android.widget.TextView$EasyEditSpanController
 android.widget.TextView$InputContentType
 android.widget.TextView$InputMethodState
 android.widget.TextView$OnEditorActionListener
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 851cb33..8c42f31 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -171,6 +171,12 @@
     private static final int ENABLED  = 1;
     private static final int DISABLED = 0;
 
+    private static final boolean ADD = true;
+    private static final boolean REMOVE = false;
+
+    private static final boolean TO_DEFAULT_TABLE = true;
+    private static final boolean TO_SECONDARY_TABLE = false;
+
     // Share the event space with NetworkStateTracker (which can't see this
     // internal class but sends us events).  If you change these, change
     // NetworkStateTracker.java too.
@@ -501,7 +507,7 @@
         IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
         INetworkManagementService nmService = INetworkManagementService.Stub.asInterface(b);
 
-        mTethering = new Tethering(mContext, nmService, statsService, mHandler.getLooper());
+        mTethering = new Tethering(mContext, nmService, statsService, this, mHandler.getLooper());
         mTetheringConfigValid = ((mTethering.getTetherableUsbRegexs().length != 0 ||
                                   mTethering.getTetherableWifiRegexs().length != 0 ||
                                   mTethering.getTetherableBluetoothRegexs().length != 0) &&
@@ -1146,23 +1152,24 @@
         return false;
     }
 
-    private boolean addRoute(LinkProperties p, RouteInfo r) {
-        return modifyRoute(p.getInterfaceName(), p, r, 0, true);
+    private boolean addRoute(LinkProperties p, RouteInfo r, boolean toDefaultTable) {
+        return modifyRoute(p.getInterfaceName(), p, r, 0, ADD, toDefaultTable);
     }
 
-    private boolean removeRoute(LinkProperties p, RouteInfo r) {
-        return modifyRoute(p.getInterfaceName(), p, r, 0, false);
+    private boolean removeRoute(LinkProperties p, RouteInfo r, boolean toDefaultTable) {
+        return modifyRoute(p.getInterfaceName(), p, r, 0, REMOVE, toDefaultTable);
     }
 
     private boolean addRouteToAddress(LinkProperties lp, InetAddress addr) {
-        return modifyRouteToAddress(lp, addr, true);
+        return modifyRouteToAddress(lp, addr, ADD, TO_DEFAULT_TABLE);
     }
 
     private boolean removeRouteToAddress(LinkProperties lp, InetAddress addr) {
-        return modifyRouteToAddress(lp, addr, false);
+        return modifyRouteToAddress(lp, addr, REMOVE, TO_DEFAULT_TABLE);
     }
 
-    private boolean modifyRouteToAddress(LinkProperties lp, InetAddress addr, boolean doAdd) {
+    private boolean modifyRouteToAddress(LinkProperties lp, InetAddress addr, boolean doAdd,
+            boolean toDefaultTable) {
         RouteInfo bestRoute = RouteInfo.selectBestRoute(lp.getRoutes(), addr);
         if (bestRoute == null) {
             bestRoute = RouteInfo.makeHostRoute(addr);
@@ -1176,15 +1183,15 @@
                 bestRoute = RouteInfo.makeHostRoute(addr, bestRoute.getGateway());
             }
         }
-        return modifyRoute(lp.getInterfaceName(), lp, bestRoute, 0, doAdd);
+        return modifyRoute(lp.getInterfaceName(), lp, bestRoute, 0, doAdd, toDefaultTable);
     }
 
     private boolean modifyRoute(String ifaceName, LinkProperties lp, RouteInfo r, int cycleCount,
-            boolean doAdd) {
+            boolean doAdd, boolean toDefaultTable) {
         if ((ifaceName == null) || (lp == null) || (r == null)) return false;
 
         if (cycleCount > MAX_HOSTROUTE_CYCLE_COUNT) {
-            loge("Error adding route - too much recursion");
+            loge("Error modifying route - too much recursion");
             return false;
         }
 
@@ -1199,14 +1206,18 @@
                     // route to it's gateway
                     bestRoute = RouteInfo.makeHostRoute(r.getGateway(), bestRoute.getGateway());
                 }
-                modifyRoute(ifaceName, lp, bestRoute, cycleCount+1, doAdd);
+                modifyRoute(ifaceName, lp, bestRoute, cycleCount+1, doAdd, toDefaultTable);
             }
         }
         if (doAdd) {
             if (VDBG) log("Adding " + r + " for interface " + ifaceName);
-            mAddedRoutes.add(r);
             try {
-                mNetd.addRoute(ifaceName, r);
+                if (toDefaultTable) {
+                    mAddedRoutes.add(r);  // only track default table - only one apps can effect
+                    mNetd.addRoute(ifaceName, r);
+                } else {
+                    mNetd.addSecondaryRoute(ifaceName, r);
+                }
             } catch (Exception e) {
                 // never crash - catch them all
                 if (VDBG) loge("Exception trying to add a route: " + e);
@@ -1215,18 +1226,29 @@
         } else {
             // if we remove this one and there are no more like it, then refcount==0 and
             // we can remove it from the table
-            mAddedRoutes.remove(r);
-            if (mAddedRoutes.contains(r) == false) {
+            if (toDefaultTable) {
+                mAddedRoutes.remove(r);
+                if (mAddedRoutes.contains(r) == false) {
+                    if (VDBG) log("Removing " + r + " for interface " + ifaceName);
+                    try {
+                        mNetd.removeRoute(ifaceName, r);
+                    } catch (Exception e) {
+                        // never crash - catch them all
+                        if (VDBG) loge("Exception trying to remove a route: " + e);
+                        return false;
+                    }
+                } else {
+                    if (VDBG) log("not removing " + r + " as it's still in use");
+                }
+            } else {
                 if (VDBG) log("Removing " + r + " for interface " + ifaceName);
                 try {
-                    mNetd.removeRoute(ifaceName, r);
+                    mNetd.removeSecondaryRoute(ifaceName, r);
                 } catch (Exception e) {
                     // never crash - catch them all
                     if (VDBG) loge("Exception trying to remove a route: " + e);
                     return false;
                 }
-            } else {
-                if (VDBG) log("not removing " + r + " as it's still in use");
             }
         }
         return true;
@@ -1862,14 +1884,21 @@
 
         for (RouteInfo r : routeDiff.removed) {
             if (isLinkDefault || ! r.isDefaultRoute()) {
-                removeRoute(curLp, r);
+                removeRoute(curLp, r, TO_DEFAULT_TABLE);
+            }
+            if (isLinkDefault == false) {
+                // remove from a secondary route table
+                removeRoute(curLp, r, TO_SECONDARY_TABLE);
             }
         }
 
         for (RouteInfo r :  routeDiff.added) {
             if (isLinkDefault || ! r.isDefaultRoute()) {
-                addRoute(newLp, r);
+                addRoute(newLp, r, TO_DEFAULT_TABLE);
             } else {
+                // add to a secondary route table
+                addRoute(newLp, r, TO_SECONDARY_TABLE);
+
                 // many radios add a default route even when we don't want one.
                 // remove the default route unless somebody else has asked for it
                 String ifaceName = newLp.getInterfaceName();
@@ -2450,12 +2479,6 @@
         int defaultVal = (SystemProperties.get("ro.tether.denied").equals("true") ? 0 : 1);
         boolean tetherEnabledInSettings = (Settings.Secure.getInt(mContext.getContentResolver(),
                 Settings.Secure.TETHER_SUPPORTED, defaultVal) != 0);
-        // Short term disabling of Tethering if DUN is required.
-        // TODO - fix multi-connection tethering using policy-base routing
-        int[] upstreamConnTypes = mTethering.getUpstreamIfaceTypes();
-        for (int i : upstreamConnTypes) {
-            if (i == ConnectivityManager.TYPE_MOBILE_DUN) return false;
-        }
         return tetherEnabledInSettings && mTetheringConfigValid;
     }
 
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index 4e4fe4a..6887de3 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -59,7 +59,11 @@
 import java.io.PrintWriter;
 import java.net.Inet4Address;
 import java.net.InetAddress;
+import java.net.InterfaceAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashSet;
 import java.util.NoSuchElementException;
 import java.util.StringTokenizer;
@@ -77,6 +81,9 @@
     private static final int ADD = 1;
     private static final int REMOVE = 2;
 
+    private static final String DEFAULT = "default";
+    private static final String SECONDARY = "secondary";
+
     /**
      * Name representing {@link #setGlobalAlert(long)} limit when delivered to
      * {@link INetworkManagementEventObserver#limitReached(String, String)}.
@@ -505,15 +512,25 @@
 
     public void addRoute(String interfaceName, RouteInfo route) {
         mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG);
-        modifyRoute(interfaceName, ADD, route);
+        modifyRoute(interfaceName, ADD, route, DEFAULT);
     }
 
     public void removeRoute(String interfaceName, RouteInfo route) {
         mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG);
-        modifyRoute(interfaceName, REMOVE, route);
+        modifyRoute(interfaceName, REMOVE, route, DEFAULT);
     }
 
-    private void modifyRoute(String interfaceName, int action, RouteInfo route) {
+    public void addSecondaryRoute(String interfaceName, RouteInfo route) {
+        mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG);
+        modifyRoute(interfaceName, ADD, route, SECONDARY);
+    }
+
+    public void removeSecondaryRoute(String interfaceName, RouteInfo route) {
+        mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG);
+        modifyRoute(interfaceName, REMOVE, route, SECONDARY);
+    }
+
+    private void modifyRoute(String interfaceName, int action, RouteInfo route, String type) {
         ArrayList<String> rsp;
 
         StringBuilder cmd;
@@ -521,12 +538,12 @@
         switch (action) {
             case ADD:
             {
-                cmd = new StringBuilder("interface route add " + interfaceName);
+                cmd = new StringBuilder("interface route add " + interfaceName + " " + type);
                 break;
             }
             case REMOVE:
             {
-                cmd = new StringBuilder("interface route remove " + interfaceName);
+                cmd = new StringBuilder("interface route remove " + interfaceName + " " + type);
                 break;
             }
             default:
@@ -833,14 +850,33 @@
         }
     }
 
+    private void modifyNat(String cmd, String internalInterface, String externalInterface)
+            throws SocketException {
+        cmd = String.format("nat %s %s %s", cmd, internalInterface, externalInterface);
+
+        NetworkInterface internalNetworkInterface =
+                NetworkInterface.getByName(internalInterface);
+        Collection<InterfaceAddress>interfaceAddresses =
+                internalNetworkInterface.getInterfaceAddresses();
+        cmd += " " + interfaceAddresses.size();
+        for (InterfaceAddress ia : interfaceAddresses) {
+            InetAddress addr = NetworkUtils.getNetworkPart(ia.getAddress(),
+                    ia.getNetworkPrefixLength());
+            cmd = cmd + " " + addr.getHostAddress() + "/" + ia.getNetworkPrefixLength();
+        }
+
+        mConnector.doCommand(cmd);
+    }
+
     public void enableNat(String internalInterface, String externalInterface)
             throws IllegalStateException {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
+        if (DBG) Log.d(TAG, "enableNat(" + internalInterface + ", " + externalInterface + ")");
         try {
-            mConnector.doCommand(
-                    String.format("nat enable %s %s", internalInterface, externalInterface));
-        } catch (NativeDaemonConnectorException e) {
+            modifyNat("enable", internalInterface, externalInterface);
+        } catch (Exception e) {
+            Log.e(TAG, "enableNat got Exception " + e.toString());
             throw new IllegalStateException(
                     "Unable to communicate to native daemon for enabling NAT interface");
         }
@@ -850,10 +886,11 @@
             throws IllegalStateException {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
+        if (DBG) Log.d(TAG, "disableNat(" + internalInterface + ", " + externalInterface + ")");
         try {
-            mConnector.doCommand(
-                    String.format("nat disable %s %s", internalInterface, externalInterface));
-        } catch (NativeDaemonConnectorException e) {
+            modifyNat("disable", internalInterface, externalInterface);
+        } catch (Exception e) {
+            Log.e(TAG, "disableNat got Exception " + e.toString());
             throw new IllegalStateException(
                     "Unable to communicate to native daemon for disabling NAT interface");
         }
diff --git a/services/java/com/android/server/UiModeManagerService.java b/services/java/com/android/server/UiModeManagerService.java
index 431cc39..280b329 100644
--- a/services/java/com/android/server/UiModeManagerService.java
+++ b/services/java/com/android/server/UiModeManagerService.java
@@ -123,6 +123,10 @@
         @Override
         public void onReceive(Context context, Intent intent) {
             if (getResultCode() != Activity.RESULT_OK) {
+                if (LOG) {
+                    Slog.v(TAG, "Handling broadcast result for action " + intent.getAction() 
+                            + ": canceled: " + getResultCode());
+                }
                 return;
             }
 
@@ -151,6 +155,12 @@
                         category = Intent.CATEGORY_HOME;
                     }
                 }
+
+                if (LOG) {
+                    Slog.v(TAG, String.format(
+                        "Handling broadcast result for action %s: enable=0x%08x disable=0x%08x category=%s", 
+                        intent.getAction(), enableFlags, disableFlags, category));
+                }
                 
                 if (category != null) {
                     // This is the new activity that will serve as home while
@@ -424,11 +434,22 @@
         }
     }
 
+    final static boolean isDeskDockState(int state) {
+        switch (state) {
+            case Intent.EXTRA_DOCK_STATE_DESK:
+            case Intent.EXTRA_DOCK_STATE_LE_DESK:
+            case Intent.EXTRA_DOCK_STATE_HE_DESK:
+                return true;
+            default:
+                return false;
+        }
+    }
+
     final void updateConfigurationLocked(boolean sendIt) {
         int uiMode = Configuration.UI_MODE_TYPE_NORMAL;
         if (mCarModeEnabled) {
             uiMode = Configuration.UI_MODE_TYPE_CAR;
-        } else if (mDockState == Intent.EXTRA_DOCK_STATE_DESK) {
+        } else if (isDeskDockState(mDockState)) {
             uiMode = Configuration.UI_MODE_TYPE_DESK;
         }
         if (mCarModeEnabled) {
@@ -477,7 +498,7 @@
             if (mLastBroadcastState == Intent.EXTRA_DOCK_STATE_CAR) {
                 adjustStatusBarCarModeLocked();
                 oldAction = UiModeManager.ACTION_EXIT_CAR_MODE;
-            } else if (mLastBroadcastState == Intent.EXTRA_DOCK_STATE_DESK) {
+            } else if (isDeskDockState(mLastBroadcastState)) {
                 oldAction = UiModeManager.ACTION_EXIT_DESK_MODE;
             }
 
@@ -491,12 +512,12 @@
                     mLastBroadcastState = Intent.EXTRA_DOCK_STATE_CAR;
                     action = UiModeManager.ACTION_ENTER_CAR_MODE;
                 }
-            } else if (mDockState == Intent.EXTRA_DOCK_STATE_DESK) {
-                if (mLastBroadcastState != Intent.EXTRA_DOCK_STATE_DESK) {
+            } else if (isDeskDockState(mDockState)) {
+                if (!isDeskDockState(mLastBroadcastState)) {
                     if (oldAction != null) {
                         mContext.sendBroadcast(new Intent(oldAction));
                     }
-                    mLastBroadcastState = Intent.EXTRA_DOCK_STATE_DESK;
+                    mLastBroadcastState = mDockState;
                     action = UiModeManager.ACTION_ENTER_DESK_MODE;
                 }
             } else {
@@ -505,6 +526,12 @@
             }
 
             if (action != null) {
+                if (LOG) {
+                    Slog.v(TAG, String.format(
+                        "updateLocked: preparing broadcast: action=%s enable=0x%08x disable=0x%08x",
+                        action, enableFlags, disableFlags));
+                }
+
                 // Send the ordered broadcast; the result receiver will receive after all
                 // broadcasts have been sent. If any broadcast receiver changes the result
                 // code from the initial value of RESULT_OK, then the result receiver will
@@ -526,7 +553,7 @@
                     if ((enableFlags&UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
                         homeIntent = buildHomeIntent(Intent.CATEGORY_CAR_DOCK);
                     }
-                } else if (mDockState == Intent.EXTRA_DOCK_STATE_DESK) {
+                } else if (isDeskDockState(mDockState)) {
                     if ((enableFlags&UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
                         homeIntent = buildHomeIntent(Intent.CATEGORY_DESK_DOCK);
                     }
@@ -535,6 +562,12 @@
                         homeIntent = buildHomeIntent(Intent.CATEGORY_HOME);
                     }
                 }
+
+                if (LOG) {
+                    Slog.v(TAG, "updateLocked: null action, mDockState="
+                            + mDockState +", firing homeIntent: " + homeIntent);
+                }
+
                 if (homeIntent != null) {
                     try {
                         mContext.startActivity(homeIntent);
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 0c42926..4fe8119 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -120,6 +120,7 @@
 
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.File;
@@ -128,8 +129,10 @@
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.PrintWriter;
+import java.io.StringWriter;
 import java.lang.IllegalStateException;
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
@@ -857,9 +860,11 @@
     static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
     static final int DISPATCH_FOREGROUND_ACTIVITIES_CHANGED = 31;
     static final int DISPATCH_PROCESS_DIED = 32;
+    static final int REPORT_MEM_USAGE = 33;
 
     AlertDialog mUidAlert;
     CompatModeDialog mCompatModeDialog;
+    long mLastMemUsageReportTime = 0;
 
     final Handler mHandler = new Handler() {
         //public Handler() {
@@ -1199,6 +1204,56 @@
                 dispatchProcessDied(pid, uid);
                 break;
             }
+            case REPORT_MEM_USAGE: {
+                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
+                if (!isDebuggable) {
+                    return;
+                }
+                synchronized (ActivityManagerService.this) {
+                    long now = SystemClock.uptimeMillis();
+                    if (now < (mLastMemUsageReportTime+10000)) {
+                        // Don't report more than every 10 seconds to somewhat
+                        // avoid spamming.
+                        return;
+                    }
+                    mLastMemUsageReportTime = now;
+                }
+                Thread thread = new Thread() {
+                    @Override public void run() {
+                        try {
+                            java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
+                                    "procrank", });
+                            final InputStreamReader converter = new InputStreamReader(
+                                    proc.getInputStream());
+                            BufferedReader in = new BufferedReader(converter);
+                            String line;
+                            while (true) {
+                                line = in.readLine();
+                                if (line == null) {
+                                    break;
+                                }
+                                if (line.length() > 0) {
+                                    Slog.i(TAG, line);
+                                }
+                            }
+                            converter.close();
+                        } catch (IOException e) {
+                        }
+                        StringWriter sw = new StringWriter();
+                        PrintWriter pw = new PrintWriter(sw);
+                        dumpApplicationMemoryUsage(null, pw, "  ", new String[] { }, true);
+                        Slog.i(TAG, sw.toString());
+                        synchronized (ActivityManagerService.this) {
+                            long now = SystemClock.uptimeMillis();
+                            if (mLastMemUsageReportTime < now) {
+                                mLastMemUsageReportTime = now;
+                            }
+                        }
+                    }
+                };
+                thread.start();
+                break;
+            }
             }
         }
     };
@@ -1339,7 +1394,7 @@
                 return;
             }
 
-            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args);
+            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false);
         }
     }
 
@@ -2768,6 +2823,7 @@
                             addProcessToGcListLocked(rec);
                         }
                     }
+                    mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
                     scheduleAppGcsLocked();
                 }
             }
@@ -9242,7 +9298,7 @@
     }
 
     final void dumpApplicationMemoryUsage(FileDescriptor fd,
-            PrintWriter pw, String prefix, String[] args) {
+            PrintWriter pw, String prefix, String[] args, boolean brief) {
         boolean dumpAll = false;
         
         int opti = 0;
@@ -9382,15 +9438,19 @@
                 }
             }
 
-            pw.println();
-            pw.println("Total PSS by process:");
-            dumpMemItems(pw, "  ", procMems, true);
-            pw.println();
+            if (!brief) {
+                pw.println();
+                pw.println("Total PSS by process:");
+                dumpMemItems(pw, "  ", procMems, true);
+                pw.println();
+            }
             pw.println("Total PSS by OOM adjustment:");
             dumpMemItems(pw, "  ", oomMems, false);
-            pw.println();
-            pw.println("Total PSS by category:");
-            dumpMemItems(pw, "  ", catMems, true);
+            if (!brief) {
+                pw.println();
+                pw.println("Total PSS by category:");
+                dumpMemItems(pw, "  ", catMems, true);
+            }
             pw.println();
             pw.print("Total PSS: "); pw.print(totalPss); pw.println(" Kb");
         }
diff --git a/services/java/com/android/server/connectivity/Tethering.java b/services/java/com/android/server/connectivity/Tethering.java
index 7bd29d9..423a78f 100644
--- a/services/java/com/android/server/connectivity/Tethering.java
+++ b/services/java/com/android/server/connectivity/Tethering.java
@@ -81,6 +81,9 @@
     private String[] mTetherableBluetoothRegexs;
     private Collection<Integer> mUpstreamIfaceTypes;
 
+    // used to synchronize public access to members
+    private Object mPublicSync;
+
     private static final Integer MOBILE_TYPE = new Integer(ConnectivityManager.TYPE_MOBILE);
     private static final Integer HIPRI_TYPE = new Integer(ConnectivityManager.TYPE_MOBILE_HIPRI);
     private static final Integer DUN_TYPE = new Integer(ConnectivityManager.TYPE_MOBILE_DUN);
@@ -91,6 +94,7 @@
 
     private final INetworkManagementService mNMService;
     private final INetworkStatsService mStatsService;
+    private final IConnectivityManager mConnService;
     private Looper mLooper;
     private HandlerThread mThread;
 
@@ -127,12 +131,15 @@
                                          // when RNDIS is enabled
 
     public Tethering(Context context, INetworkManagementService nmService,
-            INetworkStatsService statsService, Looper looper) {
+            INetworkStatsService statsService, IConnectivityManager connService, Looper looper) {
         mContext = context;
         mNMService = nmService;
         mStatsService = statsService;
+        mConnService = connService;
         mLooper = looper;
 
+        mPublicSync = new Object();
+
         mIfaces = new HashMap<String, TetherInterfaceSM>();
 
         // make our own thread so we don't anr the system
@@ -170,18 +177,25 @@
     }
 
     void updateConfiguration() {
-        mTetherableUsbRegexs = mContext.getResources().getStringArray(
+        String[] tetherableUsbRegexs = mContext.getResources().getStringArray(
                 com.android.internal.R.array.config_tether_usb_regexs);
-        mTetherableWifiRegexs = mContext.getResources().getStringArray(
+        String[] tetherableWifiRegexs = mContext.getResources().getStringArray(
                 com.android.internal.R.array.config_tether_wifi_regexs);
-        mTetherableBluetoothRegexs = mContext.getResources().getStringArray(
+        String[] tetherableBluetoothRegexs = mContext.getResources().getStringArray(
                 com.android.internal.R.array.config_tether_bluetooth_regexs);
 
         int ifaceTypes[] = mContext.getResources().getIntArray(
                 com.android.internal.R.array.config_tether_upstream_types);
-        mUpstreamIfaceTypes = new ArrayList();
+        Collection<Integer> upstreamIfaceTypes = new ArrayList();
         for (int i : ifaceTypes) {
-            mUpstreamIfaceTypes.add(new Integer(i));
+            upstreamIfaceTypes.add(new Integer(i));
+        }
+
+        synchronized (mPublicSync) {
+            mTetherableUsbRegexs = tetherableUsbRegexs;
+            mTetherableWifiRegexs = tetherableWifiRegexs;
+            mTetherableBluetoothRegexs = tetherableBluetoothRegexs;
+            mUpstreamIfaceTypes = upstreamIfaceTypes;
         }
 
         // check if the upstream type list needs to be modified due to secure-settings
@@ -192,17 +206,17 @@
         if (VDBG) Log.d(TAG, "interfaceStatusChanged " + iface + ", " + up);
         boolean found = false;
         boolean usb = false;
-        if (isWifi(iface)) {
-            found = true;
-        } else if (isUsb(iface)) {
-            found = true;
-            usb = true;
-        } else if (isBluetooth(iface)) {
-            found = true;
-        }
-        if (found == false) return;
+        synchronized (mPublicSync) {
+            if (isWifi(iface)) {
+                found = true;
+            } else if (isUsb(iface)) {
+                found = true;
+                usb = true;
+            } else if (isBluetooth(iface)) {
+                found = true;
+            }
+            if (found == false) return;
 
-        synchronized (mIfaces) {
             TetherInterfaceSM sm = mIfaces.get(iface);
             if (up) {
                 if (sm == null) {
@@ -229,46 +243,52 @@
     }
 
     private boolean isUsb(String iface) {
-        for (String regex : mTetherableUsbRegexs) {
-            if (iface.matches(regex)) return true;
+        synchronized (mPublicSync) {
+            for (String regex : mTetherableUsbRegexs) {
+                if (iface.matches(regex)) return true;
+            }
+            return false;
         }
-        return false;
     }
 
     public boolean isWifi(String iface) {
-        for (String regex : mTetherableWifiRegexs) {
-            if (iface.matches(regex)) return true;
+        synchronized (mPublicSync) {
+            for (String regex : mTetherableWifiRegexs) {
+                if (iface.matches(regex)) return true;
+            }
+            return false;
         }
-        return false;
     }
 
     public boolean isBluetooth(String iface) {
-        for (String regex : mTetherableBluetoothRegexs) {
-            if (iface.matches(regex)) return true;
+        synchronized (mPublicSync) {
+            for (String regex : mTetherableBluetoothRegexs) {
+                if (iface.matches(regex)) return true;
+            }
+            return false;
         }
-        return false;
     }
 
     public void interfaceAdded(String iface) {
         if (VDBG) Log.d(TAG, "interfaceAdded " + iface);
         boolean found = false;
         boolean usb = false;
-        if (isWifi(iface)) {
-            found = true;
-        }
-        if (isUsb(iface)) {
-            found = true;
-            usb = true;
-        }
-        if (isBluetooth(iface)) {
-            found = true;
-        }
-        if (found == false) {
-            if (VDBG) Log.d(TAG, iface + " is not a tetherable iface, ignoring");
-            return;
-        }
+        synchronized (mPublicSync) {
+            if (isWifi(iface)) {
+                found = true;
+            }
+            if (isUsb(iface)) {
+                found = true;
+                usb = true;
+            }
+            if (isBluetooth(iface)) {
+                found = true;
+            }
+            if (found == false) {
+                if (VDBG) Log.d(TAG, iface + " is not a tetherable iface, ignoring");
+                return;
+            }
 
-        synchronized (mIfaces) {
             TetherInterfaceSM sm = mIfaces.get(iface);
             if (sm != null) {
                 if (VDBG) Log.d(TAG, "active iface (" + iface + ") reported as added, ignoring");
@@ -283,7 +303,7 @@
 
     public void interfaceRemoved(String iface) {
         if (VDBG) Log.d(TAG, "interfaceRemoved " + iface);
-        synchronized (mIfaces) {
+        synchronized (mPublicSync) {
             TetherInterfaceSM sm = mIfaces.get(iface);
             if (sm == null) {
                 if (VDBG) {
@@ -301,7 +321,7 @@
     public int tether(String iface) {
         if (DBG) Log.d(TAG, "Tethering " + iface);
         TetherInterfaceSM sm = null;
-        synchronized (mIfaces) {
+        synchronized (mPublicSync) {
             sm = mIfaces.get(iface);
         }
         if (sm == null) {
@@ -319,7 +339,7 @@
     public int untether(String iface) {
         if (DBG) Log.d(TAG, "Untethering " + iface);
         TetherInterfaceSM sm = null;
-        synchronized (mIfaces) {
+        synchronized (mPublicSync) {
             sm = mIfaces.get(iface);
         }
         if (sm == null) {
@@ -336,21 +356,22 @@
 
     public int getLastTetherError(String iface) {
         TetherInterfaceSM sm = null;
-        synchronized (mIfaces) {
+        synchronized (mPublicSync) {
             sm = mIfaces.get(iface);
+            if (sm == null) {
+                Log.e(TAG, "Tried to getLastTetherError on an unknown iface :" + iface +
+                        ", ignoring");
+                return ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE;
+            }
+            return sm.getLastError();
         }
-        if (sm == null) {
-            Log.e(TAG, "Tried to getLastTetherError on an unknown iface :" + iface + ", ignoring");
-            return ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE;
-        }
-        return sm.getLastError();
     }
 
+    // TODO - move all private methods used only by the state machine into the state machine
+    // to clarify what needs synchronized protection.
     private void sendTetherStateChangedBroadcast() {
-        IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
-        IConnectivityManager cm = IConnectivityManager.Stub.asInterface(b);
         try {
-            if (!cm.isTetheringSupported()) return;
+            if (!mConnService.isTetheringSupported()) return;
         } catch (RemoteException e) {
             return;
         }
@@ -363,7 +384,7 @@
         boolean usbTethered = false;
         boolean bluetoothTethered = false;
 
-        synchronized (mIfaces) {
+        synchronized (mPublicSync) {
             Set ifaces = mIfaces.keySet();
             for (Object iface : ifaces) {
                 TetherInterfaceSM sm = mIfaces.get(iface);
@@ -469,7 +490,7 @@
         public void onReceive(Context content, Intent intent) {
             String action = intent.getAction();
             if (action.equals(UsbManager.ACTION_USB_STATE)) {
-                synchronized (Tethering.this) {
+                synchronized (Tethering.this.mPublicSync) {
                     boolean usbConnected = intent.getBooleanExtra(UsbManager.USB_CONNECTED, false);
                     mRndisEnabled = intent.getBooleanExtra(UsbManager.USB_FUNCTION_RNDIS, false);
                     // start tethering if we have a request pending
@@ -545,6 +566,7 @@
         return true;
     }
 
+    // TODO - return copies so people can't tamper
     public String[] getTetherableUsbRegexs() {
         return mTetherableUsbRegexs;
     }
@@ -561,7 +583,7 @@
         if (VDBG) Log.d(TAG, "setUsbTethering(" + enable + ")");
         UsbManager usbManager = (UsbManager)mContext.getSystemService(Context.USB_SERVICE);
 
-        synchronized (this) {
+        synchronized (mPublicSync) {
             if (enable) {
                 if (mRndisEnabled) {
                     tetherUsb(true);
@@ -581,11 +603,14 @@
     }
 
     public int[] getUpstreamIfaceTypes() {
-        updateConfiguration();
-        int values[] = new int[mUpstreamIfaceTypes.size()];
-        Iterator<Integer> iterator = mUpstreamIfaceTypes.iterator();
-        for (int i=0; i < mUpstreamIfaceTypes.size(); i++) {
-            values[i] = iterator.next();
+        int values[];
+        synchronized (mPublicSync) {
+            updateConfiguration();
+            values = new int[mUpstreamIfaceTypes.size()];
+            Iterator<Integer> iterator = mUpstreamIfaceTypes.iterator();
+            for (int i=0; i < mUpstreamIfaceTypes.size(); i++) {
+                values[i] = iterator.next();
+            }
         }
         return values;
     }
@@ -593,43 +618,46 @@
     public void checkDunRequired() {
         int secureSetting = Settings.Secure.getInt(mContext.getContentResolver(),
                 Settings.Secure.TETHER_DUN_REQUIRED, 2);
-        // 2 = not set, 0 = DUN not required, 1 = DUN required
-        if (secureSetting != 2) {
-            int requiredApn = (secureSetting == 1 ?
-                    ConnectivityManager.TYPE_MOBILE_DUN :
-                    ConnectivityManager.TYPE_MOBILE_HIPRI);
-            if (requiredApn == ConnectivityManager.TYPE_MOBILE_DUN) {
-                while (mUpstreamIfaceTypes.contains(MOBILE_TYPE)) {
-                    mUpstreamIfaceTypes.remove(MOBILE_TYPE);
-                }
-                while (mUpstreamIfaceTypes.contains(HIPRI_TYPE)) {
-                    mUpstreamIfaceTypes.remove(HIPRI_TYPE);
-                }
-                if (mUpstreamIfaceTypes.contains(DUN_TYPE) == false) {
-                    mUpstreamIfaceTypes.add(DUN_TYPE);
-                }
-            } else {
-                while (mUpstreamIfaceTypes.contains(DUN_TYPE)) {
-                    mUpstreamIfaceTypes.remove(DUN_TYPE);
-                }
-                if (mUpstreamIfaceTypes.contains(MOBILE_TYPE) == false) {
-                    mUpstreamIfaceTypes.add(MOBILE_TYPE);
-                }
-                if (mUpstreamIfaceTypes.contains(HIPRI_TYPE) == false) {
-                    mUpstreamIfaceTypes.add(HIPRI_TYPE);
+        synchronized (mPublicSync) {
+            // 2 = not set, 0 = DUN not required, 1 = DUN required
+            if (secureSetting != 2) {
+                int requiredApn = (secureSetting == 1 ?
+                        ConnectivityManager.TYPE_MOBILE_DUN :
+                        ConnectivityManager.TYPE_MOBILE_HIPRI);
+                if (requiredApn == ConnectivityManager.TYPE_MOBILE_DUN) {
+                    while (mUpstreamIfaceTypes.contains(MOBILE_TYPE)) {
+                        mUpstreamIfaceTypes.remove(MOBILE_TYPE);
+                    }
+                    while (mUpstreamIfaceTypes.contains(HIPRI_TYPE)) {
+                        mUpstreamIfaceTypes.remove(HIPRI_TYPE);
+                    }
+                    if (mUpstreamIfaceTypes.contains(DUN_TYPE) == false) {
+                        mUpstreamIfaceTypes.add(DUN_TYPE);
+                    }
+                } else {
+                    while (mUpstreamIfaceTypes.contains(DUN_TYPE)) {
+                        mUpstreamIfaceTypes.remove(DUN_TYPE);
+                    }
+                    if (mUpstreamIfaceTypes.contains(MOBILE_TYPE) == false) {
+                        mUpstreamIfaceTypes.add(MOBILE_TYPE);
+                    }
+                    if (mUpstreamIfaceTypes.contains(HIPRI_TYPE) == false) {
+                        mUpstreamIfaceTypes.add(HIPRI_TYPE);
+                    }
                 }
             }
-        }
-        if (mUpstreamIfaceTypes.contains(DUN_TYPE)) {
-            mPreferredUpstreamMobileApn = ConnectivityManager.TYPE_MOBILE_DUN;
-        } else {
-            mPreferredUpstreamMobileApn = ConnectivityManager.TYPE_MOBILE_HIPRI;
+            if (mUpstreamIfaceTypes.contains(DUN_TYPE)) {
+                mPreferredUpstreamMobileApn = ConnectivityManager.TYPE_MOBILE_DUN;
+            } else {
+                mPreferredUpstreamMobileApn = ConnectivityManager.TYPE_MOBILE_HIPRI;
+            }
         }
     }
 
+    // TODO review API - maybe return ArrayList<String> here and below?
     public String[] getTetheredIfaces() {
         ArrayList<String> list = new ArrayList<String>();
-        synchronized (mIfaces) {
+        synchronized (mPublicSync) {
             Set keys = mIfaces.keySet();
             for (Object key : keys) {
                 TetherInterfaceSM sm = mIfaces.get(key);
@@ -647,7 +675,7 @@
 
     public String[] getTetheredIfacePairs() {
         final ArrayList<String> list = Lists.newArrayList();
-        synchronized (mIfaces) {
+        synchronized (mPublicSync) {
             for (TetherInterfaceSM sm : mIfaces.values()) {
                 if (sm.isTethered()) {
                     list.add(sm.mMyUpstreamIfaceName);
@@ -660,7 +688,7 @@
 
     public String[] getTetherableIfaces() {
         ArrayList<String> list = new ArrayList<String>();
-        synchronized (mIfaces) {
+        synchronized (mPublicSync) {
             Set keys = mIfaces.keySet();
             for (Object key : keys) {
                 TetherInterfaceSM sm = mIfaces.get(key);
@@ -678,7 +706,7 @@
 
     public String[] getErroredIfaces() {
         ArrayList<String> list = new ArrayList<String>();
-        synchronized (mIfaces) {
+        synchronized (mPublicSync) {
             Set keys = mIfaces.keySet();
             for (Object key : keys) {
                 TetherInterfaceSM sm = mIfaces.get(key);
@@ -777,43 +805,54 @@
             return res;
         }
 
-        public synchronized int getLastError() {
-            return mLastError;
+        public int getLastError() {
+            synchronized (Tethering.this.mPublicSync) {
+                return mLastError;
+            }
         }
 
-        private synchronized void setLastError(int error) {
-            mLastError = error;
+        private void setLastError(int error) {
+            synchronized (Tethering.this.mPublicSync) {
+                mLastError = error;
 
-            if (isErrored()) {
-                if (mUsb) {
-                    // note everything's been unwound by this point so nothing to do on
-                    // further error..
-                    Tethering.this.configureUsbIface(false);
+                if (isErrored()) {
+                    if (mUsb) {
+                        // note everything's been unwound by this point so nothing to do on
+                        // further error..
+                        Tethering.this.configureUsbIface(false);
+                    }
                 }
             }
         }
 
-        // synchronized between this getter and the following setter
-        public synchronized boolean isAvailable() {
-            return mAvailable;
+        public boolean isAvailable() {
+            synchronized (Tethering.this.mPublicSync) {
+                return mAvailable;
+            }
         }
 
-        private synchronized void setAvailable(boolean available) {
-            mAvailable = available;
+        private void setAvailable(boolean available) {
+            synchronized (Tethering.this.mPublicSync) {
+                mAvailable = available;
+            }
         }
 
-        // synchronized between this getter and the following setter
-        public synchronized boolean isTethered() {
-            return mTethered;
+        public boolean isTethered() {
+            synchronized (Tethering.this.mPublicSync) {
+                return mTethered;
+            }
         }
 
-        private synchronized void setTethered(boolean tethered) {
-            mTethered = tethered;
+        private void setTethered(boolean tethered) {
+            synchronized (Tethering.this.mPublicSync) {
+                mTethered = tethered;
+            }
         }
 
-        // synchronized between this getter and the following setter
-        public synchronized boolean isErrored() {
-            return (mLastError != ConnectivityManager.TETHER_ERROR_NO_ERROR);
+        public boolean isErrored() {
+            synchronized (Tethering.this.mPublicSync) {
+                return (mLastError != ConnectivityManager.TETHER_ERROR_NO_ERROR);
+            }
         }
 
         class InitialState extends State {
@@ -910,6 +949,7 @@
                 try {
                     mNMService.tetherInterface(mIfaceName);
                 } catch (Exception e) {
+                    Log.e(TAG, "Error Tethering: " + e.toString());
                     setLastError(ConnectivityManager.TETHER_ERROR_TETHER_IFACE_ERROR);
 
                     transitionTo(mInitialState);
@@ -921,7 +961,7 @@
                 sendTetherStateChangedBroadcast();
             }
 
-            void cleanupUpstream() {
+            private void cleanupUpstream() {
                 if (mMyUpstreamIfaceName != null) {
                     // note that we don't care about errors here.
                     // sometimes interfaces are gone before we get
@@ -987,6 +1027,7 @@
                             try {
                                 mNMService.enableNat(mIfaceName, newUpstreamIfaceName);
                             } catch (Exception e) {
+                                Log.e(TAG, "Exception enabling Nat: " + e.toString());
                                 try {
                                     mNMService.untetherInterface(mIfaceName);
                                 } catch (Exception ee) {}
@@ -1150,13 +1191,11 @@
                 boolean retValue = true;
                 if (apnType == ConnectivityManager.TYPE_NONE) return false;
                 if (apnType != mMobileApnReserved) turnOffUpstreamMobileConnection();
-                IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
-                IConnectivityManager cm = IConnectivityManager.Stub.asInterface(b);
                 int result = Phone.APN_REQUEST_FAILED;
                 String enableString = enableString(apnType);
                 if (enableString == null) return false;
                 try {
-                    result = cm.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
+                    result = mConnService.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
                             enableString, new Binder());
                 } catch (Exception e) {
                 }
@@ -1178,10 +1217,8 @@
             }
             protected boolean turnOffUpstreamMobileConnection() {
                 if (mMobileApnReserved != ConnectivityManager.TYPE_NONE) {
-                    IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
-                    IConnectivityManager cm = IConnectivityManager.Stub.asInterface(b);
                     try {
-                        cm.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
+                        mConnService.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
                                 enableString(mMobileApnReserved));
                     } catch (Exception e) {
                         return false;
@@ -1234,28 +1271,28 @@
             }
 
             protected void chooseUpstreamType(boolean tryCell) {
-                IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
-                IConnectivityManager cm = IConnectivityManager.Stub.asInterface(b);
                 int upType = ConnectivityManager.TYPE_NONE;
                 String iface = null;
 
                 updateConfiguration();
 
-                if (VDBG) {
-                    Log.d(TAG, "chooseUpstreamType has upstream iface types:");
-                    for (Integer netType : mUpstreamIfaceTypes) {
-                        Log.d(TAG, " " + netType);
+                synchronized (mPublicSync) {
+                    if (VDBG) {
+                        Log.d(TAG, "chooseUpstreamType has upstream iface types:");
+                        for (Integer netType : mUpstreamIfaceTypes) {
+                            Log.d(TAG, " " + netType);
+                        }
                     }
-                }
 
-                for (Integer netType : mUpstreamIfaceTypes) {
-                    NetworkInfo info = null;
-                    try {
-                        info = cm.getNetworkInfo(netType.intValue());
-                    } catch (RemoteException e) { }
-                    if ((info != null) && info.isConnected()) {
-                        upType = netType.intValue();
-                        break;
+                    for (Integer netType : mUpstreamIfaceTypes) {
+                        NetworkInfo info = null;
+                        try {
+                            info = mConnService.getNetworkInfo(netType.intValue());
+                        } catch (RemoteException e) { }
+                        if ((info != null) && info.isConnected()) {
+                            upType = netType.intValue();
+                            break;
+                        }
                     }
                 }
 
@@ -1283,7 +1320,7 @@
                 } else {
                     LinkProperties linkProperties = null;
                     try {
-                        linkProperties = cm.getLinkProperties(upType);
+                        linkProperties = mConnService.getLinkProperties(upType);
                     } catch (RemoteException e) { }
                     if (linkProperties != null) iface = linkProperties.getInterfaceName();
                 }
@@ -1483,14 +1520,14 @@
                     return;
         }
 
-        pw.println("mUpstreamIfaceTypes: ");
-        for (Integer netType : mUpstreamIfaceTypes) {
-            pw.println(" " + netType);
-        }
+        synchronized (mPublicSync) {
+            pw.println("mUpstreamIfaceTypes: ");
+            for (Integer netType : mUpstreamIfaceTypes) {
+                pw.println(" " + netType);
+            }
 
-        pw.println();
-        pw.println("Tether state:");
-        synchronized (mIfaces) {
+            pw.println();
+            pw.println("Tether state:");
             for (Object o : mIfaces.values()) {
                 pw.println(" "+o.toString());
             }
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 2cd3062..8ed7966 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -8682,7 +8682,8 @@
         if (needRelayout) {
             requestAnimationLocked(0);
         } else if (animating) {
-            requestAnimationLocked(currentTime+(1000/60)-SystemClock.uptimeMillis());
+            final int refreshTimeUs = (int)(1000 / mDisplay.getRefreshRate());
+            requestAnimationLocked(currentTime + refreshTimeUs - SystemClock.uptimeMillis());
         }
 
         // Finally update all input windows now that the window changes have stabilized.
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index 61a8358..b916bd7 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -30,6 +30,10 @@
 	LOCAL_CFLAGS += -DHAS_CONTEXT_PRIORITY -DNEVER_DEFAULT_TO_ASYNC_MODE
 endif
 
+ifneq (,$(findstring $(TARGET_DEVICE),tuna toro maguro))
+	LOCAL_CFLAGS += -DREFRESH_RATE=48
+endif
+
 
 LOCAL_SHARED_LIBRARIES := \
 	libcutils \
diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
index f4be168..329c052 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
+++ b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -141,6 +141,17 @@
     mDpiY = mNativeWindow->ydpi;
     mRefreshRate = fbDev->fps;
 
+
+/* FIXME: this is a temporary HACK until we are able to report the refresh rate
+ * properly from the HAL. The WindowManagerService now relies on this value.
+ */
+#ifndef REFRESH_RATE
+    mRefreshRate = fbDev->fps;
+#else
+    mRefreshRate = REFRESH_RATE;
+#warning "refresh rate set via makefile to REFRESH_RATE"
+#endif
+
     EGLint w, h, dummy;
     EGLint numConfigs=0;
     EGLSurface surface;
diff --git a/telephony/java/com/android/internal/telephony/CallManager.java b/telephony/java/com/android/internal/telephony/CallManager.java
index 171b371..3dd57ee 100644
--- a/telephony/java/com/android/internal/telephony/CallManager.java
+++ b/telephony/java/com/android/internal/telephony/CallManager.java
@@ -379,18 +379,19 @@
                 mode = AudioManager.MODE_RINGTONE;
                 break;
             case OFFHOOK:
-                Phone fgPhone = getFgPhone();
-                // While foreground call is in DIALING,
-                // ALERTING, ACTIVE and DISCONNECTING state
-                if (getActiveFgCallState() != Call.State.IDLE
-                        && getActiveFgCallState() != Call.State.DISCONNECTED) {
-                    if (fgPhone instanceof SipPhone) {
-                        // enable IN_COMMUNICATION audio mode for sipPhone
-                        mode = AudioManager.MODE_IN_COMMUNICATION;
-                    } else {
-                        // enable IN_CALL audio mode for telephony
-                        mode = AudioManager.MODE_IN_CALL;
-                    }
+                Phone offhookPhone = getFgPhone();
+                if (getActiveFgCallState() == Call.State.IDLE) {
+                    // There is no active Fg calls, the OFFHOOK state
+                    // is set by the Bg call. So set the phone to bgPhone.
+                    offhookPhone = getBgPhone();
+                }
+
+                if (offhookPhone instanceof SipPhone) {
+                    // enable IN_COMMUNICATION audio mode for sipPhone
+                    mode = AudioManager.MODE_IN_COMMUNICATION;
+                } else {
+                    // enable IN_CALL audio mode for telephony
+                    mode = AudioManager.MODE_IN_CALL;
                 }
                 break;
         }
diff --git a/tests/FrameworkPerf/AndroidManifest.xml b/tests/FrameworkPerf/AndroidManifest.xml
index aa663f3..e88f4fb 100644
--- a/tests/FrameworkPerf/AndroidManifest.xml
+++ b/tests/FrameworkPerf/AndroidManifest.xml
@@ -13,6 +13,10 @@
         </activity>
         <service android:name="SchedulerService">
         </service>
+        <service android:name="TestService" android:process=":test">
+        </service>
+        <service android:name="LocalTestService">
+        </service>
         <receiver android:name="Receiver" android:exported="true">
         </receiver>
     </application>
diff --git a/tests/FrameworkPerf/res/layout/main.xml b/tests/FrameworkPerf/res/layout/main.xml
index 62b1a7a..7812648 100644
--- a/tests/FrameworkPerf/res/layout/main.xml
+++ b/tests/FrameworkPerf/res/layout/main.xml
@@ -91,6 +91,11 @@
             android:layout_height="wrap_content"
             android:text="@string/stop"
             />
+        <CheckBox android:id="@+id/local"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="Local"
+            />
     </LinearLayout>
 
     <TextView android:id="@+id/log"
diff --git a/tests/FrameworkPerf/src/com/android/frameworkperf/FrameworkPerfActivity.java b/tests/FrameworkPerf/src/com/android/frameworkperf/FrameworkPerfActivity.java
index 3979902..22eb579 100644
--- a/tests/FrameworkPerf/src/com/android/frameworkperf/FrameworkPerfActivity.java
+++ b/tests/FrameworkPerf/src/com/android/frameworkperf/FrameworkPerfActivity.java
@@ -17,43 +17,28 @@
 package com.android.frameworkperf;
 
 import android.app.Activity;
-import android.content.Context;
+import android.content.ComponentName;
 import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.res.TypedArray;
-import android.content.res.XmlResourceParser;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
+import android.content.ServiceConnection;
 import android.os.Bundle;
-import android.os.FileUtils;
 import android.os.Handler;
-import android.os.Looper;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.Messenger;
 import android.os.PowerManager;
-import android.os.Process;
-import android.os.SystemClock;
-import android.util.AttributeSet;
-import android.util.DisplayMetrics;
+import android.os.RemoteException;
 import android.util.Log;
-import android.util.Xml;
-import android.view.LayoutInflater;
 import android.view.View;
 import android.view.WindowManager;
 import android.widget.AdapterView;
 import android.widget.ArrayAdapter;
 import android.widget.Button;
+import android.widget.CheckBox;
 import android.widget.Spinner;
 import android.widget.TextView;
 
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.RandomAccessFile;
 import java.util.ArrayList;
 
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
 /**
  * So you thought sync used up your battery life.
  */
@@ -61,147 +46,71 @@
         implements AdapterView.OnItemSelectedListener {
     static final String TAG = "Perf";
 
-    final Handler mHandler = new Handler();
-
     Spinner mFgSpinner;
     Spinner mBgSpinner;
     TextView mTestTime;
     Button mStartButton;
     Button mStopButton;
+    CheckBox mLocalCheckBox;
     TextView mLog;
     PowerManager.WakeLock mPartialWakeLock;
 
     long mMaxRunTime = 5000;
     boolean mStarted;
 
-    final TestRunner mRunner = new TestRunner();
-
-    final Op[] mOpPairs = new Op[] {
-            new MethodCallOp(), new NoOp(),
-            new MethodCallOp(), new CpuOp(),
-            new MethodCallOp(), new SchedulerOp(),
-            new MethodCallOp(), new GcOp(),
-            new MethodCallOp(), new CreateFileOp(),
-            new MethodCallOp(), new CreateWriteFileOp(),
-            new MethodCallOp(), new CreateWriteSyncFileOp(),
-            new MethodCallOp(), new WriteFileOp(),
-            new MethodCallOp(), new ReadFileOp(),
-            new SchedulerOp(), new SchedulerOp(),
-            new GcOp(), new NoOp(),
-            new IpcOp(), new NoOp(),
-            new IpcOp(), new CpuOp(),
-            new IpcOp(), new SchedulerOp(),
-            new IpcOp(), new GcOp(),
-            new IpcOp(), new CreateFileOp(),
-            new IpcOp(), new CreateWriteFileOp(),
-            new IpcOp(), new CreateWriteSyncFileOp(),
-            new IpcOp(), new WriteFileOp(),
-            new IpcOp(), new ReadFileOp(),
-            new CreateFileOp(), new NoOp(),
-            new CreateWriteFileOp(), new NoOp(),
-            new CreateWriteSyncFileOp(), new NoOp(),
-            new WriteFileOp(), new NoOp(),
-            new ReadFileOp(), new NoOp(),
-            new WriteFileOp(), new CreateWriteFileOp(),
-            new ReadFileOp(), new CreateWriteFileOp(),
-            new WriteFileOp(), new CreateWriteSyncFileOp(),
-            new ReadFileOp(), new CreateWriteSyncFileOp(),
-            new WriteFileOp(), new WriteFileOp(),
-            new WriteFileOp(), new ReadFileOp(),
-            new ReadFileOp(), new WriteFileOp(),
-            new ReadFileOp(), new ReadFileOp(),
-            new OpenXmlResOp(), new NoOp(),
-            new ReadXmlAttrsOp(), new NoOp(),
-            new ParseXmlResOp(), new NoOp(),
-            new ParseLargeXmlResOp(), new NoOp(),
-            new LayoutInflaterOp(), new NoOp(),
-            new LayoutInflaterLargeOp(), new NoOp(),
-            new LayoutInflaterViewOp(), new NoOp(),
-            new LayoutInflaterButtonOp(), new NoOp(),
-            new LayoutInflaterImageButtonOp(), new NoOp(),
-            new CreateBitmapOp(), new NoOp(),
-            new CreateRecycleBitmapOp(), new NoOp(),
-            new LoadSmallBitmapOp(), new NoOp(),
-            new LoadRecycleSmallBitmapOp(), new NoOp(),
-            new LoadLargeBitmapOp(), new NoOp(),
-            new LoadRecycleLargeBitmapOp(), new NoOp(),
-            new LoadSmallScaledBitmapOp(), new NoOp(),
-            new LoadLargeScaledBitmapOp(), new NoOp(),
-    };
-
-    final Op[] mAvailOps = new Op[] {
-            null,
-            new NoOp(),
-            new CpuOp(),
-            new SchedulerOp(),
-            new MethodCallOp(),
-            new IpcOp(),
-            new CreateFileOp(),
-            new CreateWriteFileOp(),
-            new CreateWriteSyncFileOp(),
-            new WriteFileOp(),
-            new ReadFileOp(),
-            new OpenXmlResOp(),
-            new ReadXmlAttrsOp(),
-            new ParseXmlResOp(),
-            new ParseLargeXmlResOp(),
-            new LayoutInflaterOp(),
-            new LayoutInflaterLargeOp(),
-            new LayoutInflaterViewOp(),
-            new LayoutInflaterButtonOp(),
-            new LayoutInflaterImageButtonOp(),
-            new CreateBitmapOp(),
-            new CreateRecycleBitmapOp(),
-            new LoadSmallBitmapOp(),
-            new LoadRecycleSmallBitmapOp(),
-            new LoadLargeBitmapOp(),
-            new LoadRecycleLargeBitmapOp(),
-            new LoadSmallScaledBitmapOp(),
-            new LoadLargeScaledBitmapOp(),
-    };
-
     final String[] mAvailOpLabels;
     final String[] mAvailOpDescriptions;
 
-    Op mFgTest;
-    Op mBgTest;
+    int mFgTestIndex = -1;
+    int mBgTestIndex = -1;
+    TestService.Op mFgTest;
+    TestService.Op mBgTest;
     int mCurOpIndex = 0;
-
-    class RunResult {
-        final String name;
-        final String fgLongName;
-        final String bgLongName;
-        final long fgTime;
-        final long fgOps;
-        final long bgTime;
-        final long bgOps;
-
-        RunResult(TestRunner op) {
-            name = op.getName();
-            fgLongName = op.getForegroundLongName();
-            bgLongName = op.getBackgroundLongName();
-            fgTime = op.getForegroundTime();
-            fgOps = op.getForegroundOps();
-            bgTime = op.getBackgroundTime();
-            bgOps = op.getBackgroundOps();
-        }
-
-        float getFgMsPerOp() {
-            return fgOps != 0 ? (fgTime / (float)fgOps) : 0;
-        }
-
-        float getBgMsPerOp() {
-            return bgOps != 0 ? (bgTime / (float)bgOps) : 0;
-        }
-    }
+    TestConnection mCurConnection;
 
     final ArrayList<RunResult> mResults = new ArrayList<RunResult>();
 
+    class TestConnection implements ServiceConnection {
+        Messenger mService;
+
+        @Override public void onServiceConnected(ComponentName name, IBinder service) {
+            mService = new Messenger(service);
+            dispatchCurOp(this);
+        }
+
+        @Override public void onServiceDisconnected(ComponentName name) {
+        }
+    }
+
+    static final int MSG_CONTINUE = 1000;
+
+    final Handler mHandler = new Handler() {
+        @Override public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case TestService.RES_TEST_FINISHED: {
+                    Bundle bundle = (Bundle)msg.obj;
+                    bundle.setClassLoader(getClassLoader());
+                    RunResult res = (RunResult)bundle.getParcelable("res");
+                    completeCurOp(res);
+                } break;
+                case TestService.RES_TERMINATED: {
+                    // Give a little time for things to settle down.
+                    sendMessageDelayed(obtainMessage(MSG_CONTINUE), 500);
+                } break;
+                case MSG_CONTINUE: {
+                    startCurOp();
+                } break;
+            }
+        }
+    };
+
+    final Messenger mMessenger = new Messenger(mHandler);
+
     public FrameworkPerfActivity() {
-        mAvailOpLabels = new String[mAvailOps.length];
-        mAvailOpDescriptions = new String[mAvailOps.length];
-        for (int i=0; i<mAvailOps.length; i++) {
-            Op op = mAvailOps[i];
+        mAvailOpLabels = new String[TestService.mAvailOps.length];
+        mAvailOpDescriptions = new String[TestService.mAvailOps.length];
+        for (int i=0; i<TestService.mAvailOps.length; i++) {
+            TestService.Op op = TestService.mAvailOps[i];
             if (op == null) {
                 mAvailOpLabels[i] = "All";
                 mAvailOpDescriptions[i] = "All tests";
@@ -251,6 +160,7 @@
             }
         });
         mStopButton.setEnabled(false);
+        mLocalCheckBox = (CheckBox)findViewById(R.id.local);
 
         mLog = (TextView)findViewById(R.id.log);
 
@@ -262,11 +172,13 @@
     @Override
     public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
         if (parent == mFgSpinner || parent == mBgSpinner) {
-            Op op = mAvailOps[position];
+            TestService.Op op = TestService.mAvailOps[position];
             if (parent == mFgSpinner) {
+                mFgTestIndex = position;
                 mFgTest = op;
                 ((TextView)findViewById(R.id.fgtext)).setText(mAvailOpDescriptions[position]);
             } else {
+                mBgTestIndex = position;
                 mBgTest = op;
                 ((TextView)findViewById(R.id.bgtext)).setText(mAvailOpDescriptions[position]);
             }
@@ -291,64 +203,108 @@
         }
     }
 
-    void startCurOp() {
-        Op fgOp, bgOp;
-        if (mFgTest == null && mBgTest == null) {
-            fgOp = mOpPairs[mCurOpIndex];
-            bgOp = mOpPairs[mCurOpIndex+1];
-        } else if (mFgTest != null && mBgTest != null) {
-            fgOp = mFgTest;
-            bgOp = mBgTest;
-        } else if (mFgTest != null) {
-            // Skip null test.
-            if (mCurOpIndex == 0) {
-                mCurOpIndex = 1;
-            }
-            fgOp = mFgTest;
-            bgOp = mAvailOps[mCurOpIndex];
+    void dispatchCurOp(TestConnection conn) {
+        if (mCurConnection != conn) {
+            Log.w(TAG, "Dispatching on invalid connection: " + conn);
+            return;
+        }
+        TestArgs args = new TestArgs();
+        args.maxTime = mMaxRunTime;
+        if (mFgTestIndex == 0 && mBgTestIndex == 0) {
+            args.combOp = mCurOpIndex;
+        } else if (mFgTestIndex != 0 && mBgTestIndex != 0) {
+            args.fgOp = mFgTestIndex;
+            args.bgOp = mBgTestIndex;
         } else {
             // Skip null test.
             if (mCurOpIndex == 0) {
                 mCurOpIndex = 1;
             }
-            fgOp = mAvailOps[mCurOpIndex];
-            bgOp = mBgTest;
-        }
-        mRunner.run(mHandler, fgOp, bgOp, new Runnable() {
-            @Override public void run() {
-                RunResult result = new RunResult(mRunner);
-                log(String.format("%s: fg=%d*%gms/op (%dms) / bg=%d*%gms/op (%dms)",
-                        result.name, result.fgOps, result.getFgMsPerOp(), result.fgTime,
-                        result.bgOps, result.getBgMsPerOp(), result.bgTime));
-                mResults.add(result);
-                if (!mStarted) {
-                    log("Stop");
-                    stopRunning();
-                    return;
-                }
-                if (mFgTest != null && mBgTest != null) {
-                    log("Finished");
-                    stopRunning();
-                    return;
-                }
-                if (mFgTest == null && mBgTest == null) {
-                    mCurOpIndex+=2;
-                    if (mCurOpIndex >= mOpPairs.length) {
-                        log("Finished");
-                        stopRunning();
-                        return;
-                    }
-                } else {
-                    mCurOpIndex++;
-                    if (mCurOpIndex >= mAvailOps.length) {
-                        log("Finished");
-                        stopRunning();
-                        return;
-                    }
-                }
-                startCurOp();
+            if (mFgTestIndex != 0) {
+                args.fgOp = mFgTestIndex;
+                args.bgOp = mCurOpIndex;
+            } else {
+                args.fgOp = mCurOpIndex;
+                args.bgOp = mFgTestIndex;
             }
-        });
+        }
+        Bundle bundle = new Bundle();
+        bundle.putParcelable("args", args);
+        Message msg = Message.obtain(null, TestService.CMD_START_TEST, bundle);
+        msg.replyTo = mMessenger;
+        try {
+            conn.mService.send(msg);
+        } catch (RemoteException e) {
+            Log.i(TAG, "Failure communicating with service", e);
+        }
+    }
+
+    void completeCurOp(RunResult result) {
+        log(String.format("%s: fg=%d*%gms/op (%dms) / bg=%d*%gms/op (%dms)",
+                result.name, result.fgOps, result.getFgMsPerOp(), result.fgTime,
+                result.bgOps, result.getBgMsPerOp(), result.bgTime));
+        mResults.add(result);
+        if (!mStarted) {
+            log("Stop");
+            stopRunning();
+            return;
+        }
+        if (mFgTest != null && mBgTest != null) {
+            log("Finished");
+            stopRunning();
+            return;
+        }
+        if (mFgTest == null && mBgTest == null) {
+            mCurOpIndex+=2;
+            if (mCurOpIndex >= TestService.mOpPairs.length) {
+                log("Finished");
+                stopRunning();
+                return;
+            }
+        } else {
+            mCurOpIndex++;
+            if (mCurOpIndex >= TestService.mAvailOps.length) {
+                log("Finished");
+                stopRunning();
+                return;
+            }
+        }
+        startCurOp();
+    }
+
+    void disconnect() {
+        if (mCurConnection != null) {
+            unbindService(mCurConnection);
+            if (mCurConnection.mService != null) {
+                Message msg = Message.obtain(null, TestService.CMD_TERMINATE);
+                msg.replyTo = mMessenger;
+                try {
+                    mCurConnection.mService.send(msg);
+                } catch (RemoteException e) {
+                    Log.i(TAG, "Failure communicating with service", e);
+                }
+            }
+            mCurConnection = null;
+        }
+    }
+
+    void startCurOp() {
+        if (mCurConnection != null) {
+            disconnect();
+        }
+        if (mStarted) {
+            mHandler.removeMessages(TestService.RES_TEST_FINISHED);
+            mHandler.removeMessages(TestService.RES_TERMINATED);
+            mHandler.removeMessages(MSG_CONTINUE);
+            mCurConnection = new TestConnection();
+            Intent intent;
+            if (mLocalCheckBox.isChecked()) {
+                intent = new Intent(this, LocalTestService.class);
+            } else {
+                intent = new Intent(this, TestService.class);
+            }
+            bindService(intent, mCurConnection, BIND_AUTO_CREATE|BIND_IMPORTANT);
+        }
     }
 
     void startRunning() {
@@ -357,6 +313,7 @@
             mStarted = true;
             mStartButton.setEnabled(false);
             mStopButton.setEnabled(true);
+            mLocalCheckBox.setEnabled(false);
             mTestTime.setEnabled(false);
             mFgSpinner.setEnabled(false);
             mBgSpinner.setEnabled(false);
@@ -371,9 +328,11 @@
 
     void stopRunning() {
         if (mStarted) {
+            disconnect();
             mStarted = false;
             mStartButton.setEnabled(true);
             mStopButton.setEnabled(false);
+            mLocalCheckBox.setEnabled(true);
             mTestTime.setEnabled(true);
             mFgSpinner.setEnabled(true);
             mBgSpinner.setEnabled(true);
@@ -412,842 +371,4 @@
         mLog.setText(mLog.getText() + "\n" + s);
         Log.i(TAG, s);
     }
-
-    enum BackgroundMode {
-        NOTHING,
-        CPU,
-        SCHEDULER
-    };
-
-    public class TestRunner {
-        Handler mHandler;
-        Op mForegroundOp;
-        Op mBackgroundOp;
-        Runnable mDoneCallback;
-
-        RunnerThread mBackgroundThread;
-        RunnerThread mForegroundThread;
-        long mStartTime;
-
-        boolean mBackgroundRunning;
-        boolean mForegroundRunning;
-
-        long mBackgroundEndTime;
-        long mBackgroundOps;
-        long mForegroundEndTime;
-        long mForegroundOps;
-
-        public TestRunner() {
-        }
-
-        public String getForegroundName() {
-            return mForegroundOp.getName();
-        }
-
-        public String getBackgroundName() {
-            return mBackgroundOp.getName();
-        }
-
-        public String getName() {
-            String fgName = mForegroundOp.getName();
-            String bgName = mBackgroundOp.getName();
-            StringBuilder res = new StringBuilder();
-            if (fgName != null) {
-                res.append(fgName);
-                res.append("Fg");
-            }
-            if (bgName != null) {
-                res.append(bgName);
-                res.append("Bg");
-            }
-            return res.toString();
-        }
-
-        public String getForegroundLongName() {
-            return mForegroundOp.getLongName();
-        }
-
-        public String getBackgroundLongName() {
-            return mBackgroundOp.getLongName();
-        }
-
-        public void run(Handler handler, Op foreground, Op background, Runnable doneCallback) {
-            mHandler = handler;
-            mForegroundOp = foreground;
-            mBackgroundOp = background;
-            mDoneCallback = doneCallback;
-            mBackgroundThread = new RunnerThread("background", new Runnable() {
-                @Override public void run() {
-                    boolean running;
-                    int ops = 0;
-                    do {
-                        running = mBackgroundOp.onRun();
-                        ops++;
-                    } while (evalRepeat(running, true) && running);
-                    mBackgroundEndTime = SystemClock.uptimeMillis();
-                    mBackgroundOps = ops * mBackgroundOp.getOpsPerRun();
-                    threadFinished(false);
-                }
-            }, Process.THREAD_PRIORITY_BACKGROUND);
-            mForegroundThread = new RunnerThread("background", new Runnable() {
-                @Override public void run() {
-                    boolean running;
-                    int ops = 0;
-                    do {
-                        running = mForegroundOp.onRun();
-                        ops++;
-                    } while (evalRepeat(true, running) && running);
-                    mForegroundEndTime = SystemClock.uptimeMillis();
-                    mForegroundOps = ops * mForegroundOp.getOpsPerRun();
-                    threadFinished(true);
-                }
-            }, Process.THREAD_PRIORITY_FOREGROUND);
-
-            mForegroundOp.onInit(FrameworkPerfActivity.this, true);
-            mBackgroundOp.onInit(FrameworkPerfActivity.this, false);
-
-            synchronized (this) {
-                mStartTime = SystemClock.uptimeMillis();
-                mBackgroundRunning = true;
-                mForegroundRunning = true;
-            }
-
-            mBackgroundThread.start();
-            mForegroundThread.start();
-        }
-
-        public long getForegroundTime() {
-            return mForegroundEndTime-mStartTime;
-        }
-
-        public long getForegroundOps() {
-            return mForegroundOps;
-        }
-
-        public long getBackgroundTime() {
-            return mBackgroundEndTime-mStartTime;
-        }
-
-        public long getBackgroundOps() {
-            return mBackgroundOps;
-        }
-
-        private boolean evalRepeat(boolean bgRunning, boolean fgRunning) {
-            synchronized (this) {
-                if (!bgRunning) {
-                    mBackgroundRunning = false;
-                }
-                if (!fgRunning) {
-                    mForegroundRunning = false;
-                }
-                if (!mBackgroundRunning && !mForegroundRunning) {
-                    return false;
-                }
-                long now = SystemClock.uptimeMillis();
-                if (now > (mStartTime+mMaxRunTime)) {
-                    return false;
-                }
-                return true;
-            }
-        }
-
-        private void threadFinished(boolean foreground) {
-            synchronized (this) {
-                if (foreground) {
-                    mForegroundRunning = false;
-                } else {
-                    mBackgroundRunning = false;
-                }
-                if (!mBackgroundRunning && !mForegroundRunning) {
-                    mHandler.post(new Runnable() {
-                        @Override public void run() {
-                            mForegroundOp.onTerm(FrameworkPerfActivity.this);
-                            mBackgroundOp.onTerm(FrameworkPerfActivity.this);
-                            if (mDoneCallback != null) {
-                                mDoneCallback.run();
-                            }
-                        }
-                    });
-                }
-            }
-        }
-    }
-
-    class RunnerThread extends Thread {
-        private final Runnable mOp;
-        private final int mPriority;
-
-        RunnerThread(String name, Runnable op, int priority) {
-            super(name);
-            mOp = op;
-            mPriority = priority;
-        }
-
-        public void run() {
-            Process.setThreadPriority(mPriority);
-            mOp.run();
-        }
-    }
-
-    static public abstract class Op {
-        final String mName;
-        final String mLongName;
-
-        public Op(String name, String longName) {
-            mName = name;
-            mLongName = longName;
-        }
-
-        public String getName() {
-            return mName;
-        }
-
-        public String getLongName() {
-            return mLongName;
-        }
-
-        void onInit(Context context, boolean foreground) {
-        }
-
-        abstract boolean onRun();
-
-        void onTerm(Context context) {
-        }
-
-        int getOpsPerRun() {
-            return 1;
-        }
-    }
-
-    static class NoOp extends Op {
-        NoOp() {
-            super(null, "Nothing");
-        }
-
-        boolean onRun() {
-            return false;
-        }
-
-        int getOpsPerRun() {
-            return 0;
-        }
-    }
-
-    static class CpuOp extends Op {
-        CpuOp() {
-            super("CPU", "Consume CPU");
-        }
-
-        boolean onRun() {
-            return true;
-        }
-    }
-
-    static class SchedulerOp extends Op {
-        SchedulerOp() {
-            super("Sched", "Change scheduler group");
-        }
-
-        boolean onRun() {
-            Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND);
-            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
-            return true;
-        }
-    }
-
-    static class GcOp extends Op {
-        GcOp() {
-            super("Gc", "Run garbage collector");
-        }
-
-        boolean onRun() {
-            byte[] stuff = new byte[1024*1024];
-            return true;
-        }
-    }
-
-    static class MethodCallOp extends Op {
-        MethodCallOp() {
-            super("MethodCall", "Method call");
-        }
-
-        boolean onRun() {
-            final int N = getOpsPerRun();
-            for (int i=0; i<N; i++) {
-                someFunc(i);
-            }
-            return true;
-        }
-
-        int someFunc(int foo) {
-            return 0;
-        }
-
-        int getOpsPerRun() {
-            return 500;
-        }
-    }
-
-    static class IpcOp extends Op {
-        PackageManager mPm;
-        String mProcessName;
-
-        IpcOp() {
-            super("Ipc", "IPC to system process");
-        }
-
-        void onInit(Context context, boolean foreground) {
-            mPm = context.getPackageManager();
-            mProcessName = context.getApplicationInfo().processName;
-        }
-
-        boolean onRun() {
-            final int N = getOpsPerRun();
-            for (int i=0; i<N; i++) {
-                mPm.queryContentProviders(mProcessName, Process.myUid(), 0);
-            }
-            return true;
-        }
-
-        int getOpsPerRun() {
-            return 100;
-        }
-    }
-
-    static class OpenXmlResOp extends Op {
-        Context mContext;
-
-        OpenXmlResOp() {
-            super("OpenXmlRes", "Open (and close) an XML resource");
-        }
-
-        void onInit(Context context, boolean foreground) {
-            mContext = context;
-        }
-
-        boolean onRun() {
-            XmlResourceParser parser = mContext.getResources().getLayout(R.xml.simple);
-            parser.close();
-            return true;
-        }
-    }
-
-    static class ReadXmlAttrsOp extends Op {
-        Context mContext;
-        XmlResourceParser mParser;
-        AttributeSet mAttrs;
-
-        ReadXmlAttrsOp() {
-            super("ReadXmlAttrs", "Read attributes from an XML tag");
-        }
-
-        void onInit(Context context, boolean foreground) {
-            mContext = context;
-            mParser = mContext.getResources().getLayout(R.xml.simple);
-            mAttrs = Xml.asAttributeSet(mParser);
-
-            int eventType;
-            try {
-                // Find the first <item> tag.
-                eventType = mParser.getEventType();
-                String tagName;
-                do {
-                    if (eventType == XmlPullParser.START_TAG) {
-                        tagName = mParser.getName();
-                        if (tagName.equals("item")) {
-                            break;
-                        }
-                    }
-                    eventType = mParser.next();
-                } while (eventType != XmlPullParser.END_DOCUMENT);
-            } catch (XmlPullParserException e) {
-                throw new RuntimeException("I died", e);
-            } catch (IOException e) {
-                throw new RuntimeException("I died", e);
-            }
-        }
-
-        void onTerm(Context context) {
-            mParser.close();
-        }
-
-        boolean onRun() {
-            TypedArray a = mContext.obtainStyledAttributes(mAttrs,
-                    com.android.internal.R.styleable.MenuItem);
-            a.recycle();
-            return true;
-        }
-    }
-
-    static class ParseXmlResOp extends Op {
-        Context mContext;
-
-        ParseXmlResOp() {
-            super("ParseXmlRes", "Parse compiled XML resource");
-        }
-
-        void onInit(Context context, boolean foreground) {
-            mContext = context;
-        }
-
-        boolean onRun() {
-            SimpleInflater inf = new SimpleInflater(mContext);
-            inf.inflate(R.xml.simple);
-            return true;
-        }
-    }
-
-    static class ParseLargeXmlResOp extends Op {
-        Context mContext;
-
-        ParseLargeXmlResOp() {
-            super("ParseLargeXmlRes", "Parse large XML resource");
-        }
-
-        void onInit(Context context, boolean foreground) {
-            mContext = context;
-        }
-
-        boolean onRun() {
-            SimpleInflater inf = new SimpleInflater(mContext);
-            inf.inflate(R.xml.simple_large);
-            return true;
-        }
-    }
-
-    static class LayoutInflaterOp extends Op {
-        Context mContext;
-
-        LayoutInflaterOp() {
-            super("LayoutInflater", "Inflate layout resource");
-        }
-
-        void onInit(Context context, boolean foreground) {
-            mContext = context;
-        }
-
-        boolean onRun() {
-            if (Looper.myLooper() == null) {
-                Looper.prepare();
-            }
-            LayoutInflater inf = (LayoutInflater)mContext.getSystemService(
-                    Context.LAYOUT_INFLATER_SERVICE);
-            inf.inflate(R.layout.small_layout, null);
-            return true;
-        }
-    }
-
-    static class LayoutInflaterLargeOp extends Op {
-        Context mContext;
-
-        LayoutInflaterLargeOp() {
-            super("LayoutInflaterLarge", "Inflate large layout resource");
-        }
-
-        void onInit(Context context, boolean foreground) {
-            mContext = context;
-        }
-
-        boolean onRun() {
-            if (Looper.myLooper() == null) {
-                Looper.prepare();
-            }
-            LayoutInflater inf = (LayoutInflater)mContext.getSystemService(
-                    Context.LAYOUT_INFLATER_SERVICE);
-            inf.inflate(R.layout.large_layout, null);
-            return true;
-        }
-    }
-
-    static class LayoutInflaterViewOp extends Op {
-        Context mContext;
-
-        LayoutInflaterViewOp() {
-            super("LayoutInflaterView", "Inflate layout with 50 View objects");
-        }
-
-        void onInit(Context context, boolean foreground) {
-            mContext = context;
-        }
-
-        boolean onRun() {
-            if (Looper.myLooper() == null) {
-                Looper.prepare();
-            }
-            LayoutInflater inf = (LayoutInflater)mContext.getSystemService(
-                    Context.LAYOUT_INFLATER_SERVICE);
-            inf.inflate(R.layout.view_layout, null);
-            return true;
-        }
-    }
-
-    static class LayoutInflaterButtonOp extends Op {
-        Context mContext;
-
-        LayoutInflaterButtonOp() {
-            super("LayoutInflaterButton", "Inflate layout with 50 Button objects");
-        }
-
-        void onInit(Context context, boolean foreground) {
-            mContext = context;
-        }
-
-        boolean onRun() {
-            if (Looper.myLooper() == null) {
-                Looper.prepare();
-            }
-            LayoutInflater inf = (LayoutInflater)mContext.getSystemService(
-                    Context.LAYOUT_INFLATER_SERVICE);
-            inf.inflate(R.layout.button_layout, null);
-            return true;
-        }
-    }
-
-    static class LayoutInflaterImageButtonOp extends Op {
-        Context mContext;
-
-        LayoutInflaterImageButtonOp() {
-            super("LayoutInflaterImageButton", "Inflate layout with 50 ImageButton objects");
-        }
-
-        void onInit(Context context, boolean foreground) {
-            mContext = context;
-        }
-
-        boolean onRun() {
-            if (Looper.myLooper() == null) {
-                Looper.prepare();
-            }
-            LayoutInflater inf = (LayoutInflater)mContext.getSystemService(
-                    Context.LAYOUT_INFLATER_SERVICE);
-            inf.inflate(R.layout.image_button_layout, null);
-            return true;
-        }
-    }
-
-    static class CreateBitmapOp extends Op {
-        Context mContext;
-
-        CreateBitmapOp() {
-            super("CreateBitmap", "Create a Bitmap");
-        }
-
-        void onInit(Context context, boolean foreground) {
-            mContext = context;
-        }
-
-        boolean onRun() {
-            BitmapFactory.Options opts = new BitmapFactory.Options();
-            opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
-            Bitmap bm = Bitmap.createBitmap(16, 16, Bitmap.Config.ARGB_8888);
-            return true;
-        }
-    }
-
-    static class CreateRecycleBitmapOp extends Op {
-        Context mContext;
-
-        CreateRecycleBitmapOp() {
-            super("CreateRecycleBitmap", "Create and recycle a Bitmap");
-        }
-
-        void onInit(Context context, boolean foreground) {
-            mContext = context;
-        }
-
-        boolean onRun() {
-            BitmapFactory.Options opts = new BitmapFactory.Options();
-            opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
-            Bitmap bm = Bitmap.createBitmap(16, 16, Bitmap.Config.ARGB_8888);
-            bm.recycle();
-            return true;
-        }
-    }
-
-    static class LoadSmallBitmapOp extends Op {
-        Context mContext;
-
-        LoadSmallBitmapOp() {
-            super("LoadSmallBitmap", "Load small raw bitmap");
-        }
-
-        void onInit(Context context, boolean foreground) {
-            mContext = context;
-        }
-
-        boolean onRun() {
-            BitmapFactory.Options opts = new BitmapFactory.Options();
-            opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
-            Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(),
-                    R.drawable.stat_sample, opts);
-            return true;
-        }
-    }
-
-    static class LoadRecycleSmallBitmapOp extends Op {
-        Context mContext;
-
-        LoadRecycleSmallBitmapOp() {
-            super("LoadRecycleSmallBitmap", "Load and recycle small raw bitmap");
-        }
-
-        void onInit(Context context, boolean foreground) {
-            mContext = context;
-        }
-
-        boolean onRun() {
-            BitmapFactory.Options opts = new BitmapFactory.Options();
-            opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
-            Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(),
-                    R.drawable.stat_sample, opts);
-            bm.recycle();
-            return true;
-        }
-    }
-
-    static class LoadLargeBitmapOp extends Op {
-        Context mContext;
-
-        LoadLargeBitmapOp() {
-            super("LoadLargeBitmap", "Load large raw bitmap");
-        }
-
-        void onInit(Context context, boolean foreground) {
-            mContext = context;
-        }
-
-        boolean onRun() {
-            BitmapFactory.Options opts = new BitmapFactory.Options();
-            opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
-            Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(),
-                    R.drawable.wallpaper_goldengate, opts);
-            return true;
-        }
-    }
-
-    static class LoadRecycleLargeBitmapOp extends Op {
-        Context mContext;
-
-        LoadRecycleLargeBitmapOp() {
-            super("LoadRecycleLargeBitmap", "Load and recycle large raw bitmap");
-        }
-
-        void onInit(Context context, boolean foreground) {
-            mContext = context;
-        }
-
-        boolean onRun() {
-            BitmapFactory.Options opts = new BitmapFactory.Options();
-            opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
-            Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(),
-                    R.drawable.wallpaper_goldengate, opts);
-            bm.recycle();
-            return true;
-        }
-    }
-
-    static class LoadSmallScaledBitmapOp extends Op {
-        Context mContext;
-
-        LoadSmallScaledBitmapOp() {
-            super("LoadSmallScaledBitmap", "Load small raw bitmap that is scaled for density");
-        }
-
-        void onInit(Context context, boolean foreground) {
-            mContext = context;
-        }
-
-        boolean onRun() {
-            BitmapFactory.Options opts = new BitmapFactory.Options();
-            opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
-            Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(),
-                    R.drawable.stat_sample_scale, opts);
-            return true;
-        }
-    }
-
-    static class LoadLargeScaledBitmapOp extends Op {
-        Context mContext;
-
-        LoadLargeScaledBitmapOp() {
-            super("LoadLargeScaledBitmap", "Load large raw bitmap that is scaled for density");
-        }
-
-        void onInit(Context context, boolean foreground) {
-            mContext = context;
-        }
-
-        boolean onRun() {
-            BitmapFactory.Options opts = new BitmapFactory.Options();
-            opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
-            Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(),
-                    R.drawable.wallpaper_goldengate_scale, opts);
-            return true;
-        }
-    }
-
-    static class CreateFileOp extends Op {
-        File mFile;
-
-        CreateFileOp() {
-            super("CreateFile", "Create and delete a file");
-        }
-
-        void onInit(Context context, boolean foreground) {
-            mFile = context.getFileStreamPath(foreground ? "test-fg.file" : "test-bg.file");
-            mFile.delete();
-        }
-
-        boolean onRun() {
-            try {
-                mFile.createNewFile();
-            } catch (IOException e) {
-                Log.w(TAG, "Failure creating " + mFile, e);
-            }
-            mFile.delete();
-            return true;
-        }
-    }
-
-    static class CreateWriteFileOp extends Op {
-        File mFile;
-
-        CreateWriteFileOp() {
-            super("CreateWriteFile", "Create, write, and delete a file");
-        }
-
-        void onInit(Context context, boolean foreground) {
-            mFile = context.getFileStreamPath(foreground ? "test-fg.file" : "test-bg.file");
-            mFile.delete();
-        }
-
-        boolean onRun() {
-            try {
-                FileOutputStream fos = new FileOutputStream(mFile);
-                fos.write(1);
-                fos.close();
-            } catch (IOException e) {
-                Log.w(TAG, "Failure creating " + mFile, e);
-            }
-            mFile.delete();
-            return true;
-        }
-    }
-
-    static class CreateWriteSyncFileOp extends Op {
-        File mFile;
-
-        CreateWriteSyncFileOp() {
-            super("CreateWriteSyncFile", "Create, write, sync, and delete a file");
-        }
-
-        void onInit(Context context, boolean foreground) {
-            mFile = context.getFileStreamPath(foreground ? "test-fg.file" : "test-bg.file");
-            mFile.delete();
-        }
-
-        boolean onRun() {
-            try {
-                FileOutputStream fos = new FileOutputStream(mFile);
-                fos.write(1);
-                fos.flush();
-                FileUtils.sync(fos);
-                fos.close();
-            } catch (IOException e) {
-                Log.w(TAG, "Failure creating " + mFile, e);
-            }
-            mFile.delete();
-            return true;
-        }
-    }
-
-    static class WriteFileOp extends Op {
-        File mFile;
-        RandomAccessFile mRAF;
-        byte[] mBuffer;
-
-        WriteFileOp() {
-            super("WriteFile", "Truncate and write a 64k file");
-        }
-
-        void onInit(Context context, boolean foreground) {
-            mBuffer = new byte[1024*64];
-            for (int i=0; i<mBuffer.length; i++) {
-                mBuffer[i] = (byte)i;
-            }
-            mFile = context.getFileStreamPath(foreground ? "test-fg.file" : "test-bg.file");
-            mFile.delete();
-            try {
-                mRAF = new RandomAccessFile(mFile, "rw");
-            } catch (FileNotFoundException e) {
-                Log.w(TAG, "Failure creating " + mFile, e);
-            }
-        }
-
-        boolean onRun() {
-            try {
-                mRAF.seek(0);
-                mRAF.setLength(0);
-                mRAF.write(mBuffer);
-            } catch (IOException e) {
-                Log.w(TAG, "Failure writing " + mFile, e);
-            }
-            return true;
-        }
-
-        void onTerm(Context context) {
-            try {
-                mRAF.close();
-            } catch (IOException e) {
-                Log.w(TAG, "Failure closing " + mFile, e);
-            }
-            mFile.delete();
-        }
-    }
-
-    static class ReadFileOp extends Op {
-        File mFile;
-        RandomAccessFile mRAF;
-        byte[] mBuffer;
-
-        ReadFileOp() {
-            super("ReadFile", "Seek and read a 64k file");
-        }
-
-        void onInit(Context context, boolean foreground) {
-            mBuffer = new byte[1024*64];
-            for (int i=0; i<mBuffer.length; i++) {
-                mBuffer[i] = (byte)i;
-            }
-            mFile = context.getFileStreamPath(foreground ? "test-fg.file" : "test-bg.file");
-            mFile.delete();
-            try {
-                mRAF = new RandomAccessFile(mFile, "rw");
-                mRAF.seek(0);
-                mRAF.setLength(0);
-                mRAF.write(mBuffer);
-            } catch (IOException e) {
-                Log.w(TAG, "Failure creating " + mFile, e);
-            }
-        }
-
-        boolean onRun() {
-            try {
-                mRAF.seek(0);
-                mRAF.read(mBuffer);
-            } catch (IOException e) {
-                Log.w(TAG, "Failure reading " + mFile, e);
-            }
-            return true;
-        }
-
-        void onTerm(Context context) {
-            try {
-                mRAF.close();
-            } catch (IOException e) {
-                Log.w(TAG, "Failure closing " + mFile, e);
-            }
-            mFile.delete();
-        }
-    }
 }
diff --git a/tests/FrameworkPerf/src/com/android/frameworkperf/LocalTestService.java b/tests/FrameworkPerf/src/com/android/frameworkperf/LocalTestService.java
new file mode 100644
index 0000000..09c6be8
--- /dev/null
+++ b/tests/FrameworkPerf/src/com/android/frameworkperf/LocalTestService.java
@@ -0,0 +1,6 @@
+package com.android.frameworkperf;
+
+public class LocalTestService extends TestService {
+    void terminate() {
+    }
+}
diff --git a/tests/FrameworkPerf/src/com/android/frameworkperf/RunResult.java b/tests/FrameworkPerf/src/com/android/frameworkperf/RunResult.java
new file mode 100644
index 0000000..d14e434
--- /dev/null
+++ b/tests/FrameworkPerf/src/com/android/frameworkperf/RunResult.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2011 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.frameworkperf;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+public class RunResult implements Parcelable {
+    final String name;
+    final String fgLongName;
+    final String bgLongName;
+    final long fgTime;
+    final long fgOps;
+    final long bgTime;
+    final long bgOps;
+
+    RunResult(TestService.TestRunner op) {
+        name = op.getName();
+        fgLongName = op.getForegroundLongName();
+        bgLongName = op.getBackgroundLongName();
+        fgTime = op.getForegroundTime();
+        fgOps = op.getForegroundOps();
+        bgTime = op.getBackgroundTime();
+        bgOps = op.getBackgroundOps();
+    }
+
+    RunResult(Parcel source) {
+        name = source.readString();
+        fgLongName = source.readString();
+        bgLongName = source.readString();
+        fgTime = source.readLong();
+        fgOps = source.readLong();
+        bgTime = source.readLong();
+        bgOps = source.readLong();
+    }
+
+    float getFgMsPerOp() {
+        return fgOps != 0 ? (fgTime / (float)fgOps) : 0;
+    }
+
+    float getBgMsPerOp() {
+        return bgOps != 0 ? (bgTime / (float)bgOps) : 0;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(name);
+        dest.writeString(fgLongName);
+        dest.writeString(bgLongName);
+        dest.writeLong(fgTime);
+        dest.writeLong(fgOps);
+        dest.writeLong(bgTime);
+        dest.writeLong(bgOps);
+    }
+
+    public static final Parcelable.Creator<RunResult> CREATOR
+            = new Parcelable.Creator<RunResult>() {
+        public RunResult createFromParcel(Parcel in) {
+            return new RunResult(in);
+        }
+
+        public RunResult[] newArray(int size) {
+            return new RunResult[size];
+        }
+    };
+}
\ No newline at end of file
diff --git a/tests/FrameworkPerf/src/com/android/frameworkperf/TestArgs.java b/tests/FrameworkPerf/src/com/android/frameworkperf/TestArgs.java
new file mode 100644
index 0000000..f2f7c56
--- /dev/null
+++ b/tests/FrameworkPerf/src/com/android/frameworkperf/TestArgs.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2011 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.frameworkperf;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+public class TestArgs implements Parcelable {
+    long maxTime;
+    int combOp = -1;
+    int fgOp = -1;
+    int bgOp = -1;
+
+    public TestArgs() {
+    }
+
+    public TestArgs(Parcel source) {
+        maxTime = source.readLong();
+        combOp = source.readInt();
+        fgOp = source.readInt();
+        bgOp = source.readInt();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeLong(maxTime);
+        dest.writeInt(combOp);
+        dest.writeInt(fgOp);
+        dest.writeInt(bgOp);
+    }
+
+    public static final Parcelable.Creator<TestArgs> CREATOR
+            = new Parcelable.Creator<TestArgs>() {
+        public TestArgs createFromParcel(Parcel in) {
+            return new TestArgs(in);
+        }
+
+        public TestArgs[] newArray(int size) {
+            return new TestArgs[size];
+        }
+    };
+}
diff --git a/tests/FrameworkPerf/src/com/android/frameworkperf/TestService.java b/tests/FrameworkPerf/src/com/android/frameworkperf/TestService.java
new file mode 100644
index 0000000..ce27b65
--- /dev/null
+++ b/tests/FrameworkPerf/src/com/android/frameworkperf/TestService.java
@@ -0,0 +1,1037 @@
+/*
+ * Copyright (C) 2011 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.frameworkperf;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.Bundle;
+import android.os.FileUtils;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.util.AttributeSet;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.util.Xml;
+import android.view.LayoutInflater;
+
+public class TestService extends Service {
+    static final String TAG = "Perf";
+
+    final static Op[] mOpPairs = new Op[] {
+            new MethodCallOp(), new NoOp(),
+            new MethodCallOp(), new CpuOp(),
+            new MethodCallOp(), new SchedulerOp(),
+            new MethodCallOp(), new GcOp(),
+            new MethodCallOp(), new CreateFileOp(),
+            new MethodCallOp(), new CreateWriteFileOp(),
+            new MethodCallOp(), new CreateWriteSyncFileOp(),
+            new MethodCallOp(), new WriteFileOp(),
+            new MethodCallOp(), new ReadFileOp(),
+            new SchedulerOp(), new SchedulerOp(),
+            new GcOp(), new NoOp(),
+            new IpcOp(), new NoOp(),
+            new IpcOp(), new CpuOp(),
+            new IpcOp(), new SchedulerOp(),
+            new IpcOp(), new GcOp(),
+            new IpcOp(), new CreateFileOp(),
+            new IpcOp(), new CreateWriteFileOp(),
+            new IpcOp(), new CreateWriteSyncFileOp(),
+            new IpcOp(), new WriteFileOp(),
+            new IpcOp(), new ReadFileOp(),
+            new CreateFileOp(), new NoOp(),
+            new CreateWriteFileOp(), new NoOp(),
+            new CreateWriteSyncFileOp(), new NoOp(),
+            new WriteFileOp(), new NoOp(),
+            new ReadFileOp(), new NoOp(),
+            new WriteFileOp(), new CreateWriteFileOp(),
+            new ReadFileOp(), new CreateWriteFileOp(),
+            new WriteFileOp(), new CreateWriteSyncFileOp(),
+            new ReadFileOp(), new CreateWriteSyncFileOp(),
+            new WriteFileOp(), new WriteFileOp(),
+            new WriteFileOp(), new ReadFileOp(),
+            new ReadFileOp(), new WriteFileOp(),
+            new ReadFileOp(), new ReadFileOp(),
+            new OpenXmlResOp(), new NoOp(),
+            new ReadXmlAttrsOp(), new NoOp(),
+            new ParseXmlResOp(), new NoOp(),
+            new ParseLargeXmlResOp(), new NoOp(),
+            new LayoutInflaterOp(), new NoOp(),
+            new LayoutInflaterLargeOp(), new NoOp(),
+            new LayoutInflaterViewOp(), new NoOp(),
+            new LayoutInflaterButtonOp(), new NoOp(),
+            new LayoutInflaterImageButtonOp(), new NoOp(),
+            new CreateBitmapOp(), new NoOp(),
+            new CreateRecycleBitmapOp(), new NoOp(),
+            new LoadSmallBitmapOp(), new NoOp(),
+            new LoadRecycleSmallBitmapOp(), new NoOp(),
+            new LoadLargeBitmapOp(), new NoOp(),
+            new LoadRecycleLargeBitmapOp(), new NoOp(),
+            new LoadSmallScaledBitmapOp(), new NoOp(),
+            new LoadLargeScaledBitmapOp(), new NoOp(),
+    };
+
+    final static Op[] mAvailOps = new Op[] {
+            null,
+            new NoOp(),
+            new CpuOp(),
+            new SchedulerOp(),
+            new MethodCallOp(),
+            new IpcOp(),
+            new CreateFileOp(),
+            new CreateWriteFileOp(),
+            new CreateWriteSyncFileOp(),
+            new WriteFileOp(),
+            new ReadFileOp(),
+            new OpenXmlResOp(),
+            new ReadXmlAttrsOp(),
+            new ParseXmlResOp(),
+            new ParseLargeXmlResOp(),
+            new LayoutInflaterOp(),
+            new LayoutInflaterLargeOp(),
+            new LayoutInflaterViewOp(),
+            new LayoutInflaterButtonOp(),
+            new LayoutInflaterImageButtonOp(),
+            new CreateBitmapOp(),
+            new CreateRecycleBitmapOp(),
+            new LoadSmallBitmapOp(),
+            new LoadRecycleSmallBitmapOp(),
+            new LoadLargeBitmapOp(),
+            new LoadRecycleLargeBitmapOp(),
+            new LoadSmallScaledBitmapOp(),
+            new LoadLargeScaledBitmapOp(),
+    };
+
+    static final int CMD_START_TEST = 1;
+    static final int CMD_TERMINATE = 2;
+    
+    static final int RES_TEST_FINISHED = 1;
+    static final int RES_TERMINATED = 2;
+
+    final Handler mHandler = new Handler() {
+        @Override public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case CMD_START_TEST: {
+                    Bundle bundle = (Bundle)msg.obj;
+                    bundle.setClassLoader(getClassLoader());
+                    final TestArgs args = (TestArgs)bundle.getParcelable("args");
+                    final Messenger replyTo = msg.replyTo;
+                    mRunner.run(this, args, new Runnable() {
+                        @Override public void run() {
+                            if (replyTo != null) {
+                                Message msg = Message.obtain(null, RES_TEST_FINISHED);
+                                Bundle bundle = new Bundle();
+                                bundle.putParcelable("res", new RunResult(mRunner));
+                                msg.obj = bundle;
+                                try {
+                                    replyTo.send(msg);
+                                } catch (RemoteException e) {
+                                }
+                            }
+                        }
+                    });
+                } break;
+                case CMD_TERMINATE: {
+                    if (msg.replyTo != null) {
+                        Message reply = Message.obtain(null, RES_TERMINATED);
+                        try {
+                            msg.replyTo.send(reply);
+                        } catch (RemoteException e) {
+                        }
+                    }
+                    terminate();
+                }
+            }
+        }
+    };
+
+    final TestRunner mRunner = new TestRunner();
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return (new Messenger(mHandler)).getBinder();
+    }
+
+    void terminate() {
+        Process.killProcess(Process.myPid());
+    }
+
+    enum BackgroundMode {
+        NOTHING,
+        CPU,
+        SCHEDULER
+    };
+
+    public class TestRunner {
+        Handler mHandler;
+        long mMaxRunTime;
+        Op mForegroundOp;
+        Op mBackgroundOp;
+        Runnable mDoneCallback;
+
+        RunnerThread mBackgroundThread;
+        RunnerThread mForegroundThread;
+        long mStartTime;
+
+        boolean mBackgroundRunning;
+        boolean mForegroundRunning;
+
+        long mBackgroundEndTime;
+        long mBackgroundOps;
+        long mForegroundEndTime;
+        long mForegroundOps;
+
+        public TestRunner() {
+        }
+
+        public String getForegroundName() {
+            return mForegroundOp.getName();
+        }
+
+        public String getBackgroundName() {
+            return mBackgroundOp.getName();
+        }
+
+        public String getName() {
+            String fgName = mForegroundOp.getName();
+            String bgName = mBackgroundOp.getName();
+            StringBuilder res = new StringBuilder();
+            if (fgName != null) {
+                res.append(fgName);
+                res.append("Fg");
+            }
+            if (bgName != null) {
+                res.append(bgName);
+                res.append("Bg");
+            }
+            return res.toString();
+        }
+
+        public String getForegroundLongName() {
+            return mForegroundOp.getLongName();
+        }
+
+        public String getBackgroundLongName() {
+            return mBackgroundOp.getLongName();
+        }
+
+        public void run(Handler handler, TestArgs args, Runnable doneCallback) {
+            mHandler = handler;
+            mMaxRunTime = args.maxTime;
+            if (args.combOp >= 0) {
+                mForegroundOp = mOpPairs[args.combOp];
+                mBackgroundOp = mOpPairs[args.combOp+1];
+            } else {
+                mForegroundOp = mAvailOps[args.fgOp];
+                mBackgroundOp = mAvailOps[args.bgOp];
+            }
+            mDoneCallback = doneCallback;
+            mBackgroundThread = new RunnerThread("background", new Runnable() {
+                @Override public void run() {
+                    boolean running;
+                    int ops = 0;
+                    do {
+                        running = mBackgroundOp.onRun();
+                        ops++;
+                    } while (evalRepeat(running, true) && running);
+                    mBackgroundEndTime = SystemClock.uptimeMillis();
+                    mBackgroundOps = ops * mBackgroundOp.getOpsPerRun();
+                    threadFinished(false);
+                }
+            }, Process.THREAD_PRIORITY_BACKGROUND);
+            mForegroundThread = new RunnerThread("background", new Runnable() {
+                @Override public void run() {
+                    boolean running;
+                    int ops = 0;
+                    do {
+                        running = mForegroundOp.onRun();
+                        ops++;
+                    } while (evalRepeat(true, running) && running);
+                    mForegroundEndTime = SystemClock.uptimeMillis();
+                    mForegroundOps = ops * mForegroundOp.getOpsPerRun();
+                    threadFinished(true);
+                }
+            }, Process.THREAD_PRIORITY_FOREGROUND);
+
+            mForegroundOp.onInit(TestService.this, true);
+            mBackgroundOp.onInit(TestService.this, false);
+
+            synchronized (this) {
+                mStartTime = SystemClock.uptimeMillis();
+                mBackgroundRunning = true;
+                mForegroundRunning = true;
+            }
+
+            mBackgroundThread.start();
+            mForegroundThread.start();
+        }
+
+        public long getForegroundTime() {
+            return mForegroundEndTime-mStartTime;
+        }
+
+        public long getForegroundOps() {
+            return mForegroundOps;
+        }
+
+        public long getBackgroundTime() {
+            return mBackgroundEndTime-mStartTime;
+        }
+
+        public long getBackgroundOps() {
+            return mBackgroundOps;
+        }
+
+        private boolean evalRepeat(boolean bgRunning, boolean fgRunning) {
+            synchronized (this) {
+                if (!bgRunning) {
+                    mBackgroundRunning = false;
+                }
+                if (!fgRunning) {
+                    mForegroundRunning = false;
+                }
+                if (!mBackgroundRunning && !mForegroundRunning) {
+                    return false;
+                }
+                long now = SystemClock.uptimeMillis();
+                if (now > (mStartTime+mMaxRunTime)) {
+                    return false;
+                }
+                return true;
+            }
+        }
+
+        private void threadFinished(boolean foreground) {
+            synchronized (this) {
+                if (foreground) {
+                    mForegroundRunning = false;
+                } else {
+                    mBackgroundRunning = false;
+                }
+                if (!mBackgroundRunning && !mForegroundRunning) {
+                    mHandler.post(new Runnable() {
+                        @Override public void run() {
+                            mForegroundOp.onTerm(TestService.this);
+                            mBackgroundOp.onTerm(TestService.this);
+                            if (mDoneCallback != null) {
+                                mDoneCallback.run();
+                            }
+                        }
+                    });
+                }
+            }
+        }
+    }
+
+    class RunnerThread extends Thread {
+        private final Runnable mOp;
+        private final int mPriority;
+
+        RunnerThread(String name, Runnable op, int priority) {
+            super(name);
+            mOp = op;
+            mPriority = priority;
+        }
+
+        public void run() {
+            Process.setThreadPriority(mPriority);
+            mOp.run();
+        }
+    }
+
+    static public abstract class Op {
+        final String mName;
+        final String mLongName;
+
+        public Op(String name, String longName) {
+            mName = name;
+            mLongName = longName;
+        }
+
+        public String getName() {
+            return mName;
+        }
+
+        public String getLongName() {
+            return mLongName;
+        }
+
+        void onInit(Context context, boolean foreground) {
+        }
+
+        abstract boolean onRun();
+
+        void onTerm(Context context) {
+        }
+
+        int getOpsPerRun() {
+            return 1;
+        }
+    }
+
+    static class NoOp extends Op {
+        NoOp() {
+            super(null, "Nothing");
+        }
+
+        boolean onRun() {
+            return false;
+        }
+
+        int getOpsPerRun() {
+            return 0;
+        }
+    }
+
+    static class CpuOp extends Op {
+        CpuOp() {
+            super("CPU", "Consume CPU");
+        }
+
+        boolean onRun() {
+            return true;
+        }
+    }
+
+    static class SchedulerOp extends Op {
+        SchedulerOp() {
+            super("Sched", "Change scheduler group");
+        }
+
+        boolean onRun() {
+            Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND);
+            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
+            return true;
+        }
+    }
+
+    static class GcOp extends Op {
+        GcOp() {
+            super("Gc", "Run garbage collector");
+        }
+
+        boolean onRun() {
+            byte[] stuff = new byte[1024*1024];
+            return true;
+        }
+    }
+
+    static class MethodCallOp extends Op {
+        MethodCallOp() {
+            super("MethodCall", "Method call");
+        }
+
+        boolean onRun() {
+            final int N = getOpsPerRun();
+            for (int i=0; i<N; i++) {
+                someFunc(i);
+            }
+            return true;
+        }
+
+        int someFunc(int foo) {
+            return 0;
+        }
+
+        int getOpsPerRun() {
+            return 500;
+        }
+    }
+
+    static class IpcOp extends Op {
+        PackageManager mPm;
+        String mProcessName;
+
+        IpcOp() {
+            super("Ipc", "IPC to system process");
+        }
+
+        void onInit(Context context, boolean foreground) {
+            mPm = context.getPackageManager();
+            mProcessName = context.getApplicationInfo().processName;
+        }
+
+        boolean onRun() {
+            final int N = getOpsPerRun();
+            for (int i=0; i<N; i++) {
+                mPm.queryContentProviders(mProcessName, Process.myUid(), 0);
+            }
+            return true;
+        }
+
+        int getOpsPerRun() {
+            return 100;
+        }
+    }
+
+    static class OpenXmlResOp extends Op {
+        Context mContext;
+
+        OpenXmlResOp() {
+            super("OpenXmlRes", "Open (and close) an XML resource");
+        }
+
+        void onInit(Context context, boolean foreground) {
+            mContext = context;
+        }
+
+        boolean onRun() {
+            XmlResourceParser parser = mContext.getResources().getLayout(R.xml.simple);
+            parser.close();
+            return true;
+        }
+    }
+
+    static class ReadXmlAttrsOp extends Op {
+        Context mContext;
+        XmlResourceParser mParser;
+        AttributeSet mAttrs;
+
+        ReadXmlAttrsOp() {
+            super("ReadXmlAttrs", "Read attributes from an XML tag");
+        }
+
+        void onInit(Context context, boolean foreground) {
+            mContext = context;
+            mParser = mContext.getResources().getLayout(R.xml.simple);
+            mAttrs = Xml.asAttributeSet(mParser);
+
+            int eventType;
+            try {
+                // Find the first <item> tag.
+                eventType = mParser.getEventType();
+                String tagName;
+                do {
+                    if (eventType == XmlPullParser.START_TAG) {
+                        tagName = mParser.getName();
+                        if (tagName.equals("item")) {
+                            break;
+                        }
+                    }
+                    eventType = mParser.next();
+                } while (eventType != XmlPullParser.END_DOCUMENT);
+            } catch (XmlPullParserException e) {
+                throw new RuntimeException("I died", e);
+            } catch (IOException e) {
+                throw new RuntimeException("I died", e);
+            }
+        }
+
+        void onTerm(Context context) {
+            mParser.close();
+        }
+
+        boolean onRun() {
+            TypedArray a = mContext.obtainStyledAttributes(mAttrs,
+                    com.android.internal.R.styleable.MenuItem);
+            a.recycle();
+            return true;
+        }
+    }
+
+    static class ParseXmlResOp extends Op {
+        Context mContext;
+
+        ParseXmlResOp() {
+            super("ParseXmlRes", "Parse compiled XML resource");
+        }
+
+        void onInit(Context context, boolean foreground) {
+            mContext = context;
+        }
+
+        boolean onRun() {
+            SimpleInflater inf = new SimpleInflater(mContext);
+            inf.inflate(R.xml.simple);
+            return true;
+        }
+    }
+
+    static class ParseLargeXmlResOp extends Op {
+        Context mContext;
+
+        ParseLargeXmlResOp() {
+            super("ParseLargeXmlRes", "Parse large XML resource");
+        }
+
+        void onInit(Context context, boolean foreground) {
+            mContext = context;
+        }
+
+        boolean onRun() {
+            SimpleInflater inf = new SimpleInflater(mContext);
+            inf.inflate(R.xml.simple_large);
+            return true;
+        }
+    }
+
+    static class LayoutInflaterOp extends Op {
+        Context mContext;
+
+        LayoutInflaterOp() {
+            super("LayoutInflater", "Inflate layout resource");
+        }
+
+        void onInit(Context context, boolean foreground) {
+            mContext = context;
+        }
+
+        boolean onRun() {
+            if (Looper.myLooper() == null) {
+                Looper.prepare();
+            }
+            LayoutInflater inf = (LayoutInflater)mContext.getSystemService(
+                    Context.LAYOUT_INFLATER_SERVICE);
+            inf.inflate(R.layout.small_layout, null);
+            return true;
+        }
+    }
+
+    static class LayoutInflaterLargeOp extends Op {
+        Context mContext;
+
+        LayoutInflaterLargeOp() {
+            super("LayoutInflaterLarge", "Inflate large layout resource");
+        }
+
+        void onInit(Context context, boolean foreground) {
+            mContext = context;
+        }
+
+        boolean onRun() {
+            if (Looper.myLooper() == null) {
+                Looper.prepare();
+            }
+            LayoutInflater inf = (LayoutInflater)mContext.getSystemService(
+                    Context.LAYOUT_INFLATER_SERVICE);
+            inf.inflate(R.layout.large_layout, null);
+            return true;
+        }
+    }
+
+    static class LayoutInflaterViewOp extends Op {
+        Context mContext;
+
+        LayoutInflaterViewOp() {
+            super("LayoutInflaterView", "Inflate layout with 50 View objects");
+        }
+
+        void onInit(Context context, boolean foreground) {
+            mContext = context;
+        }
+
+        boolean onRun() {
+            if (Looper.myLooper() == null) {
+                Looper.prepare();
+            }
+            LayoutInflater inf = (LayoutInflater)mContext.getSystemService(
+                    Context.LAYOUT_INFLATER_SERVICE);
+            inf.inflate(R.layout.view_layout, null);
+            return true;
+        }
+    }
+
+    static class LayoutInflaterButtonOp extends Op {
+        Context mContext;
+
+        LayoutInflaterButtonOp() {
+            super("LayoutInflaterButton", "Inflate layout with 50 Button objects");
+        }
+
+        void onInit(Context context, boolean foreground) {
+            mContext = context;
+        }
+
+        boolean onRun() {
+            if (Looper.myLooper() == null) {
+                Looper.prepare();
+            }
+            LayoutInflater inf = (LayoutInflater)mContext.getSystemService(
+                    Context.LAYOUT_INFLATER_SERVICE);
+            inf.inflate(R.layout.button_layout, null);
+            return true;
+        }
+    }
+
+    static class LayoutInflaterImageButtonOp extends Op {
+        Context mContext;
+
+        LayoutInflaterImageButtonOp() {
+            super("LayoutInflaterImageButton", "Inflate layout with 50 ImageButton objects");
+        }
+
+        void onInit(Context context, boolean foreground) {
+            mContext = context;
+        }
+
+        boolean onRun() {
+            if (Looper.myLooper() == null) {
+                Looper.prepare();
+            }
+            LayoutInflater inf = (LayoutInflater)mContext.getSystemService(
+                    Context.LAYOUT_INFLATER_SERVICE);
+            inf.inflate(R.layout.image_button_layout, null);
+            return true;
+        }
+    }
+
+    static class CreateBitmapOp extends Op {
+        Context mContext;
+
+        CreateBitmapOp() {
+            super("CreateBitmap", "Create a Bitmap");
+        }
+
+        void onInit(Context context, boolean foreground) {
+            mContext = context;
+        }
+
+        boolean onRun() {
+            BitmapFactory.Options opts = new BitmapFactory.Options();
+            opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
+            Bitmap bm = Bitmap.createBitmap(16, 16, Bitmap.Config.ARGB_8888);
+            return true;
+        }
+    }
+
+    static class CreateRecycleBitmapOp extends Op {
+        Context mContext;
+
+        CreateRecycleBitmapOp() {
+            super("CreateRecycleBitmap", "Create and recycle a Bitmap");
+        }
+
+        void onInit(Context context, boolean foreground) {
+            mContext = context;
+        }
+
+        boolean onRun() {
+            BitmapFactory.Options opts = new BitmapFactory.Options();
+            opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
+            Bitmap bm = Bitmap.createBitmap(16, 16, Bitmap.Config.ARGB_8888);
+            bm.recycle();
+            return true;
+        }
+    }
+
+    static class LoadSmallBitmapOp extends Op {
+        Context mContext;
+
+        LoadSmallBitmapOp() {
+            super("LoadSmallBitmap", "Load small raw bitmap");
+        }
+
+        void onInit(Context context, boolean foreground) {
+            mContext = context;
+        }
+
+        boolean onRun() {
+            BitmapFactory.Options opts = new BitmapFactory.Options();
+            opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
+            Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(),
+                    R.drawable.stat_sample, opts);
+            return true;
+        }
+    }
+
+    static class LoadRecycleSmallBitmapOp extends Op {
+        Context mContext;
+
+        LoadRecycleSmallBitmapOp() {
+            super("LoadRecycleSmallBitmap", "Load and recycle small raw bitmap");
+        }
+
+        void onInit(Context context, boolean foreground) {
+            mContext = context;
+        }
+
+        boolean onRun() {
+            BitmapFactory.Options opts = new BitmapFactory.Options();
+            opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
+            Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(),
+                    R.drawable.stat_sample, opts);
+            bm.recycle();
+            return true;
+        }
+    }
+
+    static class LoadLargeBitmapOp extends Op {
+        Context mContext;
+
+        LoadLargeBitmapOp() {
+            super("LoadLargeBitmap", "Load large raw bitmap");
+        }
+
+        void onInit(Context context, boolean foreground) {
+            mContext = context;
+        }
+
+        boolean onRun() {
+            BitmapFactory.Options opts = new BitmapFactory.Options();
+            opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
+            Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(),
+                    R.drawable.wallpaper_goldengate, opts);
+            return true;
+        }
+    }
+
+    static class LoadRecycleLargeBitmapOp extends Op {
+        Context mContext;
+
+        LoadRecycleLargeBitmapOp() {
+            super("LoadRecycleLargeBitmap", "Load and recycle large raw bitmap");
+        }
+
+        void onInit(Context context, boolean foreground) {
+            mContext = context;
+        }
+
+        boolean onRun() {
+            BitmapFactory.Options opts = new BitmapFactory.Options();
+            opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
+            Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(),
+                    R.drawable.wallpaper_goldengate, opts);
+            bm.recycle();
+            return true;
+        }
+    }
+
+    static class LoadSmallScaledBitmapOp extends Op {
+        Context mContext;
+
+        LoadSmallScaledBitmapOp() {
+            super("LoadSmallScaledBitmap", "Load small raw bitmap that is scaled for density");
+        }
+
+        void onInit(Context context, boolean foreground) {
+            mContext = context;
+        }
+
+        boolean onRun() {
+            BitmapFactory.Options opts = new BitmapFactory.Options();
+            opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
+            Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(),
+                    R.drawable.stat_sample_scale, opts);
+            return true;
+        }
+    }
+
+    static class LoadLargeScaledBitmapOp extends Op {
+        Context mContext;
+
+        LoadLargeScaledBitmapOp() {
+            super("LoadLargeScaledBitmap", "Load large raw bitmap that is scaled for density");
+        }
+
+        void onInit(Context context, boolean foreground) {
+            mContext = context;
+        }
+
+        boolean onRun() {
+            BitmapFactory.Options opts = new BitmapFactory.Options();
+            opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
+            Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(),
+                    R.drawable.wallpaper_goldengate_scale, opts);
+            return true;
+        }
+    }
+
+    static class CreateFileOp extends Op {
+        File mFile;
+
+        CreateFileOp() {
+            super("CreateFile", "Create and delete a file");
+        }
+
+        void onInit(Context context, boolean foreground) {
+            mFile = context.getFileStreamPath(foreground ? "test-fg.file" : "test-bg.file");
+            mFile.delete();
+        }
+
+        boolean onRun() {
+            try {
+                mFile.createNewFile();
+            } catch (IOException e) {
+                Log.w(TAG, "Failure creating " + mFile, e);
+            }
+            mFile.delete();
+            return true;
+        }
+    }
+
+    static class CreateWriteFileOp extends Op {
+        File mFile;
+
+        CreateWriteFileOp() {
+            super("CreateWriteFile", "Create, write, and delete a file");
+        }
+
+        void onInit(Context context, boolean foreground) {
+            mFile = context.getFileStreamPath(foreground ? "test-fg.file" : "test-bg.file");
+            mFile.delete();
+        }
+
+        boolean onRun() {
+            try {
+                FileOutputStream fos = new FileOutputStream(mFile);
+                fos.write(1);
+                fos.close();
+            } catch (IOException e) {
+                Log.w(TAG, "Failure creating " + mFile, e);
+            }
+            mFile.delete();
+            return true;
+        }
+    }
+
+    static class CreateWriteSyncFileOp extends Op {
+        File mFile;
+
+        CreateWriteSyncFileOp() {
+            super("CreateWriteSyncFile", "Create, write, sync, and delete a file");
+        }
+
+        void onInit(Context context, boolean foreground) {
+            mFile = context.getFileStreamPath(foreground ? "test-fg.file" : "test-bg.file");
+            mFile.delete();
+        }
+
+        boolean onRun() {
+            try {
+                FileOutputStream fos = new FileOutputStream(mFile);
+                fos.write(1);
+                fos.flush();
+                FileUtils.sync(fos);
+                fos.close();
+            } catch (IOException e) {
+                Log.w(TAG, "Failure creating " + mFile, e);
+            }
+            mFile.delete();
+            return true;
+        }
+    }
+
+    static class WriteFileOp extends Op {
+        File mFile;
+        RandomAccessFile mRAF;
+        byte[] mBuffer;
+
+        WriteFileOp() {
+            super("WriteFile", "Truncate and write a 64k file");
+        }
+
+        void onInit(Context context, boolean foreground) {
+            mBuffer = new byte[1024*64];
+            for (int i=0; i<mBuffer.length; i++) {
+                mBuffer[i] = (byte)i;
+            }
+            mFile = context.getFileStreamPath(foreground ? "test-fg.file" : "test-bg.file");
+            mFile.delete();
+            try {
+                mRAF = new RandomAccessFile(mFile, "rw");
+            } catch (FileNotFoundException e) {
+                Log.w(TAG, "Failure creating " + mFile, e);
+            }
+        }
+
+        boolean onRun() {
+            try {
+                mRAF.seek(0);
+                mRAF.setLength(0);
+                mRAF.write(mBuffer);
+            } catch (IOException e) {
+                Log.w(TAG, "Failure writing " + mFile, e);
+            }
+            return true;
+        }
+
+        void onTerm(Context context) {
+            try {
+                mRAF.close();
+            } catch (IOException e) {
+                Log.w(TAG, "Failure closing " + mFile, e);
+            }
+            mFile.delete();
+        }
+    }
+
+    static class ReadFileOp extends Op {
+        File mFile;
+        RandomAccessFile mRAF;
+        byte[] mBuffer;
+
+        ReadFileOp() {
+            super("ReadFile", "Seek and read a 64k file");
+        }
+
+        void onInit(Context context, boolean foreground) {
+            mBuffer = new byte[1024*64];
+            for (int i=0; i<mBuffer.length; i++) {
+                mBuffer[i] = (byte)i;
+            }
+            mFile = context.getFileStreamPath(foreground ? "test-fg.file" : "test-bg.file");
+            mFile.delete();
+            try {
+                mRAF = new RandomAccessFile(mFile, "rw");
+                mRAF.seek(0);
+                mRAF.setLength(0);
+                mRAF.write(mBuffer);
+            } catch (IOException e) {
+                Log.w(TAG, "Failure creating " + mFile, e);
+            }
+        }
+
+        boolean onRun() {
+            try {
+                mRAF.seek(0);
+                mRAF.read(mBuffer);
+            } catch (IOException e) {
+                Log.w(TAG, "Failure reading " + mFile, e);
+            }
+            return true;
+        }
+
+        void onTerm(Context context) {
+            try {
+                mRAF.close();
+            } catch (IOException e) {
+                Log.w(TAG, "Failure closing " + mFile, e);
+            }
+            mFile.delete();
+        }
+    }
+}