Merge change 22282 into eclair

* changes:
  Fix Calling screen shows "In Call" on pressing mute button
diff --git a/api/current.xml b/api/current.xml
index 6059946..805917b 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -15944,6 +15944,17 @@
 <parameter name="data" type="android.content.Intent">
 </parameter>
 </method>
+<method name="onAttachedToWindow"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="onChildTitleChanged"
  return="void"
  abstract="false"
@@ -16147,6 +16158,17 @@
  visibility="protected"
 >
 </method>
+<method name="onDetachedFromWindow"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="onKeyDown"
  return="boolean"
  abstract="false"
@@ -19677,6 +19699,17 @@
  visibility="public"
 >
 </method>
+<method name="onAttachedToWindow"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="onContentChanged"
  return="void"
  abstract="false"
@@ -19785,6 +19818,17 @@
 <parameter name="featureId" type="int">
 </parameter>
 </method>
+<method name="onDetachedFromWindow"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="onKeyDown"
  return="boolean"
  abstract="false"
@@ -21731,6 +21775,30 @@
  visibility="public"
 >
 </method>
+<method name="onQueryPackageManager"
+ return="java.util.List&lt;android.content.pm.ResolveInfo&gt;"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="protected"
+>
+<parameter name="queryIntent" type="android.content.Intent">
+</parameter>
+</method>
+<method name="onSetContentView"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="protected"
+>
+</method>
 </class>
 <class name="LauncherActivity.IconResizer"
  extends="java.lang.Object"
@@ -25311,6 +25379,19 @@
  visibility="public"
 >
 </method>
+<method name="reset"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
 </class>
 <class name="ActivityNotFoundException"
  extends="java.lang.RuntimeException"
@@ -31226,6 +31307,19 @@
 <exception name="RemoteException" type="android.os.RemoteException">
 </exception>
 </method>
+<method name="reset"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
 </interface>
 <class name="Intent"
  extends="java.lang.Object"
@@ -154591,6 +154685,17 @@
 <parameter name="event" type="android.view.MotionEvent">
 </parameter>
 </method>
+<method name="onAttachedToWindow"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="onContentChanged"
  return="void"
  abstract="true"
@@ -154630,6 +154735,17 @@
 <parameter name="featureId" type="int">
 </parameter>
 </method>
+<method name="onDetachedFromWindow"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="onMenuItemSelected"
  return="boolean"
  abstract="true"
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 10e6299..80d7285 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -1930,11 +1930,32 @@
      * 
      * @see #hasWindowFocus()
      * @see #onResume
+     * @see View#onWindowFocusChanged(boolean)
      */
     public void onWindowFocusChanged(boolean hasFocus) {
     }
     
     /**
+     * Called when the main window associated with the activity has been
+     * attached to the window manager.
+     * See {@link View#onAttachedToWindow() View.onAttachedToWindow()}
+     * for more information.
+     * @see View#onAttachedToWindow
+     */
+    public void onAttachedToWindow() {
+    }
+    
+    /**
+     * Called when the main window associated with the activity has been
+     * detached from the window manager.
+     * See {@link View#onDetachedFromWindow() View.onDetachedFromWindow()}
+     * for more information.
+     * @see View#onDetachedFromWindow
+     */
+    public void onDetachedFromWindow() {
+    }
+    
+    /**
      * Returns true if this activity's <em>main</em> window currently has window focus.
      * Note that this is not the same as the view itself having focus.
      * 
diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java
index 9432755..35d1004 100644
--- a/core/java/android/app/Dialog.java
+++ b/core/java/android/app/Dialog.java
@@ -576,6 +576,12 @@
     public void onWindowFocusChanged(boolean hasFocus) {
     }
 
+    public void onAttachedToWindow() {
+    }
+    
+    public void onDetachedFromWindow() {
+    }
+    
     /**
      * Called to process key events.  You can override this to intercept all 
      * key events before they are dispatched to the window.  Be sure to call 
diff --git a/core/java/android/app/LauncherActivity.java b/core/java/android/app/LauncherActivity.java
index d788c43..a83f4e8 100644
--- a/core/java/android/app/LauncherActivity.java
+++ b/core/java/android/app/LauncherActivity.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.ComponentInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.res.Resources;
@@ -70,13 +71,15 @@
         ListItem(PackageManager pm, ResolveInfo resolveInfo, IconResizer resizer) {
             this.resolveInfo = resolveInfo;
             label = resolveInfo.loadLabel(pm);
-            if (label == null && resolveInfo.activityInfo != null) {
+            ComponentInfo ci = resolveInfo.activityInfo;
+            if (ci == null) ci = resolveInfo.serviceInfo;
+            if (label == null && ci != null) {
                 label = resolveInfo.activityInfo.name;
             }
             
             icon = resizer.createIconThumbnail(resolveInfo.loadIcon(pm));
-            packageName = resolveInfo.activityInfo.applicationInfo.packageName;
-            className = resolveInfo.activityInfo.name;
+            packageName = ci.applicationInfo.packageName;
+            className = ci.name;
         }
 
         public ListItem() {
@@ -325,8 +328,7 @@
     
         requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
         setProgressBarIndeterminateVisibility(true);
-        setContentView(com.android.internal.R.layout.activity_list);
-        
+        onSetContentView();
             
         mIntent = new Intent(getTargetIntent());
         mIntent.setComponent(null);
@@ -338,10 +340,17 @@
         setProgressBarIndeterminateVisibility(false);
     }
 
+    /**
+     * Override to call setContentView() with your own content view to
+     * customize the list layout.
+     */
+    protected void onSetContentView() {
+        setContentView(com.android.internal.R.layout.activity_list);
+    }
+
     @Override
     protected void onListItemClick(ListView l, View v, int position, long id) {
-        Intent intent = ((ActivityAdapter)mAdapter).intentForPosition(position);
-
+        Intent intent = intentForPosition(position);
         startActivity(intent);
     }
     
@@ -374,12 +383,19 @@
     }
 
     /**
+     * Perform query on package manager for list items.  The default
+     * implementation queries for activities.
+     */
+    protected List<ResolveInfo> onQueryPackageManager(Intent queryIntent) {
+        return mPackageManager.queryIntentActivities(queryIntent, /* no flags */ 0);
+    }
+    
+    /**
      * Perform the query to determine which results to show and return a list of them.
      */
     public List<ListItem> makeListItems() {
         // Load all matching activities and sort correctly
-        List<ResolveInfo> list = mPackageManager.queryIntentActivities(mIntent,
-                /* no flags */ 0);
+        List<ResolveInfo> list = onQueryPackageManager(mIntent);
         Collections.sort(list, new ResolveInfo.DisplayNameComparator(mPackageManager));
         
         IconResizer resizer = new IconResizer();
diff --git a/core/java/android/content/AbstractCursorEntityIterator.java b/core/java/android/content/AbstractCursorEntityIterator.java
index bf3c4de..c2b13a4 100644
--- a/core/java/android/content/AbstractCursorEntityIterator.java
+++ b/core/java/android/content/AbstractCursorEntityIterator.java
@@ -87,6 +87,14 @@
         }
     }
 
+    public void reset() throws RemoteException {
+        if (mIsClosed) {
+            throw new IllegalStateException("calling reset() when the iterator is closed");
+        }
+        mEntityCursor.moveToPosition(-1);
+        mNextEntity = null;
+    }
+
     /**
      * Closes this iterator making it invalid. If is invalid for the user to call any public
      * method on the iterator once it has been closed.
diff --git a/core/java/android/content/ContentProviderNative.java b/core/java/android/content/ContentProviderNative.java
index a4c217b..e367ceb 100644
--- a/core/java/android/content/ContentProviderNative.java
+++ b/core/java/android/content/ContentProviderNative.java
@@ -281,6 +281,10 @@
             return mEntityIterator.next();
         }
 
+        public void reset() throws RemoteException {
+            mEntityIterator.reset();
+        }
+
         public void close() throws RemoteException {
             mEntityIterator.close();
         }
@@ -406,6 +410,10 @@
             return mEntityIterator.next();
         }
 
+        public void reset() throws RemoteException {
+            mEntityIterator.reset();
+        }
+
         public void close() {
             try {
                 mEntityIterator.close();
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 239b3de..b915803 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -244,6 +244,13 @@
             return mInner.next();
         }
 
+        public void reset() throws RemoteException {
+            if (mClientReleased) {
+                throw new IllegalStateException("this iterator is already closed");
+            }
+            mInner.reset();
+        }
+
         public void close() {
             mClient.release();
             mInner.close();
diff --git a/core/java/android/content/EntityIterator.java b/core/java/android/content/EntityIterator.java
index 5e5f14c..3cc1040 100644
--- a/core/java/android/content/EntityIterator.java
+++ b/core/java/android/content/EntityIterator.java
@@ -41,6 +41,8 @@
      */
     public Entity next() throws RemoteException;
 
+    public void reset() throws RemoteException;
+
     /**
      * Indicates that this iterator is no longer needed and that any associated resources
      * may be released (such as a SQLite cursor).
diff --git a/core/java/android/content/IEntityIterator.java b/core/java/android/content/IEntityIterator.java
index 1c478b3..068581e 100644
--- a/core/java/android/content/IEntityIterator.java
+++ b/core/java/android/content/IEntityIterator.java
@@ -98,6 +98,20 @@
                     return true;
                 }
 
+                case TRANSACTION_reset:
+                {
+                    data.enforceInterface(DESCRIPTOR);
+                    try {
+                        this.reset();
+                    } catch (RemoteException e) {
+                        Log.e(TAG, "caught exception in next()", e);
+                        reply.writeException(e);
+                        return true;
+                    }
+                    reply.writeNoException();
+                    return true;
+                }
+
                 case TRANSACTION_close:
                 {
                     data.enforceInterface(DESCRIPTOR);
@@ -157,6 +171,19 @@
                 }
             }
 
+            public void reset() throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    mRemote.transact(Stub.TRANSACTION_reset, _data, _reply, 0);
+                    _reply.readException();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+            }
+
             public void close() throws RemoteException {
                 Parcel _data = Parcel.obtain();
                 Parcel _reply = Parcel.obtain();
@@ -174,8 +201,10 @@
         static final int TRANSACTION_hasNext = (IBinder.FIRST_CALL_TRANSACTION + 0);
         static final int TRANSACTION_next = (IBinder.FIRST_CALL_TRANSACTION + 1);
         static final int TRANSACTION_close = (IBinder.FIRST_CALL_TRANSACTION + 2);
+        static final int TRANSACTION_reset = (IBinder.FIRST_CALL_TRANSACTION + 3);
     }
     public boolean hasNext() throws RemoteException;
     public Entity next() throws RemoteException;
+    public void reset() throws RemoteException;
     public void close() throws RemoteException;
 }
diff --git a/core/java/android/content/SyncResult.java b/core/java/android/content/SyncResult.java
index f3260f3..4c201e6 100644
--- a/core/java/android/content/SyncResult.java
+++ b/core/java/android/content/SyncResult.java
@@ -113,14 +113,19 @@
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder();
-        sb.append(" syncAlreadyInProgress: ").append(syncAlreadyInProgress);
-        sb.append(" tooManyDeletions: ").append(tooManyDeletions);
-        sb.append(" tooManyRetries: ").append(tooManyRetries);
-        sb.append(" databaseError: ").append(databaseError);
-        sb.append(" fullSyncRequested: ").append(fullSyncRequested);
-        sb.append(" partialSyncUnavailable: ").append(partialSyncUnavailable);
-        sb.append(" moreRecordsToGet: ").append(moreRecordsToGet);
-        sb.append(" stats: ").append(stats);
+        sb.append("SyncResult:");
+        if (syncAlreadyInProgress) {
+            sb.append(" syncAlreadyInProgress: ").append(syncAlreadyInProgress);
+        }
+        if (tooManyDeletions) sb.append(" tooManyDeletions: ").append(tooManyDeletions);
+        if (tooManyRetries) sb.append(" tooManyRetries: ").append(tooManyRetries);
+        if (databaseError) sb.append(" databaseError: ").append(databaseError);
+        if (fullSyncRequested) sb.append(" fullSyncRequested: ").append(fullSyncRequested);
+        if (partialSyncUnavailable) {
+            sb.append(" partialSyncUnavailable: ").append(partialSyncUnavailable);
+        }
+        if (moreRecordsToGet) sb.append(" moreRecordsToGet: ").append(moreRecordsToGet);
+        sb.append(stats);
         return sb.toString();
     }
 
diff --git a/core/java/android/content/SyncStats.java b/core/java/android/content/SyncStats.java
index b561b05..cc544c0 100644
--- a/core/java/android/content/SyncStats.java
+++ b/core/java/android/content/SyncStats.java
@@ -60,15 +60,18 @@
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder();
-        sb.append("numAuthExceptions: ").append(numAuthExceptions);
-        sb.append(" numIoExceptions: ").append(numIoExceptions);
-        sb.append(" numParseExceptions: ").append(numParseExceptions);
-        sb.append(" numConflictDetectedExceptions: ").append(numConflictDetectedExceptions);
-        sb.append(" numInserts: ").append(numInserts);
-        sb.append(" numUpdates: ").append(numUpdates);
-        sb.append(" numDeletes: ").append(numDeletes);
-        sb.append(" numEntries: ").append(numEntries);
-        sb.append(" numSkippedEntries: ").append(numSkippedEntries);
+        sb.append(" stats [");
+        if (numAuthExceptions > 0) sb.append(" numAuthExceptions: ").append(numAuthExceptions);
+        if (numIoExceptions > 0) sb.append(" numIoExceptions: ").append(numIoExceptions);
+        if (numParseExceptions > 0) sb.append(" numParseExceptions: ").append(numParseExceptions);
+        if (numConflictDetectedExceptions > 0)
+            sb.append(" numConflictDetectedExceptions: ").append(numConflictDetectedExceptions);
+        if (numInserts > 0) sb.append(" numInserts: ").append(numInserts);
+        if (numUpdates > 0) sb.append(" numUpdates: ").append(numUpdates);
+        if (numDeletes > 0) sb.append(" numDeletes: ").append(numDeletes);
+        if (numEntries > 0) sb.append(" numEntries: ").append(numEntries);
+        if (numSkippedEntries > 0) sb.append(" numSkippedEntries: ").append(numSkippedEntries);
+        sb.append("]");
         return sb.toString();
     }
 
diff --git a/core/java/android/net/SSLCertificateSocketFactory.java b/core/java/android/net/SSLCertificateSocketFactory.java
index deaa3c3..a97b9e5 100644
--- a/core/java/android/net/SSLCertificateSocketFactory.java
+++ b/core/java/android/net/SSLCertificateSocketFactory.java
@@ -41,6 +41,7 @@
 
 import org.apache.harmony.xnet.provider.jsse.SSLClientSessionCache;
 import org.apache.harmony.xnet.provider.jsse.SSLContextImpl;
+import org.apache.harmony.xnet.provider.jsse.SSLParameters;
 
 /**
  * SSLSocketFactory that provides optional (on debug devices, only) skipping of ssl certificfate
@@ -54,28 +55,6 @@
 
     private static final String LOG_TAG = "SSLCertificateSocketFactory";
 
-    private static X509TrustManager sDefaultTrustManager;
-
-    static {
-        try {
-            TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
-            tmf.init((KeyStore)null);
-            TrustManager[] tms = tmf.getTrustManagers();
-            if (tms != null) {
-                for (TrustManager tm : tms) {
-                    if (tm instanceof X509TrustManager) {
-                        sDefaultTrustManager = (X509TrustManager)tm;
-                        break;
-                    }
-                }
-            }
-        } catch (NoSuchAlgorithmException e) {
-            Log.e(LOG_TAG, "Unable to get X509 Trust Manager ", e);
-        } catch (KeyStoreException e) {
-            Log.e(LOG_TAG, "Key Store exception while initializing TrustManagerFactory ", e);
-        }
-    }
-
     private static final TrustManager[] TRUST_MANAGER = new TrustManager[] {
         new X509TrustManager() {
             public X509Certificate[] getAcceptedIssuers() {
@@ -155,20 +134,13 @@
 
     private boolean hasValidCertificateChain(Certificate[] certs) 
             throws IOException {
-        if (sDefaultTrustManager == null) {
-            if (Config.LOGD) {
-                Log.d(LOG_TAG,"hasValidCertificateChain():" +
-                          " null default trust manager!");
-            }
-            throw new IOException("null default trust manager");
-        }
-
         boolean trusted = (certs != null && (certs.length > 0));
 
         if (trusted) {
             try {
                 // the authtype we pass in doesn't actually matter
-                sDefaultTrustManager.checkServerTrusted((X509Certificate[]) certs, "RSA");
+                SSLParameters.getDefaultTrustManager()
+                        .checkServerTrusted((X509Certificate[]) certs, "RSA");
             } catch (GeneralSecurityException e) { 
                 String exceptionMessage = e != null ? e.getMessage() : "none";
                 if (Config.LOGD) {
diff --git a/core/java/android/net/http/CertificateChainValidator.java b/core/java/android/net/http/CertificateChainValidator.java
index 91fa900..ed6b4c2 100644
--- a/core/java/android/net/http/CertificateChainValidator.java
+++ b/core/java/android/net/http/CertificateChainValidator.java
@@ -16,6 +16,8 @@
 
 package android.net.http;
 
+import org.apache.harmony.xnet.provider.jsse.SSLParameters;
+
 import java.io.IOException;
 
 import java.security.cert.Certificate;
@@ -47,11 +49,6 @@
             = new CertificateChainValidator();
 
     /**
-     * Default trust manager (used to perform CA certificate validation)
-     */
-    private X509TrustManager mDefaultTrustManager;
-
-    /**
      * @return The singleton instance of the certificator chain validator
      */
     public static CertificateChainValidator getInstance() {
@@ -62,28 +59,7 @@
      * Creates a new certificate chain validator. This is a pivate constructor.
      * If you need a Certificate chain validator, call getInstance().
      */
-    private CertificateChainValidator() {
-        try {
-            TrustManagerFactory trustManagerFactory
-                = TrustManagerFactory.getInstance("X509");
-            trustManagerFactory.init((KeyStore)null);
-            TrustManager[] trustManagers =
-                trustManagerFactory.getTrustManagers();
-            if (trustManagers != null && trustManagers.length > 0) {
-                for (TrustManager trustManager : trustManagers) {
-                    if (trustManager instanceof X509TrustManager) {
-                        mDefaultTrustManager = (X509TrustManager)(trustManager);
-                        break;
-                    }
-                }
-            }
-        } catch (Exception exc) {
-            if (HttpLog.LOGV) {
-                HttpLog.v("CertificateChainValidator():" +
-                          " failed to initialize the trust manager");
-            }
-        }
-    }
+    private CertificateChainValidator() {}
 
     /**
      * Performs the handshake and server certificates validation
@@ -156,7 +132,7 @@
         // report back to the user.
         //
         try {
-            mDefaultTrustManager.checkServerTrusted(
+            SSLParameters.getDefaultTrustManager().checkServerTrusted(
                 serverCertificates, "RSA");
 
             // no errors!!!
@@ -186,7 +162,7 @@
         // check if the last certificate in the chain (root) is trusted
         X509Certificate[] rootCertificateChain = { currCertificate };
         try {
-            mDefaultTrustManager.checkServerTrusted(
+            SSLParameters.getDefaultTrustManager().checkServerTrusted(
                 rootCertificateChain, "RSA");
         } catch (CertificateExpiredException e) {
             String errorMessage = e.getMessage();
diff --git a/core/java/android/service/wallpaper/IWallpaperService.aidl b/core/java/android/service/wallpaper/IWallpaperService.aidl
index eb58c3b..bc7a1d7 100644
--- a/core/java/android/service/wallpaper/IWallpaperService.aidl
+++ b/core/java/android/service/wallpaper/IWallpaperService.aidl
@@ -23,5 +23,6 @@
  */
 oneway interface IWallpaperService {
     void attach(IWallpaperConnection connection,
-    		IBinder windowToken, int reqWidth, int reqHeight);
+    		IBinder windowToken, int windowType, boolean isPreview,
+    		int reqWidth, int reqHeight);
 }
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 5bb07f3..629e97e 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -212,6 +212,15 @@
         }
         
         /**
+         * Returns true if this engine is running in preview mode -- that is,
+         * it is being shown to the user before they select it as the actual
+         * wallpaper.
+         */
+        public boolean isPreview() {
+            return mIWallpaperEngine.mIsPreview;
+        }
+        
+        /**
          * Control whether this wallpaper will receive raw touch events
          * from the window manager as the user interacts with the window
          * that is currently displaying the wallpaper.  By default they
@@ -332,7 +341,7 @@
                     mLayout.token = mWindowToken;
 
                     if (!mCreated) {
-                        mLayout.type = WindowManager.LayoutParams.TYPE_WALLPAPER;
+                        mLayout.type = mIWallpaperEngine.mWindowType;
                         mLayout.gravity = Gravity.LEFT|Gravity.TOP;
                         mSession.add(mWindow, mLayout, View.VISIBLE, mContentInsets);
                     }
@@ -465,6 +474,8 @@
 
         final IWallpaperConnection mConnection;
         final IBinder mWindowToken;
+        final int mWindowType;
+        final boolean mIsPreview;
         int mReqWidth;
         int mReqHeight;
         
@@ -472,10 +483,12 @@
         
         IWallpaperEngineWrapper(WallpaperService context,
                 IWallpaperConnection conn, IBinder windowToken,
-                int reqWidth, int reqHeight) {
+                int windowType, boolean isPreview, int reqWidth, int reqHeight) {
             mCaller = new HandlerCaller(context, this);
             mConnection = conn;
             mWindowToken = windowToken;
+            mWindowType = windowType;
+            mIsPreview = isPreview;
             mReqWidth = reqWidth;
             mReqHeight = reqHeight;
             
@@ -567,10 +580,10 @@
             mTarget = context;
         }
 
-        public void attach(IWallpaperConnection conn,
-                IBinder windowToken, int reqWidth, int reqHeight) {
-            new IWallpaperEngineWrapper(
-                    mTarget, conn, windowToken, reqWidth, reqHeight);
+        public void attach(IWallpaperConnection conn, IBinder windowToken,
+                int windowType, boolean isPreview, int reqWidth, int reqHeight) {
+            new IWallpaperEngineWrapper(mTarget, conn, windowToken,
+                    windowType, isPreview, reqWidth, reqHeight);
         }
     }
     
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 02e0515..1932765 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -237,7 +237,6 @@
         /**
          * This is called whenever the current window attributes change.
          *
-
          */
         public void onWindowAttributesChanged(WindowManager.LayoutParams attrs);
 
@@ -252,13 +251,29 @@
         public void onContentChanged();
 
         /**
-         * This hook is called whenever the window focus changes.
+         * This hook is called whenever the window focus changes.  See
+         * {@link View#onWindowFocusChanged(boolean)
+         * View.onWindowFocusChanged(boolean)} for more information.
          *
          * @param hasFocus Whether the window now has focus.
          */
         public void onWindowFocusChanged(boolean hasFocus);
 
         /**
+         * Called when the window has been attached to the window manager.
+         * See {@link View#onAttachedToWindow() View.onAttachedToWindow()}
+         * for more information.
+         */
+        public void onAttachedToWindow();
+        
+        /**
+         * Called when the window has been attached to the window manager.
+         * See {@link View#onDetachedFromWindow() View.onDetachedFromWindow()}
+         * for more information.
+         */
+        public void onDetachedFromWindow();
+        
+        /**
          * Called when a panel is being closed.  If another logical subsequent
          * panel is being opened (and this panel is being closed to make room for the subsequent
          * panel), this method will NOT be called.
diff --git a/opengl/java/android/opengl/GLSurfaceView.java b/opengl/java/android/opengl/GLSurfaceView.java
index 132473a..022da0c 100644
--- a/opengl/java/android/opengl/GLSurfaceView.java
+++ b/opengl/java/android/opengl/GLSurfaceView.java
@@ -655,25 +655,27 @@
             EGLConfig closestConfig = null;
             int closestDistance = 1000;
             for(EGLConfig config : configs) {
-                int r = findConfigAttrib(egl, display, config,
-                        EGL10.EGL_RED_SIZE, 0);
-                int g = findConfigAttrib(egl, display, config,
-                         EGL10.EGL_GREEN_SIZE, 0);
-                int b = findConfigAttrib(egl, display, config,
-                          EGL10.EGL_BLUE_SIZE, 0);
-                int a = findConfigAttrib(egl, display, config,
-                        EGL10.EGL_ALPHA_SIZE, 0);
                 int d = findConfigAttrib(egl, display, config,
                         EGL10.EGL_DEPTH_SIZE, 0);
                 int s = findConfigAttrib(egl, display, config,
                         EGL10.EGL_STENCIL_SIZE, 0);
-                int distance = Math.abs(r - mRedSize)
-                    + Math.abs(g - mGreenSize)
-                    + Math.abs(b - mBlueSize) + Math.abs(a - mAlphaSize)
-                    + Math.abs(d - mDepthSize) + Math.abs(s - mStencilSize);
-                if (distance < closestDistance) {
-                    closestDistance = distance;
-                    closestConfig = config;
+                if (d >= mDepthSize && s>= mStencilSize) {
+                    int r = findConfigAttrib(egl, display, config,
+                            EGL10.EGL_RED_SIZE, 0);
+                    int g = findConfigAttrib(egl, display, config,
+                             EGL10.EGL_GREEN_SIZE, 0);
+                    int b = findConfigAttrib(egl, display, config,
+                              EGL10.EGL_BLUE_SIZE, 0);
+                    int a = findConfigAttrib(egl, display, config,
+                            EGL10.EGL_ALPHA_SIZE, 0);
+                    int distance = Math.abs(r - mRedSize)
+                                + Math.abs(g - mGreenSize)
+                                + Math.abs(b - mBlueSize)
+                                + Math.abs(a - mAlphaSize);
+                    if (distance < closestDistance) {
+                        closestDistance = distance;
+                        closestConfig = config;
+                    }
                 }
             }
             return closestConfig;
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index 445e681..d51b333 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -224,12 +224,12 @@
 
 void *Loader::load_driver(const char* driver, gl_hooks_t* hooks, uint32_t mask)
 {
-    //LOGD("%s", driver);
     void* dso = dlopen(driver, RTLD_NOW | RTLD_LOCAL);
-    LOGE_IF(!dso, "%s", dlerror());
     if (dso == 0)
         return 0;
 
+    LOGD("loaded %s", driver);
+
     if (mask & EGL) {
         getProcAddress = (getProcAddressType)dlsym(dso, "eglGetProcAddress");
 
diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java
index 07bab18..3c62aa0 100644
--- a/services/java/com/android/server/WallpaperManagerService.java
+++ b/services/java/com/android/server/WallpaperManagerService.java
@@ -404,7 +404,9 @@
     
     void attachServiceLocked(WallpaperConnection conn) {
         try {
-            conn.mService.attach(conn, conn.mToken, mWidth, mHeight);
+            conn.mService.attach(conn, conn.mToken,
+                    WindowManager.LayoutParams.TYPE_WALLPAPER, false,
+                    mWidth, mHeight);
         } catch (RemoteException e) {
             Log.w(TAG, "Failed attaching wallpaper; clearing", e);
             bindWallpaperComponentLocked(null);
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 7ca8b52..f8ba058 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -405,7 +405,12 @@
     // If non-null, this is the currently visible window that is associated
     // with the wallpaper.
     WindowState mWallpaperTarget = null;
-    WindowState mUpcomingWallpaperTarget = null;
+    // If non-null, we are in the middle of animating from one wallpaper target
+    // to another, and this is the lower one in Z-order.
+    WindowState mLowerWallpaperTarget = null;
+    // If non-null, we are in the middle of animating from one wallpaper target
+    // to another, and this is the higher one in Z-order.
+    WindowState mUpperWallpaperTarget = null;
     int mWallpaperAnimLayerAdjustment;
     
     AppWindowToken mFocusedApp = null;
@@ -1179,7 +1184,8 @@
     boolean adjustWallpaperWindowsLocked() {
         boolean changed = false;
         
-        mUpcomingWallpaperTarget = null;
+        final int dw = mDisplay.getWidth();
+        final int dh = mDisplay.getHeight();
         
         // First find top-most window that has asked to be on top of the
         // wallpaper; all wallpapers go behind it.
@@ -1188,60 +1194,41 @@
         WindowState w = null;
         WindowState foundW = null;
         int foundI = 0;
-        AppWindowToken topToken = null;
-        AppWindowToken behindToken = null;
         int i = N;
         while (i > 0) {
             i--;
             w = (WindowState)localmWindows.get(i);
-            if (topToken != null) {
-                if (w.mAppToken == topToken) {
+            if (w.mAppToken != null) {
+                // If this window's app token is hidden and not animating,
+                // it is of no interest to us.
+                if (w.mAppToken.hidden && w.mAppToken.animation == null) {
+                    if (DEBUG_WALLPAPER) Log.v(TAG,
+                            "Skipping hidden or animating token: " + w);
                     continue;
                 }
-                if (w.mAppToken != null) {
-                    if (behindToken == null) {
-                        // We need to look through for what is behind the
-                        // potential new wallpaper target...  skip all tokens
-                        // that are hidden and not animating, since they can't
-                        // be involved with the transition.
-                        if (w.mAppToken.hidden && w.mAppToken.animation == null) {
-                            continue;
-                        }
-                        behindToken = w.mAppToken;
-                    }
-                    if (w.mAppToken != behindToken) {
-                        break;
-                    }
+                // If this window's app token is ot fullscreen, also irrelevant.
+                if (!w.mAppToken.appFullscreen) {
+                    if (DEBUG_WALLPAPER) Log.v(TAG,
+                            "Skipping non-fullscreen token: " + w);
+                    continue;
                 }
             }
+            if (DEBUG_WALLPAPER) Log.v(TAG, "Win " + w + ": readyfordisplay="
+                    + w.isReadyForDisplay() + " drawpending=" + w.mDrawPending
+                    + " commitdrawpending=" + w.mCommitDrawPending);
             if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0 && w.isReadyForDisplay()
                     && !w.mDrawPending && !w.mCommitDrawPending) {
-                if (behindToken != null && w.mAppToken == behindToken) {
-                    // We had previously found a wallpaper window that was
-                    // animating, and now we found one behind it.  We could
-                    // be doing an animation between two windows on top of
-                    // the wallpaper!
-                    if (mWallpaperTarget == w || mWallpaperTarget == foundW) {
-                        // Retain the current wallpaper target (don't move
-                        // the wallpaper yet), but note the window that is
-                        // going to become the wallpaper target so that
-                        // others know about this special state.
-                        if (DEBUG_WALLPAPER) Log.v(TAG,
-                                "Switching wallpaper activities: cur#" + i + "="
-                                + w + " upcoming#" + foundI + "=" + foundW);
-                        mUpcomingWallpaperTarget = foundW;
-                        foundW = w;
-                        foundI = i;
-                        break;
-                    }
-                }
+                if (DEBUG_WALLPAPER) Log.v(TAG,
+                        "Found wallpaper activity: #" + i + "=" + w);
                 foundW = w;
                 foundI = i;
-                if (w.mAppToken != null && w.mAppToken.animation != null) {
-                    // If this app token is animating, we want to keep the
-                    // wallpaper below it if it is animating on top of another
-                    // app with a wallpaper.
-                    topToken = w.mAppToken;
+                if (w == mWallpaperTarget && w.mAppToken != null
+                        && w.mAppToken.animation != null) {
+                    // The current wallpaper target is animating, so we'll
+                    // look behind it for another possible target and figure
+                    // out what is going on below.
+                    if (DEBUG_WALLPAPER) Log.v(TAG, "Win " + w
+                            + ": token animating, looking behind.");
                     continue;
                 }
                 break;
@@ -1258,20 +1245,93 @@
             // enough (we'll just wait until whatever transition is pending
             // executes).
             if (mWallpaperTarget != null && mWallpaperTarget.mAppToken != null) {
+                if (DEBUG_WALLPAPER) Log.v(TAG,
+                        "Wallpaper not changing: waiting for app anim in current target");
                 return false;
             }
             if (foundW != null && foundW.mAppToken != null) {
-                return false;
-            }
-            if (mUpcomingWallpaperTarget != null && mUpcomingWallpaperTarget.mAppToken != null) {
+                if (DEBUG_WALLPAPER) Log.v(TAG,
+                        "Wallpaper not changing: waiting for app anim in found target");
                 return false;
             }
         }
         
         if (mWallpaperTarget != foundW) {
-            mWallpaperTarget = foundW;
             if (DEBUG_WALLPAPER) {
-                Log.v(TAG, "New wallpaper target: " + foundW);
+                Log.v(TAG, "New wallpaper target: " + foundW
+                        + " oldTarget: " + mWallpaperTarget);
+            }
+            
+            mLowerWallpaperTarget = null;
+            mUpperWallpaperTarget = null;
+            
+            WindowState oldW = mWallpaperTarget;
+            mWallpaperTarget = foundW;
+            
+            // Now what is happening...  if the current and new targets are
+            // animating, then we are in our super special mode!
+            if (foundW != null && foundW.mAppToken != null && oldW != null
+                    && oldW.mAppToken != null) {
+                if (DEBUG_WALLPAPER) {
+                    Log.v(TAG, "New animation: " + foundW.mAppToken.animation
+                            + " old animation: " + oldW.mAppToken.animation);
+                }
+                if (foundW.mAppToken.animation != null
+                        && oldW.mAppToken.animation != null) {
+                    int oldI = localmWindows.indexOf(oldW);
+                    if (DEBUG_WALLPAPER) {
+                        Log.v(TAG, "New i: " + foundI + " old i: " + oldI);
+                    }
+                    if (oldI >= 0) {
+                        if (DEBUG_WALLPAPER) {
+                            Log.v(TAG, "Animating wallpapers: old#" + oldI
+                                    + "=" + oldW + "; new#" + foundI
+                                    + "=" + foundW);
+                        }
+                        
+                        // Set the new target correctly.
+                        if (foundW.mAppToken.hiddenRequested) {
+                            if (DEBUG_WALLPAPER) {
+                                Log.v(TAG, "Old wallpaper still the target.");
+                            }
+                            mWallpaperTarget = oldW;
+                        }
+                        
+                        // Now set the upper and lower wallpaper targets
+                        // correctly, and make sure that we are positioning
+                        // the wallpaper below the lower.
+                        if (foundI > oldI) {
+                            // The new target is on top of the old one.
+                            if (DEBUG_WALLPAPER) {
+                                Log.v(TAG, "Found target above old target.");
+                            }
+                            mUpperWallpaperTarget = foundW;
+                            mLowerWallpaperTarget = oldW;
+                            foundW = oldW;
+                            foundI = oldI;
+                        } else {
+                            // The new target is below the old one.
+                            if (DEBUG_WALLPAPER) {
+                                Log.v(TAG, "Found target below old target.");
+                            }
+                            mUpperWallpaperTarget = oldW;
+                            mLowerWallpaperTarget = foundW;
+                        }
+                    }
+                }
+            }
+            
+        } else {
+            // Is it time to stop animating?
+            if (mLowerWallpaperTarget == null
+                    || mLowerWallpaperTarget.mAppToken.animation == null
+                    || mUpperWallpaperTarget == null
+                    || mUpperWallpaperTarget.mAppToken.animation == null) {
+                if (DEBUG_WALLPAPER) {
+                    Log.v(TAG, "No longer animating wallpaper targets!");
+                }
+                mLowerWallpaperTarget = null;
+                mUpperWallpaperTarget = null;
             }
         }
         
@@ -1286,7 +1346,7 @@
             // its layer adjustment.  Only do this if we are not transfering
             // between two wallpaper targets.
             mWallpaperAnimLayerAdjustment =
-                    (mUpcomingWallpaperTarget == null && foundW.mAppToken != null)
+                    (mLowerWallpaperTarget == null && foundW.mAppToken != null)
                     ? foundW.mAppToken.animLayerAdjustment : 0;
             
             // Now w is the window we are supposed to be behind...  but we
@@ -1310,9 +1370,6 @@
         // what is below it for later.
         foundW = foundI > 0 ? (WindowState)localmWindows.get(foundI-1) : null;
         
-        final int dw = mDisplay.getWidth();
-        final int dh = mDisplay.getHeight();
-        
         // Start stepping backwards from here, ensuring that our wallpaper windows
         // are correctly placed.
         int curTokenIndex = mWallpaperTokens.size();
@@ -6676,11 +6733,14 @@
                 mAppToken.startingDisplayed = false;
             }
 
-            if (localLOGV) Log.v(
-                TAG, "Window " + this
-                + " destroying surface " + mSurface + ", session " + mSession);
             if (mSurface != null) {
                 try {
+                    if (DEBUG_VISIBILITY) {
+                        RuntimeException e = new RuntimeException();
+                        e.fillInStackTrace();
+                        Log.w(TAG, "Window " + this + " destroying surface "
+                                + mSurface + ", session " + mSession, e);
+                    }
                     if (SHOW_TRANSACTIONS) {
                         RuntimeException ex = new RuntimeException();
                         ex.fillInStackTrace();
@@ -6829,7 +6889,7 @@
                 }
                 mHasLocalTransformation = false;
                 if ((!mLocalAnimating || mAnimationIsEntrance) && mAppToken != null
-                        && mAppToken.hasTransformation) {
+                        && mAppToken.animation != null) {
                     // When our app token is animating, we kind-of pretend like
                     // we are as well.  Note the mLocalAnimating mAnimationIsEntrance
                     // part of this check means that we will only do this if
@@ -6962,7 +7022,7 @@
             
             // Wallpapers are animated based on the "real" window they
             // are currently targeting.
-            if (mAttrs.type == TYPE_WALLPAPER && mUpcomingWallpaperTarget == null
+            if (mAttrs.type == TYPE_WALLPAPER && mLowerWallpaperTarget == null
                     && mWallpaperTarget != null) {
                 if (mWallpaperTarget.mHasLocalTransformation) {
                     attachedTransformation = mWallpaperTarget.mTransformation;
@@ -7600,7 +7660,7 @@
                 if (w == mInputMethodTarget) {
                     setInputMethodAnimLayerAdjustment(adj);
                 }
-                if (w == mWallpaperTarget && mUpcomingWallpaperTarget == null) {
+                if (w == mWallpaperTarget && mLowerWallpaperTarget == null) {
                     setWallpaperAnimLayerAdjustmentLocked(adj);
                 }
             }
@@ -7640,7 +7700,7 @@
 
                 if (animation == sDummyAnimation) {
                     // This guy is going to animate, but not yet.  For now count
-                    // it is not animating for purposes of scheduling transactions;
+                    // it as not animating for purposes of scheduling transactions;
                     // when it is really time to animate, this will be set to
                     // a real animation and the next call will execute normally.
                     return false;
@@ -7780,6 +7840,7 @@
                 pw.print(prefix); pw.print("allAppWindows="); pw.println(allAppWindows);
             }
             pw.print(prefix); pw.print("groupId="); pw.print(groupId);
+                    pw.print(" appFullscreen="); pw.println(appFullscreen);
                     pw.print(" requestedOrientation="); pw.println(requestedOrientation);
             pw.print(prefix); pw.print("hiddenRequested="); pw.print(hiddenRequested);
                     pw.print(" clientHidden="); pw.print(clientHidden);
@@ -8725,13 +8786,12 @@
 
                         mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
 
-                        boolean wallpaperMoved = adjustWallpaperWindowsLocked();
+                        adjustWallpaperWindowsLocked();
                         if (DEBUG_APP_TRANSITIONS) Log.v(TAG,
-                                "Old wallpaper target=" + mWallpaperTarget
-                                + ", upcoming target=" + mUpcomingWallpaperTarget);
-                        if (mUpcomingWallpaperTarget != mWallpaperTarget &&
-                                mUpcomingWallpaperTarget != null &&
-                                mWallpaperTarget != null) {
+                                "New wallpaper target=" + mWallpaperTarget
+                                + ", lower target=" + mLowerWallpaperTarget
+                                + ", upper target=" + mUpperWallpaperTarget);
+                        if (mLowerWallpaperTarget != null) {
                             // Need to determine if both the closing and
                             // opening app token sets are wallpaper targets,
                             // in which case special animations are needed
@@ -8741,20 +8801,20 @@
                             NN = mOpeningApps.size();
                             for (i=0; i<NN; i++) {
                                 AppWindowToken wtoken = mOpeningApps.get(i);
-                                if (mUpcomingWallpaperTarget.mAppToken == wtoken) {
+                                if (mLowerWallpaperTarget.mAppToken == wtoken) {
                                     found |= 1;
                                 }
-                                if (mWallpaperTarget.mAppToken == wtoken) {
+                                if (mUpperWallpaperTarget.mAppToken == wtoken) {
                                     found |= 1;
                                 }
                             }
                             NN = mClosingApps.size();
                             for (i=0; i<NN; i++) {
                                 AppWindowToken wtoken = mClosingApps.get(i);
-                                if (mUpcomingWallpaperTarget.mAppToken == wtoken) {
+                                if (mLowerWallpaperTarget.mAppToken == wtoken) {
                                     found |= 2;
                                 }
-                                if (mWallpaperTarget.mAppToken == wtoken) {
+                                if (mUpperWallpaperTarget.mAppToken == wtoken) {
                                     found |= 2;
                                 }
                             }
diff --git a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
index cc981c9..e187c37 100644
--- a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
@@ -99,6 +99,7 @@
     protected static final int EVENT_PS_RESTRICT_DISABLED = 33;
     public static final int EVENT_CLEAN_UP_CONNECTION = 34;
     protected static final int EVENT_CDMA_OTA_PROVISION = 35;
+    protected static final int EVENT_RESTART_RADIO = 36;
 
     //***** Constants
 
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
index 8913e816..2b78097 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
@@ -76,6 +76,10 @@
     /** Currently active CdmaDataConnection */
     private CdmaDataConnection mActiveDataConnection;
 
+    private boolean mPendingRestartRadio = false;
+    private static final int TIME_DELAYED_TO_RESTART_RADIO =
+            SystemProperties.getInt("ro.cdma.timetoradiorestart", 20000);
+
     /**
      * Pool size of CdmaDataConnection objects.
      */
@@ -318,7 +322,8 @@
                 && (mCdmaPhone.mSST.isConcurrentVoiceAndData() ||
                         phone.getState() == Phone.State.IDLE )
                 && isDataAllowed()
-                && desiredPowerState) {
+                && desiredPowerState
+                && !mPendingRestartRadio) {
 
             return setupData(reason);
 
@@ -334,7 +339,8 @@
                     " dataEnabled=" + getAnyDataEnabled() +
                     " roaming=" + roaming +
                     " dataOnRoamingEnable=" + getDataOnRoamingEnabled() +
-                    " desiredPowerState=" + desiredPowerState);
+                    " desiredPowerState=" + desiredPowerState +
+                    " PendingRestartRadio=" + mPendingRestartRadio);
             }
             return false;
         }
@@ -445,16 +451,11 @@
     }
 
     protected void restartRadio() {
-        Log.d(LOG_TAG, "************TURN OFF RADIO**************");
-        cleanUpConnection(true, Phone.REASON_CDMA_DATA_DETACHED);
-        phone.mCM.setRadioPower(false, null);
-        /* Note: no need to call setRadioPower(true).  Assuming the desired
-         * radio power state is still ON (as tracked by ServiceStateTracker),
-         * ServiceStateTracker will call setRadioPower when it receives the
-         * RADIO_STATE_CHANGED notification for the power off.  And if the
-         * desired power state has changed in the interim, we don't want to
-         * override it with an unconditional power on.
-         */
+        if (DBG) log("Cleanup connection and wait " +
+                (TIME_DELAYED_TO_RESTART_RADIO / 1000) + "s to restart radio");
+        cleanUpConnection(true, Phone.REASON_RADIO_TURNED_OFF);
+        sendEmptyMessageDelayed(EVENT_RESTART_RADIO, TIME_DELAYED_TO_RESTART_RADIO);
+        mPendingRestartRadio = true;
     }
 
     private Runnable mPollNetStat = new Runnable() {
@@ -719,8 +720,18 @@
         }
         setState(State.IDLE);
 
+        // Since the pending request to turn off or restart radio will be processed here,
+        // remove the pending event to restart radio from the message queue.
+        if (mPendingRestartRadio) removeMessages(EVENT_RESTART_RADIO);
+
+        // Process the pending request to turn off radio in ServiceStateTracker first.
+        // If radio is turned off in ServiceStateTracker, ignore the pending event to restart radio.
         CdmaServiceStateTracker ssTracker = mCdmaPhone.mSST;
-        ssTracker.processPendingRadioPowerOffAfterDataOff();
+        if (ssTracker.processPendingRadioPowerOffAfterDataOff()) {
+            mPendingRestartRadio = false;
+        } else {
+            onRestartRadio();
+        }
 
         phone.notifyDataConnection(reason);
         if (retryAfterDisconnected(reason)) {
@@ -816,6 +827,21 @@
         }
     }
 
+    private void onRestartRadio() {
+        if (mPendingRestartRadio) {
+            Log.d(LOG_TAG, "************TURN OFF RADIO**************");
+            phone.mCM.setRadioPower(false, null);
+            /* Note: no need to call setRadioPower(true).  Assuming the desired
+             * radio power state is still ON (as tracked by ServiceStateTracker),
+             * ServiceStateTracker will call setRadioPower when it receives the
+             * RADIO_STATE_CHANGED notification for the power off.  And if the
+             * desired power state has changed in the interim, we don't want to
+             * override it with an unconditional power on.
+             */
+            mPendingRestartRadio = false;
+        }
+    }
+
     private void writeEventLogCdmaDataDrop() {
         CdmaCellLocation loc = (CdmaCellLocation)(phone.getCellLocation());
         int bsid = (loc != null) ? loc.getBaseStationId() : -1;
@@ -928,6 +954,11 @@
                 onCdmaOtaProvision((AsyncResult) msg.obj);
                 break;
 
+            case EVENT_RESTART_RADIO:
+                if (DBG) log("EVENT_RESTART_RADIO");
+                onRestartRadio();
+                break;
+
             default:
                 // handle the message in the super class DataConnectionTracker
                 super.handleMessage(msg);
diff --git a/tests/DumpRenderTree/assets/run_layout_tests.py b/tests/DumpRenderTree/assets/run_layout_tests.py
index 49165d0..c056de5 100755
--- a/tests/DumpRenderTree/assets/run_layout_tests.py
+++ b/tests/DumpRenderTree/assets/run_layout_tests.py
@@ -22,7 +22,7 @@
   use --refresh-test-list option *once* to re-generate test list on the card.
 
   Some other options are:
-    --rebaseline generates expected layout tests results under /sdcard/android/expected_result/ 
+    --rebaseline generates expected layout tests results under /sdcard/android/expected_result/
     --time-out-ms (default is 8000 millis) for each test
     --adb-options="-e" passes option string to adb
     --results-directory=..., (default is ./layout-test-results) directory name under which results are stored.
@@ -51,11 +51,11 @@
 
 def DumpRenderTreeFinished(adb_cmd):
   """ Check if DumpRenderTree finished running tests
-  
+
   Args:
     output: adb_cmd string
   """
-  
+
   # pull /sdcard/android/running_test.txt, if the content is "#DONE", it's done
   shell_cmd_str = adb_cmd + " shell cat /sdcard/android/running_test.txt"
   adb_output = subprocess.Popen(shell_cmd_str, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()[0]
@@ -69,7 +69,7 @@
    """
    old_file = open(old_results, "r")
    new_file = open(new_results, "r")
-   diff_file = open(diff_results, "a") 
+   diff_file = open(diff_results, "a")
 
    # Read lines from each file
    ndict = new_file.readlines()
@@ -122,7 +122,7 @@
   """
   logging.info("Comparing results to " + ref_dir)
 
-  diff_result = os.path.join(results_dir, "layout_tests_diff.txt") 
+  diff_result = os.path.join(results_dir, "layout_tests_diff.txt")
   if os.path.exists(diff_result):
     os.remove(diff_result)
 
@@ -136,7 +136,7 @@
 
 def main(options, args):
   """Run the tests. Will call sys.exit when complete.
-  
+
   Args:
     options: a dictionary of command line options
     args: a list of sub directories or files to test
@@ -198,7 +198,7 @@
 
     shell_cmd_str = adb_cmd + " shell cat /sdcard/android/running_test.txt"
     crashed_test = subprocess.Popen(shell_cmd_str, shell=True, stdout=subprocess.PIPE).communicate()[0]
-    
+
     logging.info(crashed_test + " CRASHED");
     crashed_tests.append(crashed_test);
 
@@ -226,14 +226,15 @@
   result_files = ["/sdcard/layout_tests_passed.txt",
                   "/sdcard/layout_tests_failed.txt",
                   "/sdcard/layout_tests_nontext.txt"]
-  for file in result_files: 
+  for file in result_files:
     shell_cmd_str = adb_cmd + " pull " + file + " " + results_dir
     adb_output = subprocess.Popen(shell_cmd_str, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()[0]
     logging.debug(adb_output)
-    
+
   # Create the crash list.
   fp = open(results_dir + "/layout_tests_crashed.txt", "w");
-  fp.writelines('\n'.join(crashed_tests))
+  for crashed_test in crashed_tests:
+    fp.writelines(crashed_test + '\n')
   fp.close()
 
   # Count the number of tests in each category.
diff --git a/tools/layoutlib/api/src/com/android/layoutlib/api/ILayoutBridge.java b/tools/layoutlib/api/src/com/android/layoutlib/api/ILayoutBridge.java
index df1876d..b069aad 100644
--- a/tools/layoutlib/api/src/com/android/layoutlib/api/ILayoutBridge.java
+++ b/tools/layoutlib/api/src/com/android/layoutlib/api/ILayoutBridge.java
@@ -24,35 +24,40 @@
  * <p/>
  * <p/>{@link #getApiLevel()} gives the ability to know which methods are available.
  * <p/>
+ * Changes in API level 4:
+ * <ul>
+ * <li>new render method: {@link #computeLayout(IXmlPullParser, Object, int, int, boolean, int, float, float, String, boolean, Map, Map, IProjectCallback, ILayoutLog)}</li>
+ * <li>deprecated {@link #computeLayout(IXmlPullParser, Object, int, int, int, float, float, String, boolean, Map, Map, IProjectCallback, ILayoutLog)}</li>
+ * </ul>
  * Changes in API level 3:
  * <ul>
- * <li>{@link #computeLayout(IXmlPullParser, Object, int, int, int, float, float, String, boolean, Map, Map, IProjectCallback, ILayoutLog)}</li>
- * <li> deprecated {@link #computeLayout(IXmlPullParser, Object, int, int, String, boolean, Map, Map, IProjectCallback, ILayoutLog)}</li>
+ * <li>new render method: {@link #computeLayout(IXmlPullParser, Object, int, int, int, float, float, String, boolean, Map, Map, IProjectCallback, ILayoutLog)}</li>
+ * <li>deprecated {@link #computeLayout(IXmlPullParser, Object, int, int, String, boolean, Map, Map, IProjectCallback, ILayoutLog)}</li>
  * </ul>
  * Changes in API level 2:
  * <ul>
- * <li>{@link #getApiLevel()}</li>
- * <li>{@link #computeLayout(IXmlPullParser, Object, int, int, String, boolean, Map, Map, IProjectCallback, ILayoutLog)}</li>
+ * <li>new API Level method: {@link #getApiLevel()}</li>
+ * <li>new render method: {@link #computeLayout(IXmlPullParser, Object, int, int, String, boolean, Map, Map, IProjectCallback, ILayoutLog)}</li>
  * <li>deprecated {@link #computeLayout(IXmlPullParser, Object, int, int, String, Map, Map, IProjectCallback, ILayoutLog)}</li>
  * </ul>
  */
 public interface ILayoutBridge {
-    
-    final int API_CURRENT = 3;
+
+    final int API_CURRENT = 4;
 
     /**
      * Returns the API level of the layout library.
      * While no methods will ever be removed, some may become deprecated, and some new ones
      * will appear.
      * <p/>If calling this method throws an {@link AbstractMethodError}, then the API level
-     * should be considered to be 1. 
+     * should be considered to be 1.
      */
     int getApiLevel();
 
     /**
      * Initializes the Bridge object.
      * @param fontOsLocation the location of the fonts.
-     * @param enumValueMap map attrName => { map enumFlagName => Integer value }. 
+     * @param enumValueMap map attrName => { map enumFlagName => Integer value }.
      * @return true if success.
      * @since 1
      */
@@ -65,6 +70,44 @@
      * @param projectKey An Object identifying the project. This is used for the cache mechanism.
      * @param screenWidth the screen width
      * @param screenHeight the screen height
+     * @param renderFullHeight if true, the rendering will render the full height needed by the
+     * layout. If the layout needs less than <var>screenHeight</var> then the rendering will
+     * use <var>screenHeight</var> as the height.
+     * @param density the density factor for the screen.
+     * @param xdpi the screen actual dpi in X
+     * @param ydpi the screen actual dpi in Y
+     * @param themeName The name of the theme to use.
+     * @param isProjectTheme true if the theme is a project theme, false if it is a framework theme.
+     * @param projectResources the resources of the project. The map contains (String, map) pairs
+     * where the string is the type of the resource reference used in the layout file, and the
+     * map contains (String, {@link IResourceValue}) pairs where the key is the resource name,
+     * and the value is the resource value.
+     * @param frameworkResources the framework resources. The map contains (String, map) pairs
+     * where the string is the type of the resource reference used in the layout file, and the map
+     * contains (String, {@link IResourceValue}) pairs where the key is the resource name, and the
+     * value is the resource value.
+     * @param projectCallback The {@link IProjectCallback} object to get information from
+     * the project.
+     * @param logger the object responsible for displaying warning/errors to the user.
+     * @return an {@link ILayoutResult} object that contains the result of the layout.
+     * @since 4
+     */
+    ILayoutResult computeLayout(IXmlPullParser layoutDescription,
+            Object projectKey,
+            int screenWidth, int screenHeight, boolean renderFullHeight,
+            int density, float xdpi, float ydpi,
+            String themeName, boolean isProjectTheme,
+            Map<String, Map<String, IResourceValue>> projectResources,
+            Map<String, Map<String, IResourceValue>> frameworkResources,
+            IProjectCallback projectCallback, ILayoutLog logger);
+
+    /**
+     * Computes and renders a layout
+     * @param layoutDescription the {@link IXmlPullParser} letting the LayoutLib Bridge visit the
+     * layout file.
+     * @param projectKey An Object identifying the project. This is used for the cache mechanism.
+     * @param screenWidth the screen width
+     * @param screenHeight the screen height
      * @param density the density factor for the screen.
      * @param xdpi the screen actual dpi in X
      * @param ydpi the screen actual dpi in Y
@@ -84,6 +127,7 @@
      * @return an {@link ILayoutResult} object that contains the result of the layout.
      * @since 3
      */
+    @Deprecated
     ILayoutResult computeLayout(IXmlPullParser layoutDescription,
             Object projectKey,
             int screenWidth, int screenHeight, int density, float xdpi, float ydpi,
@@ -155,7 +199,7 @@
             Map<String, Map<String, IResourceValue>> projectResources,
             Map<String, Map<String, IResourceValue>> frameworkResources,
             IProjectCallback projectCallback, ILayoutLog logger);
-    
+
     /**
      * Clears the resource cache for a specific project.
      * <p/>This cache contains bitmaps and nine patches that are loaded from the disk and reused
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
index 6e26a05..02804e8 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
@@ -312,6 +312,7 @@
     }
 
     /*
+     * For compatilibty purposes, we implement the old deprecated version of computeLayout.
      * (non-Javadoc)
      * @see com.android.layoutlib.api.ILayoutBridge#computeLayout(com.android.layoutlib.api.IXmlPullParser, java.lang.Object, int, int, int, float, float, java.lang.String, boolean, java.util.Map, java.util.Map, com.android.layoutlib.api.IProjectCallback, com.android.layoutlib.api.ILayoutLog)
      */
@@ -321,6 +322,23 @@
             Map<String, Map<String, IResourceValue>> projectResources,
             Map<String, Map<String, IResourceValue>> frameworkResources,
             IProjectCallback customViewLoader, ILayoutLog logger) {
+        return computeLayout(layoutDescription, projectKey,
+                screenWidth, screenHeight, false /* renderFullHeight */,
+                density, xdpi, ydpi, themeName, isProjectTheme,
+                projectResources, frameworkResources, customViewLoader, logger);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see com.android.layoutlib.api.ILayoutBridge#computeLayout(com.android.layoutlib.api.IXmlPullParser, java.lang.Object, int, int, boolean, int, float, float, java.lang.String, boolean, java.util.Map, java.util.Map, com.android.layoutlib.api.IProjectCallback, com.android.layoutlib.api.ILayoutLog)
+     */
+    public ILayoutResult computeLayout(IXmlPullParser layoutDescription, Object projectKey,
+            int screenWidth, int screenHeight, boolean renderFullHeight,
+            int density, float xdpi, float ydpi,
+            String themeName, boolean isProjectTheme,
+            Map<String, Map<String, IResourceValue>> projectResources,
+            Map<String, Map<String, IResourceValue>> frameworkResources,
+            IProjectCallback customViewLoader, ILayoutLog logger) {
         if (logger == null) {
             logger = sDefaultLogger;
         }
@@ -393,15 +411,33 @@
                 root.setBackgroundDrawable(d);
             }
 
-            int w_spec = MeasureSpec.makeMeasureSpec(screenWidth, MeasureSpec.EXACTLY);
-            int h_spec = MeasureSpec.makeMeasureSpec(screenHeight - screenOffset,
-                    MeasureSpec.EXACTLY);
-
             // measure the views
+            int w_spec = MeasureSpec.makeMeasureSpec(screenWidth, MeasureSpec.EXACTLY);
+            int h_spec;
+
+            if (renderFullHeight) {
+                // measure the full height needed by the layout.
+                h_spec = MeasureSpec.makeMeasureSpec(screenHeight - screenOffset,
+                        MeasureSpec.UNSPECIFIED); // this lets us know the actual needed size
+                view.measure(w_spec, h_spec);
+
+                int neededHeight = root.getChildAt(0).getMeasuredHeight();
+
+                if (neededHeight > screenHeight - screenOffset) {
+                    screenHeight = neededHeight + screenOffset;
+                }
+            }
+
+            // remeasure with only the size we need
+            // This must always be done before the call to layout
+            h_spec = MeasureSpec.makeMeasureSpec(screenHeight - screenOffset,
+                    MeasureSpec.EXACTLY);
             view.measure(w_spec, h_spec);
+
+            // now do the layout.
             view.layout(0, screenOffset, screenWidth, screenHeight);
 
-            // draw them
+            // draw the views
             Canvas canvas = new Canvas(screenWidth, screenHeight - screenOffset, logger);
 
             root.draw(canvas);
@@ -1017,7 +1053,7 @@
         public void setWallpaperPosition(IBinder window, float x, float y) {
             // pass for now.
         }
-        
+
         public IBinder asBinder() {
             // pass for now.
             return null;