Merge "Hook up tgammaf properly for RS." into honeycomb
diff --git a/api/11.xml b/api/11.xml
index d79baf0..232f62c4 100644
--- a/api/11.xml
+++ b/api/11.xml
@@ -238854,7 +238854,7 @@
 >
 </method>
 <method name="onRemoteAdapterConnected"
- return="void"
+ return="boolean"
  abstract="false"
  native="false"
  synchronized="false"
@@ -240832,7 +240832,7 @@
 >
 </method>
 <method name="onRemoteAdapterConnected"
- return="void"
+ return="boolean"
  abstract="false"
  native="false"
  synchronized="false"
diff --git a/api/current.xml b/api/current.xml
index a1113ec..8b9f381 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -238864,7 +238864,7 @@
 >
 </method>
 <method name="onRemoteAdapterConnected"
- return="void"
+ return="boolean"
  abstract="false"
  native="false"
  synchronized="false"
@@ -240842,7 +240842,7 @@
 >
 </method>
 <method name="onRemoteAdapterConnected"
- return="void"
+ return="boolean"
  abstract="false"
  native="false"
  synchronized="false"
diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java
index 231f592..9246a10 100644
--- a/core/java/android/bluetooth/BluetoothA2dp.java
+++ b/core/java/android/bluetooth/BluetoothA2dp.java
@@ -56,7 +56,7 @@
      *   <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
      * </ul>
      *
-     * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
+     * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
      * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING},
      * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}.
      *
@@ -75,10 +75,10 @@
      * <ul>
      *   <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
      *   <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile. </li>
-     *   <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. <li/>
+     *   <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
      * </ul>
      *
-     * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
+     * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
      * {@link #STATE_PLAYING}, {@link #STATE_NOT_PLAYING},
      *
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to
diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java
index 768a6ff..fa55520 100644
--- a/core/java/android/bluetooth/BluetoothHeadset.java
+++ b/core/java/android/bluetooth/BluetoothHeadset.java
@@ -57,7 +57,7 @@
      *   <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile. </li>
      *   <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
      * </ul>
-     * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
+     * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
      * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING},
      * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}.
      *
@@ -78,7 +78,7 @@
      *   <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile. </li>
      *   <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
      * </ul>
-     * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
+     * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
      * {@link #STATE_AUDIO_CONNECTED}, {@link #STATE_AUDIO_DISCONNECTED},
      *
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission
@@ -102,12 +102,12 @@
      *  <li> {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE} - The AT
      *       command type which can be one of  {@link #AT_CMD_TYPE_READ},
      *       {@link #AT_CMD_TYPE_TEST}, or {@link #AT_CMD_TYPE_SET},
-     *       {@link #AT_CMD_TYPE_BASIC},{@link #AT_CMD_TYPE_ACTION}. <li/>
+     *       {@link #AT_CMD_TYPE_BASIC},{@link #AT_CMD_TYPE_ACTION}. </li>
      *  <li> {@link #EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_ARGS} - Command
      *       arguments. </li>
      * </ul>
      *
-     * The category is the Company ID of the vendor defining the
+     *<p> The category is the Company ID of the vendor defining the
      * vendor-specific command. {@link BluetoothAssignedNumbers}
      *
      * For example, for Plantronics specific events
@@ -117,7 +117,7 @@
      * <ul>
      *   <li> EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD = +XEVENT </li>
      *   <li> EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE = AT_CMD_TYPE_SET </li>
-     *   <li> EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_ARGS = foo, 3 <li>
+     *   <li> EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_ARGS = foo, 3 </li>
      * </ul>
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission
      * to receive.
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index dac3135..9a6a274 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -56,8 +56,6 @@
 
     private DrawFilter mFilter;
 
-    private boolean mContextLocked;
-
     ///////////////////////////////////////////////////////////////////////////
     // JNI
     ///////////////////////////////////////////////////////////////////////////
@@ -224,33 +222,12 @@
     private static native void nFinish(int renderer);
 
     @Override
-    public boolean acquireContext() {
-        if (!mContextLocked) {
-            nAcquireContext(mRenderer);
-            mContextLocked = true;
-        }
-        return mContextLocked;
-    }
-
-    private static native void nAcquireContext(int renderer);
-
-    @Override
     public boolean callDrawGLFunction(int drawGLFunction) {
         return nCallDrawGLFunction(mRenderer, drawGLFunction);
     }
 
     private static native boolean nCallDrawGLFunction(int renderer, int drawGLFunction);
 
-    @Override
-    public void releaseContext() {
-        if (mContextLocked) {
-            nReleaseContext(mRenderer);
-            mContextLocked = false;
-        }
-    }
-
-    private static native void nReleaseContext(int renderer);
-    
     ///////////////////////////////////////////////////////////////////////////
     // Display list
     ///////////////////////////////////////////////////////////////////////////
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 0992079..069e8ef 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -188,14 +188,9 @@
         // Allow us to use up to our memory class value before V8's GC kicks in.
         // These values have been determined by experimentation.
         mLowMemoryUsageThresholdMb = manager.getLargeMemoryClass();
-        // If things get crazy, allow V8 to use up to 3 times our memory class, or a third of the
-        // device's total available memory, whichever is smaller.  This value must be no less
-        // than the low memory threshold.
-        // At that point V8 will start attempting more aggressive garbage collection.
-        mHighMemoryUsageThresholdMb = Math.max(Math.min(mLowMemoryUsageThresholdMb * 3,
-                (int) (memInfo.availMem / 3) >> 20), mLowMemoryUsageThresholdMb);
+        mHighMemoryUsageThresholdMb = (int) (mLowMemoryUsageThresholdMb * 1.5);
         // Avoid constant V8 GC when memory usage equals to working set estimate.
-        mHighUsageDeltaMb = 1;
+        mHighUsageDeltaMb = mLowMemoryUsageThresholdMb / 32;
 
         // Send a message to initialize the WebViewCore.
         Message init = sWebCoreHandler.obtainMessage(
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 6d66bbc..631ba0c 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -5289,12 +5289,15 @@
     /**
      * Called back when the adapter connects to the RemoteViewsService.
      */
-    public void onRemoteAdapterConnected() {
+    public boolean onRemoteAdapterConnected() {
         if (mRemoteAdapter != mAdapter) {
             setAdapter(mRemoteAdapter);
+            return false;
         } else if (mRemoteAdapter != null) {
             mRemoteAdapter.superNotifyDataSetChanged();
+            return true;
         }
+        return false;
     }
 
     /**
diff --git a/core/java/android/widget/AdapterViewAnimator.java b/core/java/android/widget/AdapterViewAnimator.java
index b505c85..e3a62db 100644
--- a/core/java/android/widget/AdapterViewAnimator.java
+++ b/core/java/android/widget/AdapterViewAnimator.java
@@ -54,6 +54,12 @@
     int mWhichChild = 0;
 
     /**
+     * The index of the child to restore after the asynchronous connection from the
+     * RemoteViewsAdapter has been.
+     */
+    private int mRestoreWhichChild = -1;
+
+    /**
      * Whether or not the first view(s) should be animated in
      */
     boolean mAnimateFirstTime = true;
@@ -780,7 +786,15 @@
         // set mWhichChild
         mWhichChild = ss.whichChild;
 
-        setDisplayedChild(mWhichChild);
+        // When using RemoteAdapters, the async connection process can lead to
+        // onRestoreInstanceState to be called before setAdapter(), so we need to save the previous
+        // values to restore the list position after we connect, and can skip setting the displayed
+        // child until then.
+        if (mRemoteViewsAdapter != null && mAdapter == null) {
+            mRestoreWhichChild = mWhichChild;
+        } else {
+            setDisplayedChild(mWhichChild);
+        }
     }
 
     /**
@@ -957,12 +971,21 @@
     /**
      * Called back when the adapter connects to the RemoteViewsService.
      */
-    public void onRemoteAdapterConnected() {
+    public boolean onRemoteAdapterConnected() {
         if (mRemoteViewsAdapter != mAdapter) {
             setAdapter(mRemoteViewsAdapter);
+
+            // Restore the previous position (see onRestoreInstanceState)
+            if (mRestoreWhichChild > -1) {
+                setDisplayedChild(mRestoreWhichChild);
+                mRestoreWhichChild = -1;
+            }
+            return false;
         } else if (mRemoteViewsAdapter != null) {
             mRemoteViewsAdapter.superNotifyDataSetChanged();
+            return true;
         }
+        return false;
     }
 
     /**
@@ -992,10 +1015,4 @@
      */
     public void fyiWillBeAdvancedByHostKThx() {
     }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        mAdapter = null;
-        super.onDetachedFromWindow();
-    }
 }
diff --git a/core/java/android/widget/RemoteViewsAdapter.java b/core/java/android/widget/RemoteViewsAdapter.java
index f329a3e..2457f7f 100644
--- a/core/java/android/widget/RemoteViewsAdapter.java
+++ b/core/java/android/widget/RemoteViewsAdapter.java
@@ -48,11 +48,11 @@
     private static final String TAG = "RemoteViewsAdapter";
 
     // The max number of items in the cache
-    private static final int sDefaultCacheSize = 36;
+    private static final int sDefaultCacheSize = 50;
     // The delay (in millis) to wait until attempting to unbind from a service after a request.
     // This ensures that we don't stay continually bound to the service and that it can be destroyed
     // if we need the memory elsewhere in the system.
-    private static final int sUnbindServiceDelay = 5000;
+    private static final int sUnbindServiceDelay = 1000;
     // Type defs for controlling different messages across the main and worker message queues
     private static final int sDefaultMessageType = 0;
     private static final int sUnbindServiceMessageType = 1;
@@ -65,6 +65,9 @@
     private WeakReference<RemoteAdapterConnectionCallback> mCallback;
     private FixedSizeRemoteViewsCache mCache;
 
+    // A flag to determine whether we should notify data set changed after we connect
+    private boolean mNotifyDataSetChangedAfterOnServiceConnected = false;
+
     // The set of requested views that are to be notified when the associated RemoteViews are
     // loaded.
     private RemoteViewsFrameLayoutRefSet mRequestedViews;
@@ -79,7 +82,10 @@
      * are actually connected to/disconnected from their actual services.
      */
     public interface RemoteAdapterConnectionCallback {
-        public void onRemoteAdapterConnected();
+        /**
+         * @return whether the adapter was set or not.
+         */
+        public boolean onRemoteAdapterConnected();
 
         public void onRemoteAdapterDisconnected();
     }
@@ -93,7 +99,8 @@
      */
     private static class RemoteViewsAdapterServiceConnection extends
             IRemoteViewsAdapterConnection.Stub {
-        private boolean mConnected;
+        private boolean mIsConnected;
+        private boolean mIsConnecting;
         private WeakReference<RemoteViewsAdapter> mAdapter;
         private IRemoteViewsFactory mRemoteViewsFactory;
 
@@ -101,27 +108,58 @@
             mAdapter = new WeakReference<RemoteViewsAdapter>(adapter);
         }
 
-        public void onServiceConnected(IBinder service) {
-            mRemoteViewsFactory = IRemoteViewsFactory.Stub.asInterface(service);
-            mConnected = true;
+        public synchronized void bind(Context context, int appWidgetId, Intent intent) {
+            if (!mIsConnecting) {
+                try {
+                    final AppWidgetManager mgr = AppWidgetManager.getInstance(context);
+                    mgr.bindRemoteViewsService(appWidgetId, intent, asBinder());
+                    mIsConnecting = true;
+                } catch (Exception e) {
+                    Log.e("RemoteViewsAdapterServiceConnection", "bind(): " + e.getMessage());
+                    mIsConnecting = false;
+                    mIsConnected = false;
+                }
+            }
+        }
 
-            // Queue up work that we need to do for the callback to run
+        public synchronized void unbind(Context context, int appWidgetId, Intent intent) {
+            try {
+                final AppWidgetManager mgr = AppWidgetManager.getInstance(context);
+                mgr.unbindRemoteViewsService(appWidgetId, intent);
+                mIsConnecting = false;
+            } catch (Exception e) {
+                Log.e("RemoteViewsAdapterServiceConnection", "unbind(): " + e.getMessage());
+                mIsConnecting = false;
+                mIsConnected = false;
+            }
+        }
+
+        public synchronized void onServiceConnected(IBinder service) {
+            mRemoteViewsFactory = IRemoteViewsFactory.Stub.asInterface(service);
+
+            // Remove any deferred unbind messages
             final RemoteViewsAdapter adapter = mAdapter.get();
             if (adapter == null) return;
+
+            // Queue up work that we need to do for the callback to run
             adapter.mWorkerQueue.post(new Runnable() {
                 @Override
                 public void run() {
-                    // Call back to the service to notify that the data set changed
-                    if (adapter.mServiceConnection.isConnected()) {
+                    if (adapter.mNotifyDataSetChangedAfterOnServiceConnected) {
+                        // Handle queued notifyDataSetChanged() if necessary
+                        adapter.onNotifyDataSetChanged();
+                    } else {
                         IRemoteViewsFactory factory =
                             adapter.mServiceConnection.getRemoteViewsFactory();
                         try {
-                            // call back to the factory
-                            factory.onDataSetChanged();
+                            if (!factory.isCreated()) {
+                                // We only call onDataSetChanged() if this is the factory was just
+                                // create in response to this bind
+                                factory.onDataSetChanged();
+                            }
                         } catch (Exception e) {
                             Log.e(TAG, "Error notifying factory of data set changed in " +
                                         "onServiceConnected(): " + e.getMessage());
-                            e.printStackTrace();
 
                             // Return early to prevent anything further from being notified
                             // (effectively nothing has changed)
@@ -130,13 +168,16 @@
 
                         // Request meta data so that we have up to date data when calling back to
                         // the remote adapter callback
-                        adapter.updateMetaData();
+                        adapter.updateTemporaryMetaData();
 
-                        // Post a runnable to call back to the view to notify it that we have
-                        // connected
+                        // Notify the host that we've connected
                         adapter.mMainQueue.post(new Runnable() {
                             @Override
                             public void run() {
+                                synchronized (adapter.mCache) {
+                                    adapter.mCache.commitTemporaryMetaData();
+                                }
+
                                 final RemoteAdapterConnectionCallback callback =
                                     adapter.mCallback.get();
                                 if (callback != null) {
@@ -145,35 +186,44 @@
                             }
                         });
                     }
+
+                    // Enqueue unbind message
+                    adapter.enqueueDeferredUnbindServiceMessage();
+                    mIsConnected = true;
+                    mIsConnecting = false;
                 }
             });
         }
 
-        public void onServiceDisconnected() {
-            mConnected = false;
+        public synchronized void onServiceDisconnected() {
+            mIsConnected = false;
+            mIsConnecting = false;
             mRemoteViewsFactory = null;
 
+            // Clear the main/worker queues
             final RemoteViewsAdapter adapter = mAdapter.get();
             if (adapter == null) return;
             
-            // Clear the main/worker queues
-            adapter.mMainQueue.removeMessages(sUnbindServiceMessageType);
-            adapter.mMainQueue.removeMessages(sDefaultMessageType);
-            adapter.mWorkerQueue.removeMessages(sDefaultMessageType);
+            adapter.mMainQueue.post(new Runnable() {
+                @Override
+                public void run() {
+                    // Dequeue any unbind messages
+                    adapter.mMainQueue.removeMessages(sUnbindServiceMessageType);
 
-            final RemoteAdapterConnectionCallback callback = adapter.mCallback.get();
-            if (callback != null) {
-                callback.onRemoteAdapterDisconnected();
-            }
-            adapter.mCache.reset();
+                    final RemoteAdapterConnectionCallback callback = adapter.mCallback.get();
+                    if (callback != null) {
+                        callback.onRemoteAdapterDisconnected();
+                    }
+                }
+            });
         }
 
-        public IRemoteViewsFactory getRemoteViewsFactory() {
+        public synchronized IRemoteViewsFactory getRemoteViewsFactory() {
             return mRemoteViewsFactory;
         }
 
-        public boolean isConnected() {
-            return mConnected;
+        public synchronized boolean isConnected() {
+            return mIsConnected;
         }
     }
 
@@ -270,7 +320,6 @@
         int count;
         int viewTypeCount;
         boolean hasStableIds;
-        boolean isDataDirty;
 
         // Used to determine how to construct loading views.  If a loading view is not specified
         // by the user, then we try and load the first view, and use its height as the height for
@@ -280,22 +329,31 @@
         int mFirstViewHeight;
 
         // A mapping from type id to a set of unique type ids
-        private Map<Integer, Integer> mTypeIdIndexMap;
+        private final HashMap<Integer, Integer> mTypeIdIndexMap = new HashMap<Integer, Integer>();
 
         public RemoteViewsMetaData() {
             reset();
         }
 
+        public void set(RemoteViewsMetaData d) {
+            synchronized (d) {
+                count = d.count;
+                viewTypeCount = d.viewTypeCount;
+                hasStableIds = d.hasStableIds;
+                setLoadingViewTemplates(d.mUserLoadingView, d.mFirstView);
+            }
+        }
+
         public void reset() {
             count = 0;
+
             // by default there is at least one dummy view type
             viewTypeCount = 1;
             hasStableIds = true;
-            isDataDirty = false;
             mUserLoadingView = null;
             mFirstView = null;
             mFirstViewHeight = 0;
-            mTypeIdIndexMap = new HashMap<Integer, Integer>();
+            mTypeIdIndexMap.clear();
         }
 
         public void setLoadingViewTemplates(RemoteViews loadingView, RemoteViews firstView) {
@@ -385,6 +443,7 @@
 
         // The meta data related to all the RemoteViews, ie. count, is stable, etc.
         private RemoteViewsMetaData mMetaData;
+        private RemoteViewsMetaData mTemporaryMetaData;
 
         // The cache/mapping of position to RemoteViewsMetaData.  This set is guaranteed to be
         // greater than or equal to the set of RemoteViews.
@@ -426,6 +485,7 @@
             mPreloadLowerBound = 0;
             mPreloadUpperBound = -1;
             mMetaData = new RemoteViewsMetaData();
+            mTemporaryMetaData = new RemoteViewsMetaData();
             mIndexMetaData = new HashMap<Integer, RemoteViewsIndexMetaData>();
             mIndexRemoteViews = new HashMap<Integer, RemoteViews>();
             mRequestedIndices = new HashSet<Integer>();
@@ -461,6 +521,9 @@
         public RemoteViewsMetaData getMetaData() {
             return mMetaData;
         }
+        public RemoteViewsMetaData getTemporaryMetaData() {
+            return mTemporaryMetaData;
+        }
         public RemoteViews getRemoteViewsAt(int position) {
             if (mIndexRemoteViews.containsKey(position)) {
                 return mIndexRemoteViews.get(position);
@@ -474,6 +537,14 @@
             return null;
         }
 
+        public void commitTemporaryMetaData() {
+            synchronized (mTemporaryMetaData) {
+                synchronized (mMetaData) {
+                    mMetaData.set(mTemporaryMetaData);
+                }
+            }
+        }
+
         private int getRemoteViewsBitmapMemoryUsage() {
             // Calculate the memory usage of all the RemoteViews bitmaps being cached
             int mem = 0;
@@ -505,12 +576,12 @@
                 mLoadIndices.add(position);
             }
         }
-        public void queuePositionsToBePreloadedFromRequestedPosition(int position) {
+        public boolean queuePositionsToBePreloadedFromRequestedPosition(int position) {
             // Check if we need to preload any items
             if (mPreloadLowerBound <= position && position <= mPreloadUpperBound) {
                 int center = (mPreloadUpperBound + mPreloadLowerBound) / 2;
                 if (Math.abs(position - center) < mMaxCountSlack) {
-                    return;
+                    return false;
                 }
             }
 
@@ -537,6 +608,7 @@
                 // But remove all the indices that have already been loaded and are cached
                 mLoadIndices.removeAll(mIndexRemoteViews.keySet());
             }
+            return true;
         }
         public int getNextIndexToLoad() {
             // We try and prioritize items that have been requested directly, instead
@@ -616,100 +688,114 @@
         mWorkerQueue.post(new Runnable() {
             @Override
             public void run() {
-                // Get the next index to load
-                int position = -1;
-                synchronized (mCache) {
-                    position = mCache.getNextIndexToLoad();
-                }
-                if (position > -1) {
-                    // Load the item, and notify any existing RemoteViewsFrameLayouts
-                    updateRemoteViews(position);
+                if (mServiceConnection.isConnected()) {
+                    // Get the next index to load
+                    int position = -1;
+                    synchronized (mCache) {
+                        position = mCache.getNextIndexToLoad();
+                    }
+                    if (position > -1) {
+                        // Load the item, and notify any existing RemoteViewsFrameLayouts
+                        updateRemoteViews(position);
 
-                    // Queue up for the next one to load
-                    loadNextIndexInBackground();
+                        // Queue up for the next one to load
+                        loadNextIndexInBackground();
+                    } else {
+                        // No more items to load, so queue unbind
+                        enqueueDeferredUnbindServiceMessage();
+                    }
                 }
             }
         });
     }
 
-    private void updateMetaData() {
-        if (mServiceConnection.isConnected()) {
-            try {
-                IRemoteViewsFactory factory = mServiceConnection.getRemoteViewsFactory();
+    private void processException(String method, Exception e) {
+        Log.e("RemoteViewsAdapter", "Error in " + method + ": " + e.getMessage());
 
-                // get the properties/first view (so that we can use it to
-                // measure our dummy views)
-                boolean hasStableIds = factory.hasStableIds();
-                int viewTypeCount = factory.getViewTypeCount();
-                int count = factory.getCount();
-                RemoteViews loadingView = factory.getLoadingView();
-                RemoteViews firstView = null;
-                if ((count > 0) && (loadingView == null)) {
-                    firstView = factory.getViewAt(0);
-                }
-                final RemoteViewsMetaData metaData = mCache.getMetaData();
-                synchronized (metaData) {
-                    metaData.hasStableIds = hasStableIds;
-                    metaData.viewTypeCount = viewTypeCount + 1;
-                    metaData.count = count;
-                    metaData.setLoadingViewTemplates(loadingView, firstView);
-                }
-            } catch (Exception e) {
-                // print the error
-                Log.e(TAG, "Error in requestMetaData(): " + e.getMessage());
-
-                // reset any members after the failed call
-                final RemoteViewsMetaData metaData = mCache.getMetaData();
-                synchronized (metaData) {
-                    metaData.reset();
-                }
+        // If we encounter a crash when updating, we should reset the metadata & cache and trigger
+        // a notifyDataSetChanged to update the widget accordingly
+        final RemoteViewsMetaData metaData = mCache.getMetaData();
+        synchronized (metaData) {
+            metaData.reset();
+        }
+        synchronized (mCache) {
+            mCache.reset();
+        }
+        mMainQueue.post(new Runnable() {
+            @Override
+            public void run() {
+                superNotifyDataSetChanged();
             }
+        });
+    }
+
+    private void updateTemporaryMetaData() {
+        IRemoteViewsFactory factory = mServiceConnection.getRemoteViewsFactory();
+
+        try {
+            // get the properties/first view (so that we can use it to
+            // measure our dummy views)
+            boolean hasStableIds = factory.hasStableIds();
+            int viewTypeCount = factory.getViewTypeCount();
+            int count = factory.getCount();
+            RemoteViews loadingView = factory.getLoadingView();
+            RemoteViews firstView = null;
+            if ((count > 0) && (loadingView == null)) {
+                firstView = factory.getViewAt(0);
+            }
+            final RemoteViewsMetaData tmpMetaData = mCache.getTemporaryMetaData();
+            synchronized (tmpMetaData) {
+                tmpMetaData.hasStableIds = hasStableIds;
+                // We +1 because the base view type is the loading view
+                tmpMetaData.viewTypeCount = viewTypeCount + 1;
+                tmpMetaData.count = count;
+                tmpMetaData.setLoadingViewTemplates(loadingView, firstView);
+            }
+        } catch (Exception e) {
+            processException("updateMetaData", e);
         }
     }
 
     private void updateRemoteViews(final int position) {
-        if (mServiceConnection.isConnected()) {
-            IRemoteViewsFactory factory = mServiceConnection.getRemoteViewsFactory();
+        if (!mServiceConnection.isConnected()) return;
+        IRemoteViewsFactory factory = mServiceConnection.getRemoteViewsFactory();
 
-            // Load the item information from the remote service
-            RemoteViews remoteViews = null;
-            long itemId = 0;
-            try {
-                remoteViews = factory.getViewAt(position);
-                itemId = factory.getItemId(position);
-            } catch (Throwable t) {
-                Log.e(TAG, "Error in updateRemoteViews(" + position + "): " + t.getMessage());
-                t.printStackTrace();
+        // Load the item information from the remote service
+        RemoteViews remoteViews = null;
+        long itemId = 0;
+        try {
+            remoteViews = factory.getViewAt(position);
+            itemId = factory.getItemId(position);
+        } catch (Exception e) {
+            Log.e(TAG, "Error in updateRemoteViews(" + position + "): " + e.getMessage());
 
-                // Return early to prevent additional work in re-centering the view cache, and
-                // swapping from the loading view
-                return;
-            }
+            // Return early to prevent additional work in re-centering the view cache, and
+            // swapping from the loading view
+            return;
+        }
 
-            if (remoteViews == null) {
-                // If a null view was returned, we break early to prevent it from getting
-                // into our cache and causing problems later. The effect is that the child  at this
-                // position will remain as a loading view until it is updated.
-                Log.e(TAG, "Error in updateRemoteViews(" + position + "): " + " null RemoteViews " +
-                        "returned from RemoteViewsFactory.");
-                return;
-            }
-            synchronized (mCache) {
-                // Cache the RemoteViews we loaded
-                mCache.insert(position, remoteViews, itemId);
+        if (remoteViews == null) {
+            // If a null view was returned, we break early to prevent it from getting
+            // into our cache and causing problems later. The effect is that the child  at this
+            // position will remain as a loading view until it is updated.
+            Log.e(TAG, "Error in updateRemoteViews(" + position + "): " + " null RemoteViews " +
+                    "returned from RemoteViewsFactory.");
+            return;
+        }
+        synchronized (mCache) {
+            // Cache the RemoteViews we loaded
+            mCache.insert(position, remoteViews, itemId);
 
-                // Notify all the views that we have previously returned for this index that
-                // there is new data for it.
-                final RemoteViews rv = remoteViews;
-                final int typeId = mCache.getMetaDataAt(position).typeId;
-                mMainQueue.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        mRequestedViews.notifyOnRemoteViewsLoaded(position, rv, typeId);
-                        enqueueDeferredUnbindServiceMessage();
-                    }
-                });
-            }
+            // Notify all the views that we have previously returned for this index that
+            // there is new data for it.
+            final RemoteViews rv = remoteViews;
+            final int typeId = mCache.getMetaDataAt(position).typeId;
+            mMainQueue.post(new Runnable() {
+                @Override
+                public void run() {
+                    mRequestedViews.notifyOnRemoteViewsLoaded(position, rv, typeId);
+                }
+            });
         }
     }
 
@@ -718,7 +804,6 @@
     }
 
     public int getCount() {
-        requestBindService();
         final RemoteViewsMetaData metaData = mCache.getMetaData();
         synchronized (metaData) {
             return metaData.count;
@@ -731,7 +816,6 @@
     }
 
     public long getItemId(int position) {
-        requestBindService();
         synchronized (mCache) {
             if (mCache.containsMetaDataAt(position)) {
                 return mCache.getMetaDataAt(position).itemId;
@@ -741,7 +825,6 @@
     }
 
     public int getItemViewType(int position) {
-        requestBindService();
         int typeId = 0;
         synchronized (mCache) {
             if (mCache.containsMetaDataAt(position)) {
@@ -773,13 +856,23 @@
     }
 
     public View getView(int position, View convertView, ViewGroup parent) {
-        requestBindService();
-        if (mServiceConnection.isConnected()) {
-            // "Request" an index so that we can queue it for loading, initiate subsequent
-            // preloading, etc.
-            synchronized (mCache) {
+        // "Request" an index so that we can queue it for loading, initiate subsequent
+        // preloading, etc.
+        synchronized (mCache) {
+            boolean isInCache = mCache.containsRemoteViewAt(position);
+            boolean isConnected = mServiceConnection.isConnected();
+            boolean hasNewItems = false;
+
+            if (!isConnected) {
+                // Requesting bind service will trigger a super.notifyDataSetChanged(), which will
+                // in turn trigger another request to getView()
+                requestBindService();
+            } else {
                 // Queue up other indices to be preloaded based on this position
-                mCache.queuePositionsToBePreloadedFromRequestedPosition(position);
+                hasNewItems = mCache.queuePositionsToBePreloadedFromRequestedPosition(position);
+            }
+
+            if (isInCache) {
                 View convertViewChild = null;
                 int convertViewTypeId = 0;
                 RemoteViewsFrameLayout layout = null;
@@ -792,51 +885,47 @@
 
                 // Second, we try and retrieve the RemoteViews from the cache, returning a loading
                 // view and queueing it to be loaded if it has not already been loaded.
-                if (mCache.containsRemoteViewAt(position)) {
-                    Context context = parent.getContext();
-                    RemoteViews rv = mCache.getRemoteViewsAt(position);
-                    int typeId = mCache.getMetaDataAt(position).typeId;
+                Context context = parent.getContext();
+                RemoteViews rv = mCache.getRemoteViewsAt(position);
+                int typeId = mCache.getMetaDataAt(position).typeId;
 
-                    // Reuse the convert view where possible
-                    if (layout != null) {
-                        if (convertViewTypeId == typeId) {
-                            rv.reapply(context, convertViewChild);
-                            return layout;
-                        }
+                // Reuse the convert view where possible
+                if (layout != null) {
+                    if (convertViewTypeId == typeId) {
+                        rv.reapply(context, convertViewChild);
+                        return layout;
                     }
-
-                    // Otherwise, create a new view to be returned
-                    View newView = rv.apply(context, parent);
-                    newView.setTagInternal(com.android.internal.R.id.rowTypeId, new Integer(typeId));
-                    if (layout != null) {
-                        layout.removeAllViews();
-                    } else {
-                        layout = new RemoteViewsFrameLayout(context);
-                    }
-                    layout.addView(newView);
-                    return layout;
+                    layout.removeAllViews();
                 } else {
-                    // If the cache does not have the RemoteViews at this position, then create a
-                    // loading view and queue the actual position to be loaded in the background
-                    RemoteViewsFrameLayout loadingView = null;
-                    final RemoteViewsMetaData metaData = mCache.getMetaData();
-                    synchronized (metaData) {
-                        loadingView = metaData.createLoadingView(position, convertView, parent);
-                    }
-
-                    mRequestedViews.add(position, loadingView);
-                    mCache.queueRequestedPositionToLoad(position);
-                    loadNextIndexInBackground();
-
-                    return loadingView;
+                    layout = new RemoteViewsFrameLayout(context);
                 }
+
+                // Otherwise, create a new view to be returned
+                View newView = rv.apply(context, parent);
+                newView.setTagInternal(com.android.internal.R.id.rowTypeId, new Integer(typeId));
+                layout.addView(newView);
+                if (hasNewItems) loadNextIndexInBackground();
+
+                return layout;
+            } else {
+                // If the cache does not have the RemoteViews at this position, then create a
+                // loading view and queue the actual position to be loaded in the background
+                RemoteViewsFrameLayout loadingView = null;
+                final RemoteViewsMetaData metaData = mCache.getMetaData();
+                synchronized (metaData) {
+                    loadingView = metaData.createLoadingView(position, convertView, parent);
+                }
+
+                mRequestedViews.add(position, loadingView);
+                mCache.queueRequestedPositionToLoad(position);
+                loadNextIndexInBackground();
+
+                return loadingView;
             }
         }
-        return new View(parent.getContext());
     }
 
     public int getViewTypeCount() {
-        requestBindService();
         final RemoteViewsMetaData metaData = mCache.getMetaData();
         synchronized (metaData) {
             return metaData.viewTypeCount;
@@ -844,7 +933,6 @@
     }
 
     public boolean hasStableIds() {
-        requestBindService();
         final RemoteViewsMetaData metaData = mCache.getMetaData();
         synchronized (metaData) {
             return metaData.hasStableIds;
@@ -855,44 +943,67 @@
         return getCount() <= 0;
     }
 
-    public void notifyDataSetChanged() {
-        mWorkerQueue.post(new Runnable() {
+
+    private void onNotifyDataSetChanged() {
+        // Complete the actual notifyDataSetChanged() call initiated earlier
+        IRemoteViewsFactory factory = mServiceConnection.getRemoteViewsFactory();
+        try {
+            factory.onDataSetChanged();
+        } catch (Exception e) {
+            Log.e(TAG, "Error in updateNotifyDataSetChanged(): " + e.getMessage());
+
+            // Return early to prevent from further being notified (since nothing has
+            // changed)
+            return;
+        }
+
+        // Flush the cache so that we can reload new items from the service
+        synchronized (mCache) {
+            mCache.reset();
+        }
+
+        // Re-request the new metadata (only after the notification to the factory)
+        updateTemporaryMetaData();
+
+        // Propagate the notification back to the base adapter
+        mMainQueue.post(new Runnable() {
             @Override
             public void run() {
-                // Complete the actual notifyDataSetChanged() call initiated earlier
-                if (mServiceConnection.isConnected()) {
-                    IRemoteViewsFactory factory = mServiceConnection.getRemoteViewsFactory();
-                    try {
-                        factory.onDataSetChanged();
-                    } catch (Exception e) {
-                        Log.e(TAG, "Error in updateNotifyDataSetChanged(): " + e.getMessage());
-
-                        // Return early to prevent from further being notified (since nothing has
-                        // changed)
-                        return;
-                    }
-                }
-
-                // Flush the cache so that we can reload new items from the service
                 synchronized (mCache) {
-                    mCache.reset();
+                    mCache.commitTemporaryMetaData();
                 }
 
-                // Re-request the new metadata (only after the notification to the factory)
-                updateMetaData();
-
-                // Propagate the notification back to the base adapter
-                mMainQueue.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        superNotifyDataSetChanged();
-                    }
-                });
+                superNotifyDataSetChanged();
+                enqueueDeferredUnbindServiceMessage();
             }
         });
 
-        // Note: we do not call super.notifyDataSetChanged() until the RemoteViewsFactory has had
-        // a chance to update itself and return new meta data associated with the new data.
+        // Reset the notify flagflag
+        mNotifyDataSetChangedAfterOnServiceConnected = false;
+    }
+
+    public void notifyDataSetChanged() {
+        // Dequeue any unbind messages
+        mMainQueue.removeMessages(sUnbindServiceMessageType);
+
+        // If we are not connected, queue up the notifyDataSetChanged to be handled when we do
+        // connect
+        if (!mServiceConnection.isConnected()) {
+            if (mNotifyDataSetChangedAfterOnServiceConnected) {
+                return;
+            }
+
+            mNotifyDataSetChangedAfterOnServiceConnected = true;
+            requestBindService();
+            return;
+        }
+
+        mWorkerQueue.post(new Runnable() {
+            @Override
+            public void run() {
+                onNotifyDataSetChanged();
+            }
+        });
     }
 
     void superNotifyDataSetChanged() {
@@ -904,9 +1015,8 @@
         boolean result = false;
         switch (msg.what) {
         case sUnbindServiceMessageType:
-            final AppWidgetManager mgr = AppWidgetManager.getInstance(mContext);
             if (mServiceConnection.isConnected()) {
-                mgr.unbindRemoteViewsService(mAppWidgetId, mIntent);
+                mServiceConnection.unbind(mContext, mAppWidgetId, mIntent);
             }
             result = true;
             break;
@@ -917,20 +1027,19 @@
     }
 
     private void enqueueDeferredUnbindServiceMessage() {
-        /* Temporarily disable delayed service unbinding
         // Remove any existing deferred-unbind messages
         mMainQueue.removeMessages(sUnbindServiceMessageType);
         mMainQueue.sendEmptyMessageDelayed(sUnbindServiceMessageType, sUnbindServiceDelay);
-        */
     }
 
     private boolean requestBindService() {
         // Try binding the service (which will start it if it's not already running)
         if (!mServiceConnection.isConnected()) {
-            final AppWidgetManager mgr = AppWidgetManager.getInstance(mContext);
-            mgr.bindRemoteViewsService(mAppWidgetId, mIntent, mServiceConnection.asBinder());
+            mServiceConnection.bind(mContext, mAppWidgetId, mIntent);
         }
 
+        // Remove any existing deferred-unbind messages
+        mMainQueue.removeMessages(sUnbindServiceMessageType);
         return mServiceConnection.isConnected();
     }
 }
diff --git a/core/java/android/widget/RemoteViewsService.java b/core/java/android/widget/RemoteViewsService.java
index e5a3de2..fb2c416 100644
--- a/core/java/android/widget/RemoteViewsService.java
+++ b/core/java/android/widget/RemoteViewsService.java
@@ -17,11 +17,11 @@
 package android.widget;
 
 import java.util.HashMap;
-import java.util.Map;
 
 import android.app.Service;
 import android.content.Intent;
 import android.os.IBinder;
+import android.util.Log;
 import android.util.Pair;
 
 import com.android.internal.widget.IRemoteViewsFactory;
@@ -35,8 +35,13 @@
 
     private static final String LOG_TAG = "RemoteViewsService";
 
-    // multimap implementation for reference counting
-    private HashMap<Intent.FilterComparison, Pair<RemoteViewsFactory, Integer>> mRemoteViewFactories;
+    // Used for reference counting of RemoteViewsFactories
+    // Because we are now unbinding when we are not using the Service (to allow them to be
+    // reclaimed), the references to the factories that are created need to be stored and used when
+    // the service is restarted (in response to user input for example).  When the process is
+    // destroyed, so is this static cache of RemoteViewsFactories.
+    private static final HashMap<Intent.FilterComparison, RemoteViewsFactory> mRemoteViewFactories =
+            new HashMap<Intent.FilterComparison, RemoteViewsFactory>();
     private final Object mLock = new Object();
 
     /**
@@ -126,9 +131,13 @@
      * A private proxy class for the private IRemoteViewsFactory interface through the
      * public RemoteViewsFactory interface.
      */
-    private class RemoteViewsFactoryAdapter extends IRemoteViewsFactory.Stub {
-        public RemoteViewsFactoryAdapter(RemoteViewsFactory factory) {
+    private static class RemoteViewsFactoryAdapter extends IRemoteViewsFactory.Stub {
+        public RemoteViewsFactoryAdapter(RemoteViewsFactory factory, boolean isCreated) {
             mFactory = factory;
+            mIsCreated = isCreated;
+        }
+        public synchronized boolean isCreated() {
+            return mIsCreated;
         }
         public synchronized void onDataSetChanged() {
             mFactory.onDataSetChanged();
@@ -155,58 +164,28 @@
         }
 
         private RemoteViewsFactory mFactory;
-    }
-
-    public RemoteViewsService() {
-        mRemoteViewFactories =
-                new HashMap<Intent.FilterComparison, Pair<RemoteViewsFactory, Integer>>();
+        private boolean mIsCreated;
     }
 
     @Override
     public IBinder onBind(Intent intent) {
         synchronized (mLock) {
-            // increment the reference count to the particular factory associated with this intent
             Intent.FilterComparison fc = new Intent.FilterComparison(intent);
-            Pair<RemoteViewsFactory, Integer> factoryRef = null;
             RemoteViewsFactory factory = null;
+            boolean isCreated = false;
             if (!mRemoteViewFactories.containsKey(fc)) {
                 factory = onGetViewFactory(intent);
-                factoryRef = new Pair<RemoteViewsFactory, Integer>(factory, 1);
-                mRemoteViewFactories.put(fc, factoryRef);
+                mRemoteViewFactories.put(fc, factory);
                 factory.onCreate();
+                isCreated = false;
             } else {
-                Pair<RemoteViewsFactory, Integer> oldFactoryRef = mRemoteViewFactories.get(fc);
-                factory = oldFactoryRef.first;
-                int newRefCount = oldFactoryRef.second.intValue() + 1;
-                factoryRef = new Pair<RemoteViewsFactory, Integer>(oldFactoryRef.first, newRefCount);
-                mRemoteViewFactories.put(fc, factoryRef);
+                factory = mRemoteViewFactories.get(fc);
+                isCreated = true;
             }
-            return new RemoteViewsFactoryAdapter(factory);
+            return new RemoteViewsFactoryAdapter(factory, isCreated);
         }
     }
 
-    @Override
-    public boolean onUnbind(Intent intent) {
-        synchronized (mLock) {
-            Intent.FilterComparison fc = new Intent.FilterComparison(intent);
-            if (mRemoteViewFactories.containsKey(fc)) {
-                // this alleviates the user's responsibility of having to clear all factories
-                Pair<RemoteViewsFactory, Integer> oldFactoryRef =
-                        mRemoteViewFactories.get(fc);
-                int newRefCount = oldFactoryRef.second.intValue() - 1;
-                if (newRefCount <= 0) {
-                    oldFactoryRef.first.onDestroy();
-                    mRemoteViewFactories.remove(fc);
-                } else {
-                    Pair<RemoteViewsFactory, Integer> factoryRef =
-                            new Pair<RemoteViewsFactory, Integer>(oldFactoryRef.first, newRefCount);
-                    mRemoteViewFactories.put(fc, factoryRef);
-                }
-            }
-        }
-        return super.onUnbind(intent);
-    }
-
     /**
      * To be implemented by the derived service to generate appropriate factories for
      * the data.
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index fedda68..54d7021 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -3508,6 +3508,8 @@
     private static class ErrorPopup extends PopupWindow {
         private boolean mAbove = false;
         private final TextView mView;
+        private int mPopupInlineErrorBackgroundId = 0;
+        private int mPopupInlineErrorAboveBackgroundId = 0;
 
         ErrorPopup(TextView v, int width, int height) {
             super(v, width, height);
@@ -3518,10 +3520,23 @@
             mAbove = above;
 
             if (above) {
-                mView.setBackgroundResource(com.android.internal.R.drawable.popup_inline_error_above);
+                mPopupInlineErrorAboveBackgroundId =
+                    getResourceId(mPopupInlineErrorAboveBackgroundId, com.android.internal.R.styleable.Theme_errorMessageAboveBackground);
             } else {
-                mView.setBackgroundResource(com.android.internal.R.drawable.popup_inline_error);
+                mPopupInlineErrorBackgroundId =
+                    getResourceId(mPopupInlineErrorBackgroundId, com.android.internal.R.styleable.Theme_errorMessageBackground);
             }
+
+            mView.setBackgroundResource(above ? mPopupInlineErrorAboveBackgroundId : mPopupInlineErrorBackgroundId);
+        }
+
+        private int getResourceId(int currentId, int index) {
+            if (currentId == 0) {
+                TypedArray styledAttributes = mView.getContext().obtainStyledAttributes(R.styleable.Theme);
+                currentId = styledAttributes.getResourceId(index, 0);
+                styledAttributes.recycle();
+            }
+            return currentId;
         }
 
         @Override
diff --git a/core/java/com/android/internal/widget/IRemoteViewsFactory.aidl b/core/java/com/android/internal/widget/IRemoteViewsFactory.aidl
index ae9900c..60eca00 100644
--- a/core/java/com/android/internal/widget/IRemoteViewsFactory.aidl
+++ b/core/java/com/android/internal/widget/IRemoteViewsFactory.aidl
@@ -27,5 +27,6 @@
     int getViewTypeCount();
     long getItemId(int position);
     boolean hasStableIds();
+    boolean isCreated();
 }
 
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index 9de270d..7a609a5 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -137,21 +137,11 @@
     renderer->finish();
 }
 
-static void android_view_GLES20Canvas_acquireContext(JNIEnv* env, jobject clazz,
-        OpenGLRenderer* renderer) {
-    renderer->acquireContext();
-}
-
 static bool android_view_GLES20Canvas_callDrawGLFunction(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, Functor *functor) {
     return renderer->callDrawGLFunction(functor);
 }
 
-static void android_view_GLES20Canvas_releaseContext(JNIEnv* env, jobject clazz,
-        OpenGLRenderer* renderer) {
-    renderer->releaseContext();
-}
-
 // ----------------------------------------------------------------------------
 // State
 // ----------------------------------------------------------------------------
@@ -609,8 +599,6 @@
     { "nPrepare",           "(IZ)V",           (void*) android_view_GLES20Canvas_prepare },
     { "nPrepareDirty",      "(IIIIIZ)V",       (void*) android_view_GLES20Canvas_prepareDirty },
     { "nFinish",            "(I)V",            (void*) android_view_GLES20Canvas_finish },
-    { "nAcquireContext",    "(I)V",            (void*) android_view_GLES20Canvas_acquireContext },
-    { "nReleaseContext",    "(I)V",            (void*) android_view_GLES20Canvas_releaseContext },
 
     { "nCallDrawGLFunction", "(II)Z",
             (void*) android_view_GLES20Canvas_callDrawGLFunction },
diff --git a/core/res/res/drawable-mdpi/popup_inline_error_above_holo_dark.9.png b/core/res/res/drawable-mdpi/popup_inline_error_above_holo_dark.9.png
new file mode 100644
index 0000000..dd4af6d
--- /dev/null
+++ b/core/res/res/drawable-mdpi/popup_inline_error_above_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/popup_inline_error_above_holo_light.9.png b/core/res/res/drawable-mdpi/popup_inline_error_above_holo_light.9.png
new file mode 100644
index 0000000..8925112
--- /dev/null
+++ b/core/res/res/drawable-mdpi/popup_inline_error_above_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/popup_inline_error_holo_dark.9.png b/core/res/res/drawable-mdpi/popup_inline_error_holo_dark.9.png
new file mode 100755
index 0000000..66c2c09
--- /dev/null
+++ b/core/res/res/drawable-mdpi/popup_inline_error_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/popup_inline_error_holo_light.9.png b/core/res/res/drawable-mdpi/popup_inline_error_holo_light.9.png
new file mode 100755
index 0000000..c5113f2
--- /dev/null
+++ b/core/res/res/drawable-mdpi/popup_inline_error_holo_light.9.png
Binary files differ
diff --git a/core/res/res/layout/textview_hint.xml b/core/res/res/layout/textview_hint.xml
index 20b08bf..f9c4406 100644
--- a/core/res/res/layout/textview_hint.xml
+++ b/core/res/res/layout/textview_hint.xml
@@ -17,7 +17,6 @@
 <TextView xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:background="@drawable/popup_inline_error"
     android:textAppearance="?android:attr/textAppearanceSmall"
     android:textColor="@color/primary_text_light"
 />
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 260c7c6..4a56532 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -142,6 +142,11 @@
         <!-- EditText background drawable. -->
         <attr name="editTextBackground" format="reference" />
 
+        <!-- Popup text displayed in TextView when setError is used. -->
+        <attr name="errorMessageBackground" format="reference" />
+        <!-- Background used instead of errorMessageBackground when the popup has to be above. -->
+        <attr name="errorMessageAboveBackground" format="reference" />
+
         <!-- A styled string, specifying the style to be used for showing
              inline candidate text when composing with an input method.  The
              text itself will be ignored, but the style spans will be applied
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index ddaeb82..c5ae77f 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -217,6 +217,8 @@
         <item name="starStyle">@android:style/Widget.CompoundButton.Star</item>
         <item name="tabWidgetStyle">@android:style/Widget.TabWidget</item>
         <item name="textViewStyle">@android:style/Widget.TextView</item>
+        <item name="errorMessageBackground">@android:drawable/popup_inline_error</item>
+        <item name="errorMessageAboveBackground">@android:drawable/popup_inline_error_above</item>
         <item name="webTextViewStyle">@android:style/Widget.WebTextView</item>
         <item name="webViewStyle">@android:style/Widget.WebView</item>
         <item name="dropDownItemStyle">@android:style/Widget.DropDownItem</item>
@@ -934,6 +936,8 @@
         <item name="starStyle">@android:style/Widget.Holo.CompoundButton.Star</item>
         <item name="tabWidgetStyle">@android:style/Widget.Holo.TabWidget</item>
         <item name="textViewStyle">@android:style/Widget.Holo.TextView</item>
+        <item name="errorMessageBackground">@android:drawable/popup_inline_error_holo_dark</item>
+        <item name="errorMessageAboveBackground">@android:drawable/popup_inline_error_above_holo_dark</item>
         <item name="webTextViewStyle">@android:style/Widget.Holo.WebTextView</item>
         <item name="webViewStyle">@android:style/Widget.Holo.WebView</item>
         <item name="dropDownItemStyle">@android:style/Widget.Holo.DropDownItem</item>
@@ -1207,6 +1211,8 @@
         <item name="starStyle">@android:style/Widget.Holo.Light.CompoundButton.Star</item>
         <item name="tabWidgetStyle">@android:style/Widget.Holo.Light.TabWidget</item>
         <item name="textViewStyle">@android:style/Widget.Holo.Light.TextView</item>
+        <item name="errorMessageBackground">@android:drawable/popup_inline_error_holo_light</item>
+        <item name="errorMessageAboveBackground">@android:drawable/popup_inline_error_above_holo_light</item>
         <item name="webTextViewStyle">@android:style/Widget.Holo.Light.WebTextView</item>
         <item name="webViewStyle">@android:style/Widget.Holo.Light.WebView</item>
         <item name="dropDownItemStyle">@android:style/Widget.Holo.Light.DropDownItem</item>
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index 00b06e0..c1deed3 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -1596,51 +1596,6 @@
     }
 
     /**
-     * <p>Acquires the Canvas context. After invoking this method, the Canvas
-     * context  can be modified by the caller. For instance, if you acquire
-     * the context of an OpenGL Canvas you can reset the GL viewport, scissor,
-     * etc.</p>
-     * 
-     * <p>A call to {@link #acquireContext()} should aways be followed by
-     * a call to {@link #releaseContext()}, preferrably using a try block:</p>
-     * 
-     * <pre>
-     * try {
-     *     if (canvas.acquireContext()) {
-     *         // Use the canvas and/or its context
-     *     }
-     * } finally {
-     *     canvas.releaseContext();
-     * }
-     * </pre>
-     * 
-     * <p>Acquiring the context can be an expensive operation and should not
-     * be done unless absolutely necessary.</p>
-     * 
-     * <p>Applications should never invoke this method directly.</p>
-     * 
-     * @return True if the context could be acquired successfully, false
-     *         otherwise (if the context is already acquired for instance.)
-     * 
-     * @see #releaseContext() 
-     * 
-     * @hide
-     */
-    public boolean acquireContext() {
-        return false;
-    }
-
-    /**
-     * <p>Release the context acquired with {@link #acquireContext()}.</p>
-     * 
-     * @see #acquireContext() 
-     * 
-     * @hide
-     */
-    public void releaseContext() {
-    }
-
-    /**
      * Free up as much memory as possible from private caches (e.g. fonts, images)
      *
      * @hide
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index c2106d4..cfc853c 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -82,8 +82,6 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 const char* DisplayList::OP_NAMES[] = {
-    "AcquireContext",
-    "ReleaseContext",
     "Save",
     "Restore",
     "RestoreToCount",
@@ -239,16 +237,6 @@
                 needsInvalidate |= renderer.callDrawGLFunction(functor);
             }
             break;
-            case AcquireContext: {
-                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
-                renderer.acquireContext();
-            }
-            break;
-            case ReleaseContext: {
-                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
-                renderer.releaseContext();
-            }
-            break;
             case Save: {
                 int rendererNum = getInt();
                 DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, OP_NAMES[op], rendererNum);
@@ -644,15 +632,9 @@
 }
 
 void DisplayListRenderer::interrupt() {
-
 }
+
 void DisplayListRenderer::resume() {
-
-}
-void DisplayListRenderer::acquireContext() {
-    // TODO: probably noop instead of calling super
-    addOp(DisplayList::AcquireContext);
-    OpenGLRenderer::acquireContext();
 }
 
 bool DisplayListRenderer::callDrawGLFunction(Functor *functor) {
@@ -661,12 +643,6 @@
     return false; // No invalidate needed at record-time
 }
 
-void DisplayListRenderer::releaseContext() {
-    // TODO: probably noop instead of calling super
-    addOp(DisplayList::ReleaseContext);
-    OpenGLRenderer::releaseContext();
-}
-
 int DisplayListRenderer::save(int flags) {
     addOp(DisplayList::Save);
     addInt(flags);
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index bab5149..a6d2bfe 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -89,9 +89,7 @@
     // IMPORTANT: Update the intialization of OP_NAMES in the .cpp file
     //            when modifying this file
     enum Op {
-        AcquireContext = 0,
-        ReleaseContext,
-        Save,
+        Save = 0,
         Restore,
         RestoreToCount,
         SaveLayer,
@@ -245,8 +243,6 @@
     void finish();
 
     bool callDrawGLFunction(Functor *functor);
-    void acquireContext();
-    void releaseContext();
 
     void interrupt();
     void resume();
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index c378f46..81c3407 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -191,10 +191,6 @@
     mCaches.unbindMeshBuffer();
 }
 
-void OpenGLRenderer::acquireContext() {
-    interrupt();
-}
-
 void OpenGLRenderer::resume() {
     glViewport(0, 0, mSnapshot->viewport.getWidth(), mSnapshot->viewport.getHeight());
 
@@ -212,10 +208,6 @@
     glBlendEquation(GL_FUNC_ADD);
 }
 
-void OpenGLRenderer::releaseContext() {
-    resume();
-}
-
 bool OpenGLRenderer::callDrawGLFunction(Functor *functor) {
     interrupt();
     if (mDirtyClip) {
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 77de1d2..64def03 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -71,8 +71,6 @@
     virtual void resume();
 
     virtual bool callDrawGLFunction(Functor *functor);
-    virtual void acquireContext();
-    virtual void releaseContext();
 
     int getSaveCount() const;
     virtual int save(int flags);
diff --git a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
old mode 100755
new mode 100644
index f10f5e8..1244b8e
--- a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
+++ b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
@@ -24,15 +24,16 @@
 import java.util.Iterator;
 import java.util.List;
 import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Rect;
 import android.media.videoeditor.VideoEditor.ExportProgressListener;
 import android.media.videoeditor.VideoEditor.PreviewProgressListener;
 import android.media.videoeditor.VideoEditor.MediaProcessingProgressListener;
 import android.util.Log;
 import android.util.Pair;
 import android.view.Surface;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.Rect;
 
 /**
  *This class provide Native methods to be used by MediaArtist {@hide}
@@ -70,11 +71,17 @@
     private boolean mExportDone = false;
 
     private int mProgressToApp;
+
     /**
      *  The resize paint
      */
     private static final Paint sResizePaint = new Paint(Paint.FILTER_BITMAP_FLAG);
 
+    private String mRenderPreviewOverlayFile;
+    private int   mRenderPreviewRenderingMode;
+
+    private boolean mIsFirstProgress;
+
     public static final int TASK_LOADING_SETTINGS = 1;
 
     public static final int TASK_ENCODING = 2;
@@ -1899,12 +1906,35 @@
     }
 
     @SuppressWarnings("unused")
-    private void onPreviewProgressUpdate(int progress, boolean isFinished) {
+    private void onPreviewProgressUpdate(int progress, boolean isFinished,
+                  boolean updateOverlay, String filename, int renderingMode) {
         if (mPreviewProgressListener != null) {
-            mPreviewProgressListener.onProgress(mVideoEditor, progress, isFinished);
+            if (mIsFirstProgress) {
+                mPreviewProgressListener.onStart(mVideoEditor);
+                mIsFirstProgress = false;
+            }
+
+            final VideoEditor.OverlayData overlayData;
+            if (updateOverlay) {
+                overlayData = new VideoEditor.OverlayData();
+                if (filename != null) {
+                    overlayData.set(BitmapFactory.decodeFile(filename), renderingMode);
+                } else {
+                    overlayData.setClear();
+                }
+            } else {
+                overlayData = null;
+            }
+
+            mPreviewProgressListener.onProgress(mVideoEditor, progress, overlayData);
+
             if (progress != 0) {
                 mPreviewProgress = progress;
             }
+
+            if (isFinished) {
+                mPreviewProgressListener.onStop(mVideoEditor);
+            }
         }
     }
 
@@ -2894,6 +2924,7 @@
                     maxHeight = populateMediaItemProperties(lMediaItem,
                                                             previewIndex,
                                                             maxHeight);
+                    /* Get the clip properties of the media item. */
                     if (lMediaItem instanceof MediaImageItem)
                     {
                         int tmpCnt = 0;
@@ -3014,11 +3045,11 @@
      * @param callbackAfterFrameCount INdicated after how many frames
      * the callback is needed
      * @param listener The PreviewProgressListener
-     *
      */
     public void doPreview(Surface surface, long fromMs, long toMs, boolean loop,
             int callbackAfterFrameCount, PreviewProgressListener listener) {
         mPreviewProgress = fromMs;
+        mIsFirstProgress = true;
         mPreviewProgressListener = listener;
 
         if (!mInvalidatePreviewArray) {
@@ -3042,9 +3073,6 @@
                 Log.e("MediaArtistNativeHelper", "Runtime exception in nativeStartPreview");
                 throw ex;
             }
-
-        } else {
-            return;
         }
     }
 
@@ -3064,22 +3092,37 @@
      * @param time The time in ms at which the frame has to be rendered
      * @param surfaceWidth The surface width
      * @param surfaceHeight The surface height
+     * @param overlayData The overlay data
      *
      * @return The actual time from the story board at which the  frame was extracted
      * and rendered
      */
     public long renderPreviewFrame(Surface surface, long time, int surfaceWidth,
-                                   int surfaceHeight) {
+            int surfaceHeight, VideoEditor.OverlayData overlayData) {
         long timeMs = 0;
         if (!mInvalidatePreviewArray) {
             try {
-                for (int clipCnt = 0; clipCnt < mPreviewEditSettings.clipSettingsArray.length; clipCnt++) {
+                for (int clipCnt = 0;
+                      clipCnt < mPreviewEditSettings.clipSettingsArray.length;
+                      clipCnt++) {
+
                     if (mPreviewEditSettings.clipSettingsArray[clipCnt].fileType == FileType.JPG) {
-                        mPreviewEditSettings.clipSettingsArray[clipCnt].clipPath = mPreviewEditSettings.clipSettingsArray[clipCnt].clipDecodedPath;
+                        mPreviewEditSettings.clipSettingsArray[clipCnt].clipPath =
+                            mPreviewEditSettings.clipSettingsArray[clipCnt].clipDecodedPath;
                     }
                 }
+
+                // Reset the render preview frame params that shall be set by native.
+                mRenderPreviewOverlayFile = null;
+                mRenderPreviewRenderingMode = MediaRendering.RESIZING;
                 nativePopulateSettings(mPreviewEditSettings, mClipProperties, mAudioSettings);
                 timeMs = (long)nativeRenderPreviewFrame(surface, time, surfaceWidth, surfaceHeight);
+
+                if (mRenderPreviewOverlayFile != null) {
+                    overlayData.set(BitmapFactory.decodeFile(mRenderPreviewOverlayFile), mRenderPreviewRenderingMode);
+                } else {
+                    overlayData.setClear();
+                }
             } catch (IllegalArgumentException ex) {
                 Log.e("MediaArtistNativeHelper",
                 "Illegal Argument exception in nativeRenderPreviewFrame");
@@ -3094,11 +3137,16 @@
             }
             return timeMs;
         } else {
-
             throw new RuntimeException("Call generate preview first");
         }
     }
 
+    private void previewFrameEditInfo(String filename, int renderingMode) {
+        mRenderPreviewOverlayFile = filename;
+        mRenderPreviewRenderingMode = renderingMode;
+    }
+
+
     /**
      * This function is responsible for rendering a single frame
      * from a single media item on the surface
@@ -3551,7 +3599,6 @@
         int outBitrate = 0;
         mExportFilename = filePath;
         previewStoryBoard(mediaItemsList, mediaTransitionList, mediaBGMList,null);
-
         mExportProgressListener = listener;
 
         mProgressToApp = 0;
@@ -3678,7 +3725,6 @@
         int outBitrate = 0;
         mExportFilename = filePath;
         previewStoryBoard(mediaItemsList, mediaTransitionList, mediaBGMList,null);
-
         mExportProgressListener = listener;
 
         mProgressToApp = 0;
@@ -4003,6 +4049,7 @@
     public void clearPreviewSurface(Surface surface) {
        nativeClearSurface(surface);
     }
+
     /**     Native Methods        */
     native Properties getMediaProperties(String file) throws IllegalArgumentException,
     IllegalStateException, RuntimeException, Exception;
diff --git a/media/java/android/media/videoeditor/Transition.java b/media/java/android/media/videoeditor/Transition.java
index feec284..4d1bafb 100755
--- a/media/java/android/media/videoeditor/Transition.java
+++ b/media/java/android/media/videoeditor/Transition.java
@@ -332,8 +332,6 @@
         List<EffectSettings> effectSettings_clip2;
 
         String output = null;
-        String effectClip1 = null;
-        String effectClip2 = null;
 
         if (mNativeHelper == null) {
             if (m1 != null)
diff --git a/media/java/android/media/videoeditor/VideoEditor.java b/media/java/android/media/videoeditor/VideoEditor.java
index f1ad921..9006613 100755
--- a/media/java/android/media/videoeditor/VideoEditor.java
+++ b/media/java/android/media/videoeditor/VideoEditor.java
@@ -20,7 +20,10 @@
 import java.io.IOException;
 import java.util.List;
 import java.util.concurrent.CancellationException;
-
+import android.graphics.Bitmap;
+import android.graphics.Color;
+import android.graphics.Canvas;
+import android.graphics.Rect;
 import android.view.SurfaceHolder;
 
 /**
@@ -78,9 +81,26 @@
          * @param videoEditor The VideoEditor instance
          * @param timeMs The current preview position (expressed in milliseconds
          *        since the beginning of the storyboard timeline).
-         * @param end true if the end of the timeline was reached
+         * @param overlayData The overlay data (null if the overlay data
+         *      is unchanged)
          */
-        public void onProgress(VideoEditor videoEditor, long timeMs, boolean end);
+        public void onProgress(VideoEditor videoEditor, long timeMs,
+                               OverlayData overlayData);
+        /**
+         * This method notifies the listener when the preview is started
+         * previewing a project.
+         *
+         * @param videoEditor The VideoEditor instance
+         */
+        public void onStart(VideoEditor videoEditor);
+
+        /**
+         * This method notifies the listener when the preview is stopped
+         * previewing a project.
+         *
+         * @param videoEditor The VideoEditor instance
+         */
+        public void onStop(VideoEditor videoEditor);
     }
 
     /**
@@ -126,6 +146,158 @@
     }
 
     /**
+     * The overlay data
+     */
+    public static final class OverlayData {
+        // Instance variables
+        private Bitmap mOverlayBitmap;
+        private int mRenderingMode;
+        private boolean mClear;
+
+        /**
+         * Default constructor
+         */
+        public OverlayData() {
+            mOverlayBitmap = null;
+            mRenderingMode = MediaArtistNativeHelper.MediaRendering.BLACK_BORDERS;
+            mClear = false;
+        }
+
+        /**
+         * Releases the bitmap
+         */
+        public void release() {
+            if (mOverlayBitmap != null) {
+                mOverlayBitmap.recycle();
+                mOverlayBitmap = null;
+            }
+        }
+
+        /**
+         * Check if the overlay needs to be rendered
+         *
+         * @return true if rendering is needed
+         */
+        public boolean needsRendering() {
+            return (mClear || mOverlayBitmap != null);
+        }
+
+        /**
+         * Store the overlay data
+         *
+         * @param overlayBitmap The overlay bitmap
+         * @param renderingMode The rendering mode
+         */
+        void set(Bitmap overlayBitmap, int renderingMode) {
+            mOverlayBitmap = overlayBitmap;
+            mRenderingMode = renderingMode;
+            mClear = false;
+        }
+
+        /**
+         * Clear the overlay
+         */
+        void setClear() {
+            mClear = true;
+        }
+
+        /**
+        * Render the overlay by either clearing it or by
+        * rendering the overlay bitmap with the specified
+        * rendering mode
+        *
+        * @param destBitmap The destination bitmap
+        */
+        public void renderOverlay(Bitmap destBitmap) {
+            if (mClear) {
+                destBitmap.eraseColor(Color.TRANSPARENT);
+            } else if (mOverlayBitmap != null) {
+                final Canvas overlayCanvas = new Canvas(destBitmap);
+                final Rect destRect;
+                final Rect srcRect;
+                switch (mRenderingMode) {
+                    case MediaArtistNativeHelper.MediaRendering.RESIZING: {
+                        destRect = new Rect(0, 0, overlayCanvas.getWidth(),
+                                                 overlayCanvas.getHeight());
+                        srcRect = new Rect(0, 0, mOverlayBitmap.getWidth(),
+                                                 mOverlayBitmap.getHeight());
+                        break;
+                    }
+
+                    case MediaArtistNativeHelper.MediaRendering.BLACK_BORDERS: {
+                        int left, right, top, bottom;
+                        float aROverlayImage, aRCanvas;
+                        aROverlayImage = (float)(mOverlayBitmap.getWidth()) /
+                                         (float)(mOverlayBitmap.getHeight());
+
+                        aRCanvas = (float)(overlayCanvas.getWidth()) /
+                                         (float)(overlayCanvas.getHeight());
+
+                        if (aROverlayImage > aRCanvas) {
+                            int newHeight = ((overlayCanvas.getWidth() * mOverlayBitmap.getHeight())
+                                             / mOverlayBitmap.getWidth());
+                            left = 0;
+                            top  = (overlayCanvas.getHeight() - newHeight) / 2;
+                            right = overlayCanvas.getWidth();
+                            bottom = top + newHeight;
+                        } else {
+                            int newWidth = ((overlayCanvas.getHeight() * mOverlayBitmap.getWidth())
+                                                / mOverlayBitmap.getHeight());
+                            left = (overlayCanvas.getWidth() - newWidth) / 2;
+                            top  = 0;
+                            right = left + newWidth;
+                            bottom = overlayCanvas.getHeight();
+                        }
+
+                        destRect = new Rect(left, top, right, bottom);
+                        srcRect = new Rect(0, 0, mOverlayBitmap.getWidth(), mOverlayBitmap.getHeight());
+                        break;
+                    }
+
+                    case MediaArtistNativeHelper.MediaRendering.CROPPING: {
+                        // Calculate the source rect
+                        int left, right, top, bottom;
+                        float aROverlayImage, aRCanvas;
+                        aROverlayImage = (float)(mOverlayBitmap.getWidth()) /
+                                         (float)(mOverlayBitmap.getHeight());
+                        aRCanvas = (float)(overlayCanvas.getWidth()) /
+                                        (float)(overlayCanvas.getHeight());
+                        if (aROverlayImage < aRCanvas) {
+                            int newHeight = ((mOverlayBitmap.getWidth() * overlayCanvas.getHeight())
+                                       / overlayCanvas.getWidth());
+
+                            left = 0;
+                            top  = (mOverlayBitmap.getHeight() - newHeight) / 2;
+                            right = mOverlayBitmap.getWidth();
+                            bottom = top + newHeight;
+                        } else {
+                            int newWidth = ((mOverlayBitmap.getHeight() * overlayCanvas.getWidth())
+                                        / overlayCanvas.getHeight());
+                            left = (mOverlayBitmap.getWidth() - newWidth) / 2;
+                            top  = 0;
+                            right = left + newWidth;
+                            bottom = mOverlayBitmap.getHeight();
+                        }
+
+                        srcRect = new Rect(left, top, right, bottom);
+                        destRect = new Rect(0, 0, overlayCanvas.getWidth(), overlayCanvas.getHeight());
+                        break;
+                    }
+
+                    default: {
+                        throw new IllegalStateException("Rendering mode: " + mRenderingMode);
+                    }
+                }
+
+                destBitmap.eraseColor(Color.TRANSPARENT);
+                overlayCanvas.drawBitmap(mOverlayBitmap, srcRect, destRect, null);
+
+                mOverlayBitmap.recycle();
+            }
+        }
+    }
+
+    /**
      * @return The path where the VideoEditor stores all files related to the
      *         project
      */
@@ -518,6 +690,7 @@
      *
      * @param surfaceHolder SurfaceHolder used by the application
      * @param timeMs time corresponding to the frame to display
+     * @param overlayData The overlay data
      *
      * @return The accurate time stamp of the frame that is rendered.
      *
@@ -526,7 +699,8 @@
      * @throws IllegalArgumentException if time is negative or beyond the
      *        preview duration
      */
-    public long renderPreviewFrame(SurfaceHolder surfaceHolder, long timeMs);
+    public long renderPreviewFrame(SurfaceHolder surfaceHolder, long timeMs,
+            OverlayData overlayData);
 
     /**
      * This method must be called after any changes made to the storyboard
@@ -535,7 +709,6 @@
      */
     public void generatePreview(MediaProcessingProgressListener listener);
 
-
     /**
      * Start the preview of all the storyboard items applied on all MediaItems
      * This method does not block (does not wait for the preview to complete).
@@ -580,5 +753,4 @@
      * and needs to be cleared.
      */
     public void clearSurface(SurfaceHolder surfaceHolder);
-
 }
diff --git a/media/java/android/media/videoeditor/VideoEditorImpl.java b/media/java/android/media/videoeditor/VideoEditorImpl.java
index 672ce19..d2dfe82bf 100755
--- a/media/java/android/media/videoeditor/VideoEditorImpl.java
+++ b/media/java/android/media/videoeditor/VideoEditorImpl.java
@@ -899,7 +899,8 @@
     /*
      * {@inheritDoc}
      */
-    public long renderPreviewFrame(SurfaceHolder surfaceHolder, long timeMs) {
+    public long renderPreviewFrame(SurfaceHolder surfaceHolder, long timeMs,
+                                    OverlayData overlayData) {
         long result = 0;
         int surfaceWidth = 0;
         int surfaceHeight = 0;
@@ -939,7 +940,7 @@
             if (!mMANativeHelper.mInvalidatePreviewArray) {
                 if (mMediaItems.size() > 0) {
                     result = mMANativeHelper.renderPreviewFrame(surface,
-                                             timeMs,surfaceWidth,surfaceHeight);
+                                             timeMs,surfaceWidth,surfaceHeight, overlayData);
                 }
                 else {
                     result = 0;
@@ -1643,7 +1644,7 @@
                     mMANativeHelper.previewStoryBoard(mMediaItems, mTransitions,
                                                       mAudioTracks, null);
                     mMANativeHelper.doPreview(mSurface, fromMs, toMs, loop,
-                                             callbackAfterFrameCount, listener);
+                                     callbackAfterFrameCount, listener);
                     mPreviewInProgress = true;
                 } catch (IllegalArgumentException ex) {
                     mPreviewSemaphore.release();
@@ -1683,7 +1684,7 @@
         }
     }
 
-    /**
+    /*
      * Remove transitions associated with the specified media item
      *
      * @param mediaItem The media item
diff --git a/media/jni/mediaeditor/VideoEditorClasses.cpp b/media/jni/mediaeditor/VideoEditorClasses.cpp
index 52e032a..369faa9 100755
--- a/media/jni/mediaeditor/VideoEditorClasses.cpp
+++ b/media/jni/mediaeditor/VideoEditorClasses.cpp
@@ -2481,7 +2481,7 @@
 
             pSettings->xVSS.width = pSettings->xVSS.pFramingBuffer->u_width;
             pSettings->xVSS.height = pSettings->xVSS.pFramingBuffer->u_height;
-            pSettings->xVSS.rgbType = M4VSS3GPP_kRGB888;
+            pSettings->xVSS.rgbType = M4VSS3GPP_kRGB565;
 
             VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR_CLASSES",
                     "pFramingBuffer u_width %d ", pSettings->xVSS.pFramingBuffer->u_width);
diff --git a/media/jni/mediaeditor/VideoEditorMain.cpp b/media/jni/mediaeditor/VideoEditorMain.cpp
index 8ce788b..4149bc9 100755
--- a/media/jni/mediaeditor/VideoEditorMain.cpp
+++ b/media/jni/mediaeditor/VideoEditorMain.cpp
@@ -86,6 +86,7 @@
     jmethodID                      onWarningMethodId;
     jmethodID                      onProgressUpdateMethodId;
     jmethodID                      onPreviewProgressUpdateMethodId;
+    jmethodID                      previewFrameEditInfoId;
     M4xVSS_InitParams              initParams;
     void*                          pTextRendererHandle;
     M4xVSS_getTextRgbBufferFct     pTextRendererFunction;
@@ -102,6 +103,9 @@
     M4OSA_Bool                      bSkipState;
     jmethodID                       onAudioGraphProgressUpdateMethodId;
     Mutex                           mLock;
+    bool                            mIsUpdateOverlay;
+    char                            *mOverlayFileName;
+    int                             mOverlayRenderingMode;
 } ManualEditContext;
 
 extern "C" M4OSA_ERR M4MCS_open_normalMode(
@@ -224,7 +228,7 @@
                 JNIEnv*                             pEnv);
 
 static void jniPreviewProgressCallback(void* cookie, M4OSA_UInt32 msgType,
-                                        M4OSA_UInt32 argc);
+                                        void *argc);
 
 static int videoEditor_renderMediaItemPreviewFrame(JNIEnv* pEnv,
                                                     jobject thiz,
@@ -374,35 +378,105 @@
 }
 
 static void jniPreviewProgressCallback (void* cookie, M4OSA_UInt32 msgType,
-                                        M4OSA_UInt32 argc)
+                                        void *argc)
 {
     ManualEditContext *pContext = (ManualEditContext *)cookie;
     JNIEnv*     pEnv = NULL;
     bool        isFinished = false;
     int         currentMs = 0;
     int         error = M4NO_ERROR;
+    bool        isUpdateOverlay = false;
+    int         overlayEffectIndex;
+    char        *extPos;
+    bool        isSendProgress = true;
+    jstring     tmpFileName;
+    VideoEditorCurretEditInfo *pCurrEditInfo;
 
     // Attach the current thread.
     pContext->pVM->AttachCurrentThread(&pEnv, NULL);
     switch(msgType)
     {
         case MSG_TYPE_PROGRESS_INDICATION:
-            currentMs = argc;
+            currentMs = *(int*)argc;
             break;
         case MSG_TYPE_PLAYER_ERROR:
             currentMs = -1;
-            error = argc;
+            error = *(int*)argc;
             break;
         case MSG_TYPE_PREVIEW_END:
             isFinished = true;
             break;
+        case MSG_TYPE_OVERLAY_UPDATE:
+        {
+            int overlayFileNameLen = 0;
+            isSendProgress = false;
+            pContext->mIsUpdateOverlay = true;
+            pCurrEditInfo = (VideoEditorCurretEditInfo*)argc;
+            overlayEffectIndex = pCurrEditInfo->overlaySettingsIndex;
+            LOGV("MSG_TYPE_OVERLAY_UPDATE");
+
+            if (pContext->mOverlayFileName != NULL) {
+                M4OSA_free((M4OSA_MemAddr32)pContext->mOverlayFileName);
+                pContext->mOverlayFileName = NULL;
+            }
+
+            overlayFileNameLen =
+                strlen((const char*)pContext->pEditSettings->Effects[overlayEffectIndex].xVSS.pFramingFilePath);
+
+            pContext->mOverlayFileName =
+                (char*)M4OSA_malloc(overlayFileNameLen+1,
+                                    M4VS, (M4OSA_Char*)"videoEdito JNI overlayFile");
+            if (pContext->mOverlayFileName != NULL) {
+                strncpy (pContext->mOverlayFileName,
+                    (const char*)pContext->pEditSettings->\
+                    Effects[overlayEffectIndex].xVSS.pFramingFilePath, overlayFileNameLen);
+                //Change the name to png file
+                extPos = strstr(pContext->mOverlayFileName, ".rgb");
+                if (extPos != NULL) {
+                    *extPos = '\0';
+                } else {
+                    LOGE("ERROR the overlay file is incorrect");
+                }
+
+                strcat(pContext->mOverlayFileName, ".png");
+                LOGV("Conv string is %s", pContext->mOverlayFileName);
+                LOGV("Current Clip index = %d", pCurrEditInfo->clipIndex);
+
+                pContext->mOverlayRenderingMode = pContext->pEditSettings->\
+                         pClipList[pCurrEditInfo->clipIndex]->xVSS.MediaRendering;
+                LOGI("rendering mode %d ", pContext->mOverlayRenderingMode);
+
+            }
+
+            break;
+        }
+
+        case MSG_TYPE_OVERLAY_CLEAR:
+            isSendProgress = false;
+            pContext->mOverlayFileName = NULL;
+            LOGI("MSG_TYPE_OVERLAY_CLEAR");
+            //argc is not used
+            pContext->mIsUpdateOverlay = true;
+            break;
         default:
             break;
     }
 
-    pEnv->CallVoidMethod(pContext->engine,
-                        pContext->onPreviewProgressUpdateMethodId,
-                        currentMs,isFinished);
+    if (isSendProgress) {
+        tmpFileName  = pEnv->NewStringUTF(pContext->mOverlayFileName);
+        pEnv->CallVoidMethod(pContext->engine,
+                pContext->onPreviewProgressUpdateMethodId,
+                currentMs,isFinished, pContext->mIsUpdateOverlay,
+                tmpFileName, pContext->mOverlayRenderingMode);
+
+        if (pContext->mIsUpdateOverlay) {
+            pContext->mIsUpdateOverlay = false;
+        }
+
+        if (tmpFileName) {
+            pEnv->DeleteLocalRef(tmpFileName);
+        }
+    }
 
     // Detach the current thread.
     pContext->pVM->DetachCurrentThread();
@@ -422,6 +496,11 @@
                                              (M4OSA_NULL == pContext),
                                              "not initialized");
     pContext->mPreviewController->stopPreview();
+
+    if (pContext->mOverlayFileName != NULL) {
+        M4OSA_free((M4OSA_MemAddr32)pContext->mOverlayFileName);
+        pContext->mOverlayFileName = NULL;
+    }
 }
 
 static void videoEditor_clearSurface(JNIEnv* pEnv,
@@ -507,6 +586,7 @@
     M4OSA_Context tnContext = M4OSA_NULL;
     const char* pMessage = NULL;
     M4VIFI_ImagePlane *yuvPlane = NULL;
+    VideoEditorCurretEditInfo  currEditInfo;
 
     VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO,
         "VIDEO_EDITOR", "surfaceWidth = %d",surfaceWidth);
@@ -770,9 +850,36 @@
         pContext->pEditSettings->\
         pClipList[iCurrentClipIndex]->xVSS.MediaRendering,
         pContext->pEditSettings->xVSS.outputVideoSize);
-
     result = pContext->mPreviewController->renderPreviewFrame(previewSurface,
-                                                              &frameStr);
+                                                              &frameStr, &currEditInfo);
+
+    if (currEditInfo.overlaySettingsIndex != -1) {
+        char tmpOverlayFilename[100];
+        char *extPos = NULL;
+        jstring tmpOverlayString;
+        int tmpRenderingMode = 0;
+
+        strncpy (tmpOverlayFilename,
+                (const char*)pContext->pEditSettings->Effects[currEditInfo.overlaySettingsIndex].xVSS.pFramingFilePath, 99);
+
+        //Change the name to png file
+        extPos = strstr(tmpOverlayFilename, ".rgb");
+        if (extPos != NULL) {
+            *extPos = '\0';
+        } else {
+            LOGE("ERROR the overlay file is incorrect");
+        }
+
+        strcat(tmpOverlayFilename, ".png");
+
+        tmpRenderingMode = pContext->pEditSettings->pClipList[iCurrentClipIndex]->xVSS.MediaRendering;
+        tmpOverlayString = pEnv->NewStringUTF(tmpOverlayFilename);
+        pEnv->CallVoidMethod(pContext->engine,
+            pContext->previewFrameEditInfoId,
+            tmpOverlayString, tmpRenderingMode);
+
+    }
+
     videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv,
             (M4NO_ERROR != result), result);
 
@@ -937,7 +1044,7 @@
     /*  pContext->mPreviewController->setPreviewFrameRenderingMode(M4xVSS_kBlackBorders,
     (M4VIDEOEDITING_VideoFrameSize)(M4VIDEOEDITING_kHD960+1));*/
     result
-    = pContext->mPreviewController->renderPreviewFrame(previewSurface,&frameStr);
+    = pContext->mPreviewController->renderPreviewFrame(previewSurface,&frameStr, NULL);
     videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv,
                                                 (M4NO_ERROR != result), result);
 
@@ -1325,7 +1432,7 @@
                                      "not initialized");
 
     pContext->onPreviewProgressUpdateMethodId = pEnv->GetMethodID(engineClass,
-            "onPreviewProgressUpdate",     "(IZ)V");
+            "onPreviewProgressUpdate",     "(IZZLjava/lang/String;I)V");
     // Check if the context is valid (required because the context is dereferenced).
     if (needToBeLoaded) {
         // Make sure that we are in a correct state.
@@ -1342,6 +1449,9 @@
     }
     M4OSA_TRACE1_0("videoEditorC_getEditSettings done");
 
+    pContext->previewFrameEditInfoId = pEnv->GetMethodID(engineClass,
+        "previewFrameEditInfo", "(Ljava/lang/String;I)V");
+
     if ( pContext->pEditSettings != NULL )
     {
         // Check if the edit settings could be retrieved.
@@ -1440,22 +1550,22 @@
                 width = pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_width;
                 height = pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_height;
 
-                pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_stride = width*3;
+                //RGB 565
+                pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_stride = width*2;
 
-                //for RGB888
+                //for RGB565
                 pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->u_topleft = 0;
-
                 pContext->pEditSettings->Effects[j].xVSS.pFramingBuffer->pac_data =
-                                                    (M4VIFI_UInt8 *)M4OSA_malloc(width*height*3,
-                    0x00,(M4OSA_Char *)"pac_data buffer");
+                            (M4VIFI_UInt8 *)M4OSA_malloc(width*height*2,
+                            0x00,(M4OSA_Char *)"pac_data buffer");
 
                 M4OSA_memcpy((M4OSA_Int8 *)&pContext->pEditSettings->\
                     Effects[j].xVSS.pFramingBuffer->\
-                    pac_data[0],(M4OSA_Int8 *)&aFramingCtx->FramingRgb->pac_data[0],(width*height*3));
+                    pac_data[0],(M4OSA_Int8 *)&aFramingCtx->FramingRgb->pac_data[0],(width*height*2));
 
-                //As of now rgb type is always rgb888, can be changed in future for rgb 565
+                //As of now rgb type is 565
                 pContext->pEditSettings->Effects[j].xVSS.rgbType =
-                (M4VSS3GPP_RGBType)M4VSS3GPP_kRGB888; //M4VSS3GPP_kRGB565;
+                    (M4VSS3GPP_RGBType) M4VSS3GPP_kRGB565;
 
                 if (aFramingCtx->FramingYuv != M4OSA_NULL )
                 {
@@ -2153,6 +2263,8 @@
             M4OSA_chrNCat((M4OSA_Char*)pContext->initParams.pTempPath, tmpString, M4OSA_chrLength(tmpString));
             M4OSA_chrNCat((M4OSA_Char*)pContext->initParams.pTempPath, (M4OSA_Char*)"/", 1);
             M4OSA_free((M4OSA_MemAddr32)tmpString);
+            pContext->mIsUpdateOverlay = false;
+            pContext->mOverlayFileName = NULL;
         }
 
         // Check if the initialization succeeded
diff --git a/media/jni/mediaeditor/VideoEditorMain.h b/media/jni/mediaeditor/VideoEditorMain.h
index b73913a..ca4a945 100755
--- a/media/jni/mediaeditor/VideoEditorMain.h
+++ b/media/jni/mediaeditor/VideoEditorMain.h
@@ -21,11 +21,18 @@
 
 typedef enum
 {
-    MSG_TYPE_PROGRESS_INDICATION,             /* Playback progress indication event*/
-    MSG_TYPE_PLAYER_ERROR,                    /* Playback error*/
-    MSG_TYPE_PREVIEW_END,                     /* Preview of clips is complete */
+    MSG_TYPE_PROGRESS_INDICATION,     // Playback progress indication event
+    MSG_TYPE_PLAYER_ERROR,            // Playback error
+    MSG_TYPE_PREVIEW_END,             // Preview of clips is complete
+    MSG_TYPE_OVERLAY_UPDATE,          // update overlay during preview
+    MSG_TYPE_OVERLAY_CLEAR,           // clear the overlay
 } progress_callback_msg_type;
 
+typedef struct {
+    int overlaySettingsIndex;
+    int clipIndex;
+} VideoEditorCurretEditInfo;
+
 typedef struct
 {
     M4OSA_Void     *pFile;                   /** PCM file path */
diff --git a/packages/SystemUI/res/drawable-mdpi/status_bar_ticker_tile.png b/packages/SystemUI/res/drawable-mdpi/status_bar_ticker_tile.png
new file mode 100644
index 0000000..85394fa
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/status_bar_ticker_tile.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_1x.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_1x.png
new file mode 100644
index 0000000..8e039ce
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_3g.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_3g.png
new file mode 100644
index 0000000..0cb0a08
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_4g.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_4g.png
new file mode 100644
index 0000000..c3cd10b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_e.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_e.png
new file mode 100644
index 0000000..650f67b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_g.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_g.png
new file mode 100644
index 0000000..f5b1618
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_h.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_h.png
new file mode 100644
index 0000000..eddc487
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_in_1x.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_in_1x.png
new file mode 100644
index 0000000..39dfcd3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_in_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_in_3g.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_in_3g.png
new file mode 100644
index 0000000..e78d872
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_in_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_in_4g.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_in_4g.png
new file mode 100644
index 0000000..5f88279
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_in_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_in_e.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_in_e.png
new file mode 100644
index 0000000..ad73252
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_in_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_in_g.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_in_g.png
new file mode 100644
index 0000000..d02de5b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_in_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_in_h.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_in_h.png
new file mode 100644
index 0000000..cb13b91
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_in_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_inandout_1x.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_inandout_1x.png
new file mode 100644
index 0000000..39dfcd3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_inandout_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_inandout_3g.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_inandout_3g.png
new file mode 100644
index 0000000..e78d872
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_inandout_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_inandout_4g.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_inandout_4g.png
new file mode 100644
index 0000000..8c04bd61
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_inandout_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_inandout_e.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_inandout_e.png
new file mode 100644
index 0000000..ad73252
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_inandout_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_inandout_g.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_inandout_g.png
new file mode 100644
index 0000000..d02de5b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_inandout_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_inandout_h.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_inandout_h.png
new file mode 100644
index 0000000..cb13b91
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_inandout_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_out_1x.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_out_1x.png
new file mode 100644
index 0000000..39dfcd3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_out_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_out_3g.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_out_3g.png
new file mode 100644
index 0000000..e78d872
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_out_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_out_4g.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_out_4g.png
new file mode 100644
index 0000000..456d0b6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_out_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_out_e.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_out_e.png
new file mode 100644
index 0000000..ad73252
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_out_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_out_g.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_out_g.png
new file mode 100644
index 0000000..d02de5b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_out_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_out_h.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_out_h.png
new file mode 100644
index 0000000..cb13b91
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_out_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_roam.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_roam.png
new file mode 100644
index 0000000..1eb0142
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_connected_roam.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_connected_1x.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_connected_1x.png
new file mode 100644
index 0000000..4c8e7c3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_connected_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_connected_3g.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_connected_3g.png
new file mode 100644
index 0000000..657dc04
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_connected_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_connected_4g.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_connected_4g.png
new file mode 100644
index 0000000..359e8f8
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_connected_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_connected_e.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_connected_e.png
new file mode 100644
index 0000000..e5b0841
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_connected_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_connected_g.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_connected_g.png
new file mode 100644
index 0000000..4fe8df3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_connected_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_connected_h.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_connected_h.png
new file mode 100644
index 0000000..a7a7beac
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_connected_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_in_1x.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_in_1x.png
new file mode 100644
index 0000000..39dfcd3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_in_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_in_3g.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_in_3g.png
new file mode 100644
index 0000000..e78d872
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_in_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_in_4g.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_in_4g.png
new file mode 100644
index 0000000..456d0b6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_in_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_in_e.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_in_e.png
new file mode 100644
index 0000000..ad73252
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_in_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_in_g.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_in_g.png
new file mode 100644
index 0000000..d02de5b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_in_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_in_h.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_in_h.png
new file mode 100644
index 0000000..cb13b91
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_in_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_inandout_1x.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_inandout_1x.png
new file mode 100644
index 0000000..39dfcd3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_inandout_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_inandout_3g.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_inandout_3g.png
new file mode 100644
index 0000000..e78d872
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_inandout_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_inandout_4g.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_inandout_4g.png
new file mode 100644
index 0000000..456d0b6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_inandout_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_inandout_e.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_inandout_e.png
new file mode 100644
index 0000000..ad73252
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_inandout_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_inandout_g.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_inandout_g.png
new file mode 100644
index 0000000..d02de5b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_inandout_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_inandout_h.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_inandout_h.png
new file mode 100644
index 0000000..cb13b91
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_inandout_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_out_1x.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_out_1x.png
new file mode 100644
index 0000000..39dfcd3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_out_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_out_3g.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_out_3g.png
new file mode 100644
index 0000000..e78d872
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_out_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_out_4g.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_out_4g.png
new file mode 100644
index 0000000..456d0b6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_out_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_out_e.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_out_e.png
new file mode 100644
index 0000000..ad73252
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_out_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_out_g.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_out_g.png
new file mode 100644
index 0000000..d02de5b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_out_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_out_h.png b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_out_h.png
new file mode 100644
index 0000000..cb13b91
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/stat_sys_data_fully_out_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_1x.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_1x.png
new file mode 100644
index 0000000..2cbec7b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_3g.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_3g.png
new file mode 100644
index 0000000..0efb9c9
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_4g.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_4g.png
new file mode 100644
index 0000000..2eae1e1
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_e.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_e.png
new file mode 100644
index 0000000..7e82c4c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_g.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_g.png
new file mode 100644
index 0000000..d37f1e5
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_h.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_h.png
new file mode 100644
index 0000000..5f7349e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_in_1x.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_in_1x.png
new file mode 100644
index 0000000..f50c987
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_in_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_in_3g.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_in_3g.png
new file mode 100644
index 0000000..1fff17e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_in_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_in_4g.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_in_4g.png
new file mode 100644
index 0000000..821d00e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_in_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_in_e.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_in_e.png
new file mode 100644
index 0000000..e27439e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_in_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_in_g.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_in_g.png
new file mode 100644
index 0000000..8b53f0f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_in_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_in_h.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_in_h.png
new file mode 100644
index 0000000..a23ec6e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_in_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_inandout_1x.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_inandout_1x.png
new file mode 100644
index 0000000..f50c987
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_inandout_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_inandout_3g.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_inandout_3g.png
new file mode 100644
index 0000000..1fff17e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_inandout_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_inandout_4g.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_inandout_4g.png
new file mode 100644
index 0000000..4cdce84
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_inandout_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_inandout_e.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_inandout_e.png
new file mode 100644
index 0000000..e27439e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_inandout_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_inandout_g.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_inandout_g.png
new file mode 100644
index 0000000..8b53f0f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_inandout_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_inandout_h.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_inandout_h.png
new file mode 100644
index 0000000..a23ec6e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_inandout_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_out_1x.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_out_1x.png
new file mode 100644
index 0000000..f50c987
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_out_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_out_3g.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_out_3g.png
new file mode 100644
index 0000000..1fff17e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_out_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_out_4g.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_out_4g.png
new file mode 100644
index 0000000..5a2662a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_out_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_out_e.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_out_e.png
new file mode 100644
index 0000000..e27439e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_out_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_out_g.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_out_g.png
new file mode 100644
index 0000000..8b53f0f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_out_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_out_h.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_out_h.png
new file mode 100644
index 0000000..a23ec6e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_out_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_roam.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_roam.png
new file mode 100644
index 0000000..31358ec
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_connected_roam.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_connected_1x.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_connected_1x.png
new file mode 100644
index 0000000..e5a3484
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_connected_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_connected_3g.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_connected_3g.png
new file mode 100644
index 0000000..2a3a5dc
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_connected_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_connected_4g.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_connected_4g.png
new file mode 100644
index 0000000..5dbd1ab
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_connected_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_connected_e.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_connected_e.png
new file mode 100644
index 0000000..51d1f76
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_connected_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_connected_g.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_connected_g.png
new file mode 100644
index 0000000..10d81ca
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_connected_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_connected_h.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_connected_h.png
new file mode 100644
index 0000000..1d9bda0
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_connected_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_in_1x.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_in_1x.png
new file mode 100644
index 0000000..f50c987
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_in_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_in_3g.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_in_3g.png
new file mode 100644
index 0000000..1fff17e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_in_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_in_4g.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_in_4g.png
new file mode 100644
index 0000000..5a2662a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_in_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_in_e.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_in_e.png
new file mode 100644
index 0000000..e27439e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_in_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_in_g.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_in_g.png
new file mode 100644
index 0000000..8b53f0f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_in_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_in_h.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_in_h.png
new file mode 100644
index 0000000..a23ec6e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_in_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_inandout_1x.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_inandout_1x.png
new file mode 100644
index 0000000..f50c987
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_inandout_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_inandout_3g.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_inandout_3g.png
new file mode 100644
index 0000000..1fff17e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_inandout_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_inandout_4g.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_inandout_4g.png
new file mode 100644
index 0000000..5a2662a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_inandout_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_inandout_e.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_inandout_e.png
new file mode 100644
index 0000000..e27439e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_inandout_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_inandout_g.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_inandout_g.png
new file mode 100644
index 0000000..8b53f0f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_inandout_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_inandout_h.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_inandout_h.png
new file mode 100644
index 0000000..a23ec6e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_inandout_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_out_1x.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_out_1x.png
new file mode 100644
index 0000000..f50c987
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_out_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_out_3g.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_out_3g.png
new file mode 100644
index 0000000..1fff17e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_out_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_out_4g.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_out_4g.png
new file mode 100644
index 0000000..5a2662a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_out_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_out_e.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_out_e.png
new file mode 100644
index 0000000..e27439e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_out_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_out_g.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_out_g.png
new file mode 100644
index 0000000..8b53f0f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_out_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_out_h.png b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_out_h.png
new file mode 100644
index 0000000..a23ec6e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/stat_sys_data_fully_out_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/status_bar_ticker_background.xml b/packages/SystemUI/res/drawable/status_bar_ticker_background.xml
index c230358..83524a6 100644
--- a/packages/SystemUI/res/drawable/status_bar_ticker_background.xml
+++ b/packages/SystemUI/res/drawable/status_bar_ticker_background.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- 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.
@@ -14,14 +14,8 @@
      limitations under the License.
 -->
 
-<layer-list
+<bitmap
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:opacity="translucent"
-    >
-    <item
-        android:drawable="@drawable/ticker_background_color"
-        android:top="12dp"
-        />
-</layer-list>
-
-
+    android:tileMode="repeat"
+    android:src="@drawable/status_bar_ticker_tile"
+    />
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_ticker_compat.xml b/packages/SystemUI/res/layout-xlarge/status_bar_ticker_compat.xml
index 6de7697..d963de1 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar_ticker_compat.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_ticker_compat.xml
@@ -18,9 +18,9 @@
 <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="@*android:dimen/status_bar_height"
+    android:layout_height="match_parent"
     android:orientation="horizontal"
-    android:background="@drawable/status_bar_ticker_background"
+    android:gravity="bottom"
     >
 
     <ImageView
@@ -30,29 +30,38 @@
         android:scaleType="center"
         android:visibility="gone"
         />
-    
-    <ImageView android:id="@+id/left_icon"
-        android:layout_width="64dp"
-        android:layout_height="match_parent"
-        android:scaleType="center"
-        android:visibility="gone"
-        />
 
-    <TextView android:id="@+id/text"
-        android:textAppearance="@*android:style/TextAppearance.StatusBar.Ticker"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_gravity="center_vertical"
-        android:layout_marginLeft="12dp"
-        android:gravity="center_vertical"
-        android:maxLines="2"
-        />
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="@*android:dimen/status_bar_height"
+        android:layout_weight="1"
+        android:background="@drawable/status_bar_ticker_background"
+        >
+        
+        <ImageView android:id="@+id/left_icon"
+            android:layout_width="64dp"
+            android:layout_height="match_parent"
+            android:scaleType="center"
+            android:visibility="gone"
+            />
 
-    <ImageView android:id="@+id/right_icon"
-        android:layout_width="64dp"
-        android:layout_height="match_parent"
-        android:scaleType="center"
-        android:visibility="gone"
-        />
+        <TextView android:id="@+id/text"
+            android:textAppearance="@*android:style/TextAppearance.StatusBar.Ticker"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_gravity="center_vertical"
+            android:layout_marginLeft="12dp"
+            android:gravity="center_vertical"
+            android:maxLines="2"
+            />
+
+        <ImageView android:id="@+id/right_icon"
+            android:layout_width="64dp"
+            android:layout_height="match_parent"
+            android:scaleType="center"
+            android:visibility="gone"
+            />
+
+    </LinearLayout>
 
 </LinearLayout>
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_ticker_panel.xml b/packages/SystemUI/res/layout-xlarge/status_bar_ticker_panel.xml
index d570ace..6cd8899 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar_ticker_panel.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_ticker_panel.xml
@@ -18,14 +18,10 @@
 <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="wrap_content"
+    android:layout_height="match_parent"
     android:orientation="horizontal"
-    android:background="@drawable/status_bar_ticker_background"
     android:gravity="bottom"
     >
-    <!--
-    android:background="@drawable/ticker_background"
-    -->
 
     <ImageView
         android:id="@+id/large_icon"
@@ -34,6 +30,12 @@
         android:scaleType="center"
         android:visibility="gone"
         />
-        <!-- TODO: scaleType should be top-left but ImageView doesn't support that. -->
 
+    <FrameLayout
+        android:id="@+id/ticker_expanded"
+        android:layout_weight="1"
+        android:layout_height="@*android:dimen/status_bar_height"
+        android:layout_width="match_parent"
+        android:background="@drawable/status_bar_ticker_background"
+        />
 </LinearLayout>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
index 440d680..5184462 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
@@ -38,7 +38,7 @@
 import android.view.WindowManagerImpl;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
-import android.widget.LinearLayout;
+import android.widget.FrameLayout;
 import android.widget.TextView;
 
 import com.android.internal.statusbar.StatusBarIcon;
@@ -173,6 +173,7 @@
                     mWindow = makeWindow();
                     WindowManagerImpl.getDefault().addView(mWindow, mWindow.getLayoutParams());
                 }
+
                 mWindow.addView(mCurrentView);
                 sendEmptyMessageDelayed(MSG_ADVANCE, ADVANCE_DELAY);
                 break;
@@ -259,10 +260,11 @@
         }
         if (n.tickerView != null) {
             group = (ViewGroup)inflater.inflate(R.layout.status_bar_ticker_panel, null, false);
+            ViewGroup content = (FrameLayout) group.findViewById(R.id.ticker_expanded);
             View expanded = null;
             Exception exception = null;
             try {
-                expanded = n.tickerView.apply(mContext, group);
+                expanded = n.tickerView.apply(mContext, content);
             }
             catch (RuntimeException e) {
                 exception = e;
@@ -273,12 +275,10 @@
                 Slog.e(TAG, "couldn't inflate view for notification " + ident, exception);
                 return null;
             }
-            final int statusBarHeight = mContext.getResources().getDimensionPixelSize(
-                    com.android.internal.R.dimen.status_bar_height);
-            LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
-                    ViewGroup.LayoutParams.WRAP_CONTENT, statusBarHeight, 1.0f);
-            lp.gravity = Gravity.BOTTOM;
-            group.addView(expanded, lp);
+            FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
+                    ViewGroup.LayoutParams.MATCH_PARENT, 
+                    ViewGroup.LayoutParams.MATCH_PARENT);
+            content.addView(expanded, lp);
         } else if (n.tickerText != null) {
             group = (ViewGroup)inflater.inflate(R.layout.status_bar_ticker_compat, mWindow, false);
             final Drawable icon = StatusBarIconView.getIcon(mContext,
diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java
index 59a540b..ad25657 100644
--- a/services/java/com/android/server/AppWidgetService.java
+++ b/services/java/com/android/server/AppWidgetService.java
@@ -22,6 +22,7 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.PrintWriter;
+import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -62,6 +63,7 @@
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.util.AttributeSet;
+import android.util.Log;
 import android.util.Pair;
 import android.util.Slog;
 import android.util.TypedValue;
@@ -121,18 +123,15 @@
      * globally and may lead us to leak AppWidgetService instances (if there were more than one).
      */
     static class ServiceConnectionProxy implements ServiceConnection {
-        private final AppWidgetService mAppWidgetService;
         private final Pair<Integer, Intent.FilterComparison> mKey;
         private final IBinder mConnectionCb;
 
-        ServiceConnectionProxy(AppWidgetService appWidgetService,
-                Pair<Integer, Intent.FilterComparison> key, IBinder connectionCb) {
-            mAppWidgetService = appWidgetService;
+        ServiceConnectionProxy(Pair<Integer, Intent.FilterComparison> key, IBinder connectionCb) {
             mKey = key;
             mConnectionCb = connectionCb;
         }
         public void onServiceConnected(ComponentName name, IBinder service) {
-            IRemoteViewsAdapterConnection cb =
+            final IRemoteViewsAdapterConnection cb =
                 IRemoteViewsAdapterConnection.Stub.asInterface(mConnectionCb);
             try {
                 cb.onServiceConnected(service);
@@ -141,19 +140,13 @@
             }
         }
         public void onServiceDisconnected(ComponentName name) {
-            IRemoteViewsAdapterConnection cb =
+            disconnect();
+        }
+        public void disconnect() {
+            final IRemoteViewsAdapterConnection cb =
                 IRemoteViewsAdapterConnection.Stub.asInterface(mConnectionCb);
             try {
                 cb.onServiceDisconnected();
-                mAppWidgetService.mServiceConnectionUpdateHandler.post(new Runnable() {
-                    public void run() {
-                        // We don't want to touch mBoundRemoteViewsServices from any other thread
-                        // so queue this to run on the main thread.
-                        if (mAppWidgetService.mBoundRemoteViewsServices.containsKey(mKey)) {
-                            mAppWidgetService.mBoundRemoteViewsServices.remove(mKey);
-                        }
-                    }
-                });
             } catch (RemoteException e) {
                 e.printStackTrace();
             }
@@ -163,7 +156,6 @@
     // Manages connections to RemoteViewsServices
     private final HashMap<Pair<Integer, FilterComparison>, ServiceConnection>
         mBoundRemoteViewsServices = new HashMap<Pair<Integer,FilterComparison>,ServiceConnection>();
-    private final Handler mServiceConnectionUpdateHandler = new Handler();
 
     Context mContext;
     Locale mLocale;
@@ -456,13 +448,24 @@
                 throw new IllegalArgumentException("Unknown component " + componentName);
             }
 
-            // Bind to the RemoteViewsService (which will trigger a callback to the
-            // RemoteViewsAdapter)
+            // If there is already a connection made for this service intent, then disconnect from
+            // that first.  (This does not allow multiple connections to the same service under
+            // the same key)
+            ServiceConnectionProxy conn = null;
             Pair<Integer, FilterComparison> key = Pair.create(appWidgetId,
                     new FilterComparison(intent));
-            final ServiceConnection conn = new ServiceConnectionProxy(this, key, connection);
+            if (mBoundRemoteViewsServices.containsKey(key)) {
+                conn = (ServiceConnectionProxy) mBoundRemoteViewsServices.get(key);
+                conn.disconnect();
+                mContext.unbindService(conn);
+                mBoundRemoteViewsServices.remove(key);
+            }
+
+            // Bind to the RemoteViewsService (which will trigger a callback to the
+            // RemoteViewsAdapter.onServiceConnected())
             final long token = Binder.clearCallingIdentity();
             try {
+                conn = new ServiceConnectionProxy(key, connection);
                 mContext.bindService(intent, conn, Context.BIND_AUTO_CREATE);
                 mBoundRemoteViewsServices.put(key, conn);
             } finally {
@@ -473,37 +476,43 @@
 
     public void unbindRemoteViewsService(int appWidgetId, Intent intent) {
         synchronized (mAppWidgetIds) {
-            AppWidgetId id = lookupAppWidgetIdLocked(appWidgetId);
-            if (id == null) {
-                throw new IllegalArgumentException("bad appWidgetId");
-            }
-
             // Unbind from the RemoteViewsService (which will trigger a callback to the bound
             // RemoteViewsAdapter)
             Pair<Integer, FilterComparison> key = Pair.create(appWidgetId,
                     new FilterComparison(intent));
             if (mBoundRemoteViewsServices.containsKey(key)) {
-                final ServiceConnection conn = mBoundRemoteViewsServices.get(key);
-                mBoundRemoteViewsServices.remove(key);
-                conn.onServiceDisconnected(null);
+                // We don't need to use the appWidgetId until after we are sure there is something
+                // to unbind.  Note that this may mask certain issues with apps calling unbind()
+                // more than necessary.
+                AppWidgetId id = lookupAppWidgetIdLocked(appWidgetId);
+                if (id == null) {
+                    throw new IllegalArgumentException("bad appWidgetId");
+                }
+
+                ServiceConnectionProxy conn =
+                    (ServiceConnectionProxy) mBoundRemoteViewsServices.get(key);
+                conn.disconnect();
                 mContext.unbindService(conn);
+                mBoundRemoteViewsServices.remove(key);
+            } else {
+                Log.e("AppWidgetService", "Error (unbindRemoteViewsService): Connection not bound");
             }
         }
     }
 
     private void unbindAppWidgetRemoteViewsServicesLocked(AppWidgetId id) {
+        int appWidgetId = id.appWidgetId;
+        // Unbind all connections to Services bound to this AppWidgetId
         Iterator<Pair<Integer, Intent.FilterComparison>> it =
             mBoundRemoteViewsServices.keySet().iterator();
-        int appWidgetId = id.appWidgetId;
-
-        // Unbind all connections to AppWidgets bound to this id
         while (it.hasNext()) {
             final Pair<Integer, Intent.FilterComparison> key = it.next();
             if (key.first.intValue() == appWidgetId) {
-                final ServiceConnection conn = mBoundRemoteViewsServices.get(key);
-                it.remove();
-                conn.onServiceDisconnected(null);
+                final ServiceConnectionProxy conn = (ServiceConnectionProxy)
+                        mBoundRemoteViewsServices.get(key);
+                conn.disconnect();
                 mContext.unbindService(conn);
+                it.remove();
             }
         }
     }
diff --git a/services/java/com/android/server/ScreenRotationAnimation.java b/services/java/com/android/server/ScreenRotationAnimation.java
index bef64b3..90318f1 100644
--- a/services/java/com/android/server/ScreenRotationAnimation.java
+++ b/services/java/com/android/server/ScreenRotationAnimation.java
@@ -102,7 +102,7 @@
                 Slog.w(TAG, "Unable to allocate freeze surface", e);
             }
 
-            if (false) {
+            if (true) {
                 try {
                     int size = mOriginalWidth > mOriginalHeight ? mOriginalWidth : mOriginalHeight;
                     mBlackSurface = new Surface(session, 0, "BlackSurface",
diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp
index 464841b..8d83f0b 100644
--- a/services/surfaceflinger/LayerBase.cpp
+++ b/services/surfaceflinger/LayerBase.cpp
@@ -563,10 +563,15 @@
     if (s == 0) {
         s = createSurface();
         mClientSurface = s;
+        mClientSurfaceBinder = s->asBinder();
     }
     return s;
 }
 
+wp<IBinder> LayerBaseClient::getSurfaceBinder() const {
+    return mClientSurfaceBinder;
+}
+
 sp<LayerBaseClient::Surface> LayerBaseClient::createSurface() const
 {
     return new Surface(mFlinger, mIdentity,
diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h
index 1a34f52..8ed4749 100644
--- a/services/surfaceflinger/LayerBase.h
+++ b/services/surfaceflinger/LayerBase.h
@@ -285,6 +285,7 @@
     virtual ~LayerBaseClient();
 
             sp<Surface> getSurface();
+            wp<IBinder> getSurfaceBinder() const;
     virtual sp<Surface> createSurface() const;
     virtual sp<LayerBaseClient> getLayerBaseClient() const {
         return const_cast<LayerBaseClient*>(this); }
@@ -325,6 +326,7 @@
 private:
     mutable Mutex mLock;
     mutable wp<Surface> mClientSurface;
+    wp<IBinder> mClientSurfaceBinder;
     const wp<Client> mClientRef;
     // only read
     const uint32_t mIdentity;
diff --git a/services/surfaceflinger/LayerDim.cpp b/services/surfaceflinger/LayerDim.cpp
index 80cc52c..11f8feb 100644
--- a/services/surfaceflinger/LayerDim.cpp
+++ b/services/surfaceflinger/LayerDim.cpp
@@ -67,8 +67,14 @@
         const GLfloat alpha = s.alpha/255.0f;
         const uint32_t fbHeight = hw.getHeight();
         glDisable(GL_DITHER);
-        glEnable(GL_BLEND);
-        glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+
+        if (s.alpha == 0xFF) {
+            glDisable(GL_BLEND);
+        } else {
+            glEnable(GL_BLEND);
+            glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+        }
+
         glColor4f(0, 0, 0, alpha);
 
 #if defined(GL_OES_EGL_image_external)
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 291ebc5..87b66ea 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1088,7 +1088,7 @@
 {
     sp<LayerBaseClient> lbc(layerBase->getLayerBaseClient());
     if (lbc != 0) {
-        mLayerMap.removeItem( lbc->getSurface()->asBinder() );
+        mLayerMap.removeItem( lbc->getSurfaceBinder() );
     }
     ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
     if (index >= 0) {