Merge change 21010

* changes:
  Grass has graduated from an RS experiment to a real live wallpaper.
diff --git a/api/current.xml b/api/current.xml
index b9fb85a..397e25d 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -26818,6 +26818,19 @@
 <exception name="IOException" type="java.io.IOException">
 </exception>
 </method>
+<method name="clearWallpaperOffsets"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="windowToken" type="android.os.IBinder">
+</parameter>
+</method>
 <method name="getDesiredMinimumHeight"
  return="int"
  abstract="false"
@@ -277743,6 +277756,8 @@
  deprecated="not deprecated"
  visibility="public"
 >
+<parameter name="name" type="java.lang.String">
+</parameter>
 </constructor>
 <constructor name="Timer"
  type="java.util.Timer"
@@ -277763,8 +277778,6 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="name" type="java.lang.String">
-</parameter>
 </constructor>
 <method name="cancel"
  return="void"
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index 78b6cf1..fd8776f 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -335,6 +335,25 @@
     }
     
     /**
+     * Clear the offsets previously associated with this window through
+     * {@link #setWallpaperOffsets(IBinder, float, float)}.  This reverts
+     * the window to its default state, where it does not cause the wallpaper
+     * to scroll from whatever its last offsets were.
+     * 
+     * @param windowToken The window who these offsets should be associated
+     * with, as returned by {@link android.view.View#getWindowVisibility()
+     * View.getWindowToken()}.
+     */
+    public void clearWallpaperOffsets(IBinder windowToken) {
+        try {
+            ViewRoot.getWindowSession(mContext.getMainLooper()).setWallpaperPosition(
+                    windowToken, -1, -1);
+        } catch (RemoteException e) {
+            // Ignore.
+        }
+    }
+    
+    /**
      * Remove any currently set wallpaper, reverting to the system's default
      * wallpaper. On success, the intent {@link Intent#ACTION_WALLPAPER_CHANGED}
      * is broadcast.
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 7017514..595b10c 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -24,7 +24,6 @@
 import android.app.WallpaperManager;
 import android.content.Intent;
 import android.graphics.Rect;
-import android.os.Handler;
 import android.os.IBinder;
 import android.os.Message;
 import android.os.RemoteException;
@@ -33,6 +32,7 @@
 import android.view.IWindowSession;
 import android.view.SurfaceHolder;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.ViewRoot;
 import android.view.WindowManager;
 import android.view.WindowManagerImpl;
@@ -50,13 +50,14 @@
         "android.service.wallpaper.WallpaperService";
 
     static final String TAG = "WallpaperService";
-    static final boolean DEBUG = true;
+    static final boolean DEBUG = false;
     
     private static final int DO_ATTACH = 10;
     private static final int DO_DETACH = 20;
     
     private static final int MSG_UPDATE_SURFACE = 10000;
     private static final int MSG_VISIBILITY_CHANGED = 10010;
+    private static final int MSG_WALLPAPER_OFFSETS = 10020;
     
     /**
      * The actual implementation of a wallpaper.  A wallpaper service may
@@ -83,6 +84,8 @@
         int mHeight;
         int mFormat;
         int mType;
+        int mCurWidth;
+        int mCurHeight;
         boolean mDestroyReportNeeded;
         final Rect mVisibleInsets = new Rect();
         final Rect mWinFrame = new Rect();
@@ -92,6 +95,11 @@
                 = new WindowManager.LayoutParams();
         IWindowSession mSession;
 
+        final Object mLock = new Object();
+        boolean mOffsetMessageEnqueued;
+        float mPendingXOffset;
+        float mPendingYOffset;
+        
         final BaseSurfaceHolder mSurfaceHolder = new BaseSurfaceHolder() {
 
             @Override
@@ -127,6 +135,20 @@
                         visible ? 1 : 0);
                 mCaller.sendMessage(msg);
             }
+
+            @Override
+            public void dispatchWallpaperOffsets(float x, float y) {
+                synchronized (mLock) {
+                    mPendingXOffset = x;
+                    mPendingYOffset = y;
+                    if (!mOffsetMessageEnqueued) {
+                        mOffsetMessageEnqueued = true;
+                        Message msg = mCaller.obtainMessage(MSG_WALLPAPER_OFFSETS);
+                        mCaller.sendMessage(msg);
+                    }
+                }
+            }
+            
         };
         
         /**
@@ -178,6 +200,16 @@
         }
         
         /**
+         * Called to inform you of the wallpaper's offsets changing
+         * within its contain, corresponding to the container's
+         * call to {@link WallpaperManager#setWallpaperOffsets(IBinder, float, float)
+         * WallpaperManager.setWallpaperOffsets()}.
+         */
+        public void onOffsetsChanged(float xOffset, float yOffset,
+                int xPixelOffset, int yPixelOffset) {
+        }
+        
+        /**
          * Convenience for {@link SurfaceHolder.Callback#surfaceChanged
          * SurfaceHolder.Callback.surfaceChanged()}.
          */
@@ -200,9 +232,9 @@
 
         void updateSurface(boolean force) {
             int myWidth = mSurfaceHolder.getRequestedWidth();
-            if (myWidth <= 0) myWidth = mIWallpaperEngine.mReqWidth;
+            if (myWidth <= 0) myWidth = ViewGroup.LayoutParams.FILL_PARENT;
             int myHeight = mSurfaceHolder.getRequestedHeight();
-            if (myHeight <= 0) myHeight = mIWallpaperEngine.mReqHeight;
+            if (myHeight <= 0) myHeight = ViewGroup.LayoutParams.FILL_PARENT;
             
             final boolean creating = !mCreated;
             final boolean formatChanged = mFormat != mSurfaceHolder.getRequestedFormat();
@@ -254,6 +286,9 @@
                     if (DEBUG) Log.i(TAG, "New surface: " + mSurfaceHolder.mSurface
                             + ", frame=" + mWinFrame);
                     
+                    mCurWidth = mWinFrame.width();
+                    mCurHeight = mWinFrame.height();
+                    
                     mSurfaceHolder.mSurfaceLock.unlock();
 
                     try {
@@ -278,10 +313,12 @@
                             }
                         }
                         if (creating || formatChanged || sizeChanged) {
-                            onSurfaceChanged(mSurfaceHolder, mFormat, mWidth, mHeight);
+                            onSurfaceChanged(mSurfaceHolder, mFormat,
+                                    mCurWidth, mCurHeight);
                             if (callbacks != null) {
                                 for (SurfaceHolder.Callback c : callbacks) {
-                                    c.surfaceChanged(mSurfaceHolder, mFormat, mWidth, mHeight);
+                                    c.surfaceChanged(mSurfaceHolder, mFormat,
+                                            mCurWidth, mCurHeight);
                                 }
                             }
                         }
@@ -305,7 +342,10 @@
             mCaller = wrapper.mCaller;
             mConnection = wrapper.mConnection;
             mWindowToken = wrapper.mWindowToken;
-            mSurfaceHolder.setSizeFromLayout();
+            // XXX temp -- should run in size from layout (screen) mode.
+            mSurfaceHolder.setFixedSize(mIWallpaperEngine.mReqWidth,
+                    mIWallpaperEngine.mReqHeight);
+            //mSurfaceHolder.setSizeFromLayout();
             mInitializing = true;
             mSession = ViewRoot.getWindowSession(getMainLooper());
             mWindow.setSession(mSession);
@@ -396,6 +436,22 @@
                             + ": " + message.arg1);
                     mEngine.onVisibilityChanged(message.arg1 != 0);
                     break;
+                case MSG_WALLPAPER_OFFSETS: {
+                    float xOffset;
+                    float yOffset;
+                    synchronized (mEngine.mLock) {
+                        xOffset = mEngine.mPendingXOffset;
+                        yOffset = mEngine.mPendingYOffset;
+                        mEngine.mOffsetMessageEnqueued = false;
+                    }
+                    if (DEBUG) Log.v(TAG, "Offsets change in " + mEngine
+                            + ": " + xOffset + "," + yOffset);
+                    final int availw = mReqWidth-mEngine.mCurWidth;
+                    final int xPixels = availw > 0 ? -(int)(availw*xOffset+.5f) : 0;
+                    final int availh = mReqHeight-mEngine.mCurHeight;
+                    final int yPixels = availh > 0 ? -(int)(availh*yOffset+.5f) : 0;
+                    mEngine.onOffsetsChanged(xOffset, yOffset, xPixels, yPixels);
+                } break;
                 default :
                     Log.w(TAG, "Unknown message type " + message.what);
             }
diff --git a/core/java/android/view/IWindow.aidl b/core/java/android/view/IWindow.aidl
index 99d5c0c..ec2036e 100644
--- a/core/java/android/view/IWindow.aidl
+++ b/core/java/android/view/IWindow.aidl
@@ -56,4 +56,9 @@
      * to date on the current state showing navigational focus (touch mode) too.
      */
     void windowFocusChanged(boolean hasFocus, boolean inTouchMode);
+    
+    /**
+     * Called for wallpaper windows when their offsets change.
+     */
+    void dispatchWallpaperOffsets(float x, float y);
 }
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 4546572..92e813f 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -16,6 +16,8 @@
 
 package android.view;
 
+import com.android.internal.view.BaseIWindow;
+
 import android.content.Context;
 import android.content.res.Resources;
 import android.content.res.CompatibilityInfo.Translator;
@@ -435,7 +437,7 @@
         updateWindow(false);
     }
 
-    private static class MyWindow extends IWindow.Stub {
+    private static class MyWindow extends BaseIWindow {
         private final WeakReference<SurfaceView> mSurfaceView;
 
         public MyWindow(SurfaceView surfaceView) {
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index 216fc5e..4623bb5 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -2858,6 +2858,9 @@
                 }
             }
         }
+        
+        public void dispatchWallpaperOffsets(float x, float y) {
+        }
     }
 
     /**
diff --git a/core/java/com/android/internal/os/HandlerCaller.java b/core/java/com/android/internal/os/HandlerCaller.java
index 2ab9e09..e4c473d 100644
--- a/core/java/com/android/internal/os/HandlerCaller.java
+++ b/core/java/com/android/internal/os/HandlerCaller.java
@@ -93,6 +93,10 @@
         mH.sendMessage(msg);
     }
     
+    public boolean hasMessages(int what) {
+        return mH.hasMessages(what);
+    }
+    
     public void sendMessage(Message msg) {
         mH.sendMessage(msg);
     }
diff --git a/core/java/com/android/internal/service/wallpaper/ImageWallpaper.java b/core/java/com/android/internal/service/wallpaper/ImageWallpaper.java
index 6d50840..e1bf5ca 100644
--- a/core/java/com/android/internal/service/wallpaper/ImageWallpaper.java
+++ b/core/java/com/android/internal/service/wallpaper/ImageWallpaper.java
@@ -21,6 +21,7 @@
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.service.wallpaper.WallpaperService;
+import android.util.Log;
 import android.view.SurfaceHolder;
 import android.content.Context;
 import android.content.IntentFilter;
@@ -63,12 +64,23 @@
 
     class DrawableEngine extends Engine {
         private final Object mLock = new Object();
+        private final Rect mBounds = new Rect();
         Drawable mBackground;
+        int mXOffset;
+        int mYOffset;
 
         @Override
         public void onCreate(SurfaceHolder surfaceHolder) {
             super.onCreate(surfaceHolder);
             mBackground = mWallpaperManager.getDrawable();
+            mBounds.left = mBounds.top = 0;
+            mBounds.right = mBackground.getIntrinsicWidth();
+            mBounds.bottom = mBackground.getIntrinsicHeight();
+            int offx = (getDesiredMinimumWidth() - mBounds.right) / 2;
+            int offy = (getDesiredMinimumHeight() - mBounds.bottom) / 2;
+            mBounds.offset(offx, offy);
+            mBackground.setBounds(mBounds);
+            surfaceHolder.setSizeFromLayout();
         }
 
         @Override
@@ -77,6 +89,14 @@
         }
         
         @Override
+        public void onOffsetsChanged(float xOffset, float yOffset,
+                int xPixels, int yPixels) {
+            mXOffset = xPixels;
+            mYOffset = yPixels;
+            drawFrame();
+        }
+
+        @Override
         public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
             super.onSurfaceChanged(holder, format, width, height);
             drawFrame();
@@ -94,19 +114,16 @@
         
         void drawFrame() {
             SurfaceHolder sh = getSurfaceHolder();
-            Canvas c = null;
-            try {
-                c = sh.lockCanvas();
-                if (c != null) {
-                    final Rect frame = sh.getSurfaceFrame();
-                    synchronized (mLock) {
-                        final Drawable background = mBackground;
-                        background.setBounds(frame);
-                        background.draw(c);
-                    }
+            Canvas c = sh.lockCanvas();
+            if (c != null) {
+                //final Rect frame = sh.getSurfaceFrame();
+                synchronized (mLock) {
+                    final Drawable background = mBackground;
+                    //background.setBounds(frame);
+                    c.translate(mXOffset, mYOffset);
+                    background.draw(c);
                 }
-            } finally {
-                if (c != null) sh.unlockCanvasAndPost(c);
+                sh.unlockCanvasAndPost(c);
             }
         }
 
diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java
index 7449067..a030db7 100644
--- a/core/java/com/android/internal/view/BaseIWindow.java
+++ b/core/java/com/android/internal/view/BaseIWindow.java
@@ -65,4 +65,7 @@
 
     public void executeCommand(String command, String parameters, ParcelFileDescriptor out) {
     }
+    
+    public void dispatchWallpaperOffsets(float x, float y) {
+    }
 }
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 641f251..b0f049e 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -1237,6 +1237,10 @@
                 curWallpaperIndex--;
                 WindowState wallpaper = token.windows.get(curWallpaperIndex);
                 
+                if (visible) {
+                    updateWallpaperOffsetLocked(mWallpaperTarget, wallpaper, dw, dh);                        
+                }
+                
                 // First, make sure the client has the current visibility
                 // state.
                 if (wallpaper.mWallpaperVisible != visible) {
@@ -1250,10 +1254,6 @@
                     }
                 }
                 
-                if (visible) {
-                    updateWallpaperOffsetLocked(mWallpaperTarget, wallpaper, dw, dh);                        
-                }
-                
                 wallpaper.mAnimLayer = wallpaper.mLayer + mWallpaperAnimLayerAdjustment;
                 if (DEBUG_LAYERS) Log.v(TAG, "Wallpaper win " + wallpaper
                         + " anim layer: " + wallpaper.mAnimLayer);
@@ -1306,18 +1306,35 @@
 
     boolean updateWallpaperOffsetLocked(WindowState target,
             WindowState wallpaperWin, int dw, int dh) {
-        int availw = wallpaperWin.mFrame.right-wallpaperWin.mFrame.left-dw;
-        int offset = availw > 0 ? -(int)(availw*target.mWallpaperX+.5f) : 0;
-        boolean changed = wallpaperWin.mXOffset != offset;
-        if (changed) {
-            wallpaperWin.mXOffset = offset;
+        boolean changed = false;
+        if (target.mWallpaperX >= 0) {
+            int availw = wallpaperWin.mFrame.right-wallpaperWin.mFrame.left-dw;
+            int offset = availw > 0 ? -(int)(availw*target.mWallpaperX+.5f) : 0;
+            changed = wallpaperWin.mXOffset != offset;
+            if (changed) {
+                wallpaperWin.mXOffset = offset;
+            }
         }
-        int availh = wallpaperWin.mFrame.bottom-wallpaperWin.mFrame.top-dh;
-        offset = availh > 0 ? -(int)(availh*target.mWallpaperY+.5f) : 0;
-        if (wallpaperWin.mYOffset != offset) {
-            changed = true;
-            wallpaperWin.mYOffset = offset;
+        if (target.mWallpaperY >= 0) {
+            int availh = wallpaperWin.mFrame.bottom-wallpaperWin.mFrame.top-dh;
+            int offset = availh > 0 ? -(int)(availh*target.mWallpaperY+.5f) : 0;
+            if (wallpaperWin.mYOffset != offset) {
+                changed = true;
+                wallpaperWin.mYOffset = offset;
+            }
         }
+        
+        if (wallpaperWin.mWallpaperX != target.mWallpaperX
+                || wallpaperWin.mWallpaperY != target.mWallpaperY) {
+            wallpaperWin.mWallpaperX = target.mWallpaperX;
+            wallpaperWin.mWallpaperY = target.mWallpaperY;
+            try {
+                wallpaperWin.mClient.dispatchWallpaperOffsets(
+                        wallpaperWin.mWallpaperX, wallpaperWin.mWallpaperY);
+            } catch (RemoteException e) {
+            }
+        }
+        
         return changed;
     }
     
@@ -5975,8 +5992,6 @@
         int mRequestedHeight;
         int mLastRequestedWidth;
         int mLastRequestedHeight;
-        int mXOffset;
-        int mYOffset;
         int mLayer;
         int mAnimLayer;
         int mLastLayer;
@@ -6061,8 +6076,14 @@
         boolean mHasLocalTransformation;
         final Transformation mTransformation = new Transformation();
 
-        float mWallpaperX = 0;
-        float mWallpaperY = 0;
+        // If a window showing a wallpaper: the requested offset for the
+        // wallpaper; if a wallpaper window: the currently applied offset.
+        float mWallpaperX = -1;
+        float mWallpaperY = -1;
+        
+        // Wallpaper windows: pixels offset based on above variables.
+        int mXOffset;
+        int mYOffset;
         
         // This is set after IWindowSession.relayout() has been called at
         // least once for the window.  It allows us to detect the situation
@@ -7181,7 +7202,7 @@
                 pw.print(prefix); pw.print("mHScale="); pw.print(mHScale);
                         pw.print(" mVScale="); pw.println(mVScale);
             }
-            if (mWallpaperX != 0 || mWallpaperY != 0) {
+            if (mWallpaperX != -1 || mWallpaperY != -1) {
                 pw.print(prefix); pw.print("mWallpaperX="); pw.print(mWallpaperX);
                         pw.print(" mWallpaperY="); pw.println(mWallpaperY);
             }
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index a877c73..13713e5 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -26,8 +26,11 @@
 import android.text.Editable;
 import android.text.SpannableStringBuilder;
 import android.text.TextUtils;
+import android.util.Log;
 import android.util.SparseIntArray;
 
+import static com.android.internal.telephony.TelephonyProperties.PROPERTY_IDP_STRING;
+
 import java.util.Locale;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -57,6 +60,9 @@
     public static final int TOA_International = 0x91;
     public static final int TOA_Unknown = 0x81;
 
+    static final String LOG_TAG = "PhoneNumberUtils";
+    private static final boolean DBG = false;
+
     /*
      * global-phone-number = ["+"] 1*( DIGIT / written-sep )
      * written-sep         = ("-"/".")
@@ -227,6 +233,9 @@
         }
     }
 
+    private static void log(String msg) {
+        Log.d(LOG_TAG, msg);
+    }
     /** index of the last character of the network portion
      *  (eg anything after is a post-dial string)
      */
@@ -741,6 +750,14 @@
         return true;
     }
 
+    private static boolean isNonSeparator(String address) {
+        for (int i = 0, count = address.length(); i < count; i++) {
+            if (!isNonSeparator(address.charAt(i))) {
+                return false;
+            }
+        }
+        return true;
+    }
     /**
      * Note: calls extractNetworkPortion(), so do not use for
      * SIM EF[ADN] style records
@@ -1229,4 +1246,261 @@
         KEYPAD_MAP.put('w', '9'); KEYPAD_MAP.put('x', '9'); KEYPAD_MAP.put('y', '9'); KEYPAD_MAP.put('z', '9');
         KEYPAD_MAP.put('W', '9'); KEYPAD_MAP.put('X', '9'); KEYPAD_MAP.put('Y', '9'); KEYPAD_MAP.put('Z', '9');
     }
+
+    //================ Plus Code formatting =========================
+    private static final char PLUS_SIGN_CHAR = '+';
+    private static final String PLUS_SIGN_STRING = "+";
+    private static final String NANP_IDP_STRING = "011";
+    private static final int NANP_LENGTH = 10;
+
+    /**
+     * This function checks if there is a plus sign (+) in the passed-in dialing number.
+     * If there is, it processes the plus sign based on the default telephone
+     * numbering plan of the system when the phone is activated and the current
+     * telephone numbering plan of the system that the phone is camped on.
+     * Currently, we only support the case that the default and current telephone
+     * numbering plans are North American Numbering Plan(NANP).
+     *
+     * The passed-in dialStr should only contain the valid format as described below,
+     * 1) the 1st character in the dialStr should be one of the really dialable
+     *    characters listed below
+     *    ISO-LATIN characters 0-9, *, # , +
+     * 2) the dialStr should already strip out the separator characters,
+     *    every character in the dialStr should be one of the non separator characters
+     *    listed below
+     *    ISO-LATIN characters 0-9, *, # , +, WILD, WAIT, PAUSE
+     *
+     * Otherwise, this function returns the dial string passed in
+     *
+     * This API is for CDMA only
+     *
+     * @hide TODO: pending API Council approval
+     */
+    public static String cdmaCheckAndProcessPlusCode(String dialStr) {
+        if (!TextUtils.isEmpty(dialStr)) {
+            if (isReallyDialable(dialStr.charAt(0)) &&
+                isNonSeparator(dialStr)) {
+                return cdmaCheckAndProcessPlusCodeByNumberFormat(dialStr,
+                        getFormatTypeForLocale(Locale.getDefault()));
+            }
+        }
+        return dialStr;
+    }
+
+    /**
+     * This function should be called from checkAndProcessPlusCode only
+     * And it is used for test purpose also.
+     *
+     * It checks the dial string by looping through the network portion,
+     * post dial portion 1, post dial porting 2, etc. If there is any
+     * plus sign, then process the plus sign.
+     * Currently, this function supports the plus sign conversion within NANP only.
+     * Specifically, it handles the plus sign in the following ways:
+     * 1)+NANP or +1NANP,remove +, e.g.
+     *   +8475797000 is converted to 8475797000,
+     *   +18475797000 is converted to 18475797000,
+     * 2)+non-NANP Numbers,replace + with the current NANP IDP, e.g,
+     *   +11875767800 is converted to 01111875767800
+     * 3)+NANP in post dial string(s), e.g.
+     *   8475797000;+8475231753 is converted to 8475797000;8475231753
+     *
+     * This function returns the original dial string if locale/numbering plan
+     * aren't supported.
+     *
+     * @hide
+     */
+    public static String cdmaCheckAndProcessPlusCodeByNumberFormat(String dialStr,int numFormat) {
+        String retStr = dialStr;
+
+        // Checks if the plus sign character is in the passed-in dial string
+        if (dialStr != null &&
+            dialStr.lastIndexOf(PLUS_SIGN_STRING) != -1) {
+
+            String postDialStr = null;
+            String tempDialStr = dialStr;
+
+            // Sets the retStr to null since the conversion will be performed below.
+            retStr = null;
+            if (DBG) log("checkAndProcessPlusCode,dialStr=" + dialStr);
+            // This routine is to process the plus sign in the dial string by loop through
+            // the network portion, post dial portion 1, post dial portion 2... etc. if
+            // applied
+            do {
+                String networkDialStr;
+
+                // Format the string based on the rules for the country the number is from
+                if (numFormat != FORMAT_NANP) {
+                    // TODO: to support NANP international conversion and
+                    // other telephone numbering plan
+                    // Currently the phone is ever used in non-NANP system
+                    // return the original dial string
+                    Log.e("checkAndProcessPlusCode:non-NANP not supported", dialStr);
+                    return dialStr;
+                } else {
+                    // For the case that the default and current telephone
+                    // numbering plans are NANP
+                    networkDialStr = extractNetworkPortion(tempDialStr);
+                    // Handles the conversion within NANP
+                    networkDialStr = processPlusCodeWithinNanp(networkDialStr);
+                }
+                // Concatenates the string that is converted from network portion
+                if (!TextUtils.isEmpty(networkDialStr)) {
+                    if (retStr == null) {
+                        retStr = networkDialStr;
+                    } else {
+                        retStr = retStr.concat(networkDialStr);
+                    }
+                } else {
+                    // This should never happen since we checked the if dialStr is null
+                    // and if it contains the plus sign in the begining of this function.
+                    // The plus sign is part of the network portion.
+                    Log.e("checkAndProcessPlusCode: null newDialStr", networkDialStr);
+                    return dialStr;
+                }
+                postDialStr = extractPostDialPortion(tempDialStr);
+                if (!TextUtils.isEmpty(postDialStr)) {
+                    int dialableIndex = findDialableIndexFromPostDialStr(postDialStr);
+
+                    // dialableIndex should always be greater than 0
+                    if (dialableIndex >= 1) {
+                        retStr = appendPwCharBackToOrigDialStr(dialableIndex,
+                                 retStr,postDialStr);
+                        // Skips the P/W character, extracts the dialable portion
+                        tempDialStr = postDialStr.substring(dialableIndex);
+                    } else {
+                        // Non-dialable character such as P/W should not be at the end of
+                        // the dial string after P/W processing in CdmaConnection.java
+                        // Set the postDialStr to "" to break out of the loop
+                        if (dialableIndex < 0) {
+                            postDialStr = "";
+                        }
+                        Log.e("wrong postDialStr=", postDialStr);
+                    }
+                }
+                if (DBG) log("checkAndProcessPlusCode,postDialStr=" + postDialStr);
+            } while (!TextUtils.isEmpty(postDialStr) && !TextUtils.isEmpty(tempDialStr));
+        }
+        return retStr;
+     }
+
+    // This function gets the default international dialing prefix
+    private static String getDefaultIdp( ) {
+        String ps = null;
+        SystemProperties.get(PROPERTY_IDP_STRING, ps);
+        if (TextUtils.isEmpty(ps)) {
+            ps = NANP_IDP_STRING;
+        }
+        return ps;
+    }
+
+    private static boolean isTwoToNine (char c) {
+        if (c >= '2' && c <= '9') {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * This function checks if the passed in string conforms to the NANP format
+     * i.e. NXX-NXX-XXXX, N is any digit 2-9 and X is any digit 0-9
+     */
+    private static boolean isNanp (String dialStr) {
+        boolean retVal = false;
+        if (dialStr != null) {
+            if (dialStr.length() == NANP_LENGTH) {
+                if (isTwoToNine(dialStr.charAt(0)) &&
+                    isTwoToNine(dialStr.charAt(3))) {
+                    retVal = true;
+                    for (int i=1; i<NANP_LENGTH; i++ ) {
+                        char c=dialStr.charAt(i);
+                        if (!PhoneNumberUtils.isISODigit(c)) {
+                            retVal = false;
+                            break;
+                        }
+                    }
+                }
+            }
+        } else {
+            Log.e("isNanp: null dialStr passed in", dialStr);
+        }
+        return retVal;
+    }
+
+   /**
+    * This function checks if the passed in string conforms to 1-NANP format
+    */
+    private static boolean isOneNanp(String dialStr) {
+        boolean retVal = false;
+        if (dialStr != null) {
+            String newDialStr = dialStr.substring(1);
+            if ((dialStr.charAt(0) == '1') && isNanp(newDialStr)) {
+                retVal = true;
+            }
+        } else {
+            Log.e("isOneNanp: null dialStr passed in", dialStr);
+        }
+        return retVal;
+    }
+
+    /**
+     * This function handles the plus code conversion within NANP CDMA network
+     * If the number format is
+     * 1)+NANP or +1NANP,remove +,
+     * 2)+non-NANP Numbers,replace + with the current IDP
+     */
+    private static String processPlusCodeWithinNanp(String networkDialStr) {
+        String retStr = networkDialStr;
+
+        if (DBG) log("processPlusCodeWithinNanp,networkDialStr=" + networkDialStr);
+        // If there is a plus sign at the beginning of the dial string,
+        // Convert the plus sign to the default IDP since it's an international number
+        if (networkDialStr != null &
+            networkDialStr.charAt(0) == PLUS_SIGN_CHAR &&
+            networkDialStr.length() > 1) {
+            String newStr = networkDialStr.substring(1);
+            if (isNanp(newStr) || isOneNanp(newStr)) {
+                // Remove the leading plus sign
+                retStr = newStr;
+             } else {
+                 String idpStr = getDefaultIdp();
+                 // Replaces the plus sign with the default IDP
+                 retStr = networkDialStr.replaceFirst("[+]", idpStr);
+            }
+        }
+        if (DBG) log("processPlusCodeWithinNanp,retStr=" + retStr);
+        return retStr;
+    }
+
+    // This function finds the index of the dialable character(s)
+    // in the post dial string
+    private static int findDialableIndexFromPostDialStr(String postDialStr) {
+        for (int index = 0;index < postDialStr.length();index++) {
+             char c = postDialStr.charAt(index);
+             if (isReallyDialable(c)) {
+                return index;
+             }
+        }
+        return -1;
+    }
+
+    // This function appends the non-diablable P/W character to the original
+    // dial string based on the dialable index passed in
+    private static String
+    appendPwCharBackToOrigDialStr(int dialableIndex,String origStr, String dialStr) {
+        String retStr;
+
+        // There is only 1 P/W character before the dialable characters
+        if (dialableIndex == 1) {
+            StringBuilder ret = new StringBuilder(origStr);
+            ret = ret.append(dialStr.charAt(0));
+            retStr = ret.toString();
+        } else {
+            // It means more than 1 P/W characters in the post dial string,
+            // appends to retStr
+            String nonDigitStr = dialStr.substring(0,dialableIndex);
+            retStr = origStr.concat(nonDigitStr);
+        }
+        return retStr;
+    }
 }
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java b/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
old mode 100644
new mode 100755
index 69ef0e3..0c94e6a
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
@@ -818,15 +818,12 @@
         return c == PhoneNumberUtils.WAIT;
     }
 
-
-
-
     // This function is to find the next PAUSE character index if
     // multiple pauses in a row. Otherwise it finds the next non PAUSE or
     // non WAIT character index.
     private static int
     findNextPCharOrNonPOrNonWCharIndex(String phoneNumber, int currIndex) {
-        boolean wMatched = false;
+        boolean wMatched = isWait(phoneNumber.charAt(currIndex));
         int index = currIndex + 1;
         int length = phoneNumber.length();
         while (index < length) {
@@ -863,17 +860,17 @@
         // Append the PW char
         ret = (isPause(c)) ? PhoneNumberUtils.PAUSE : PhoneNumberUtils.WAIT;
 
-        // if there is a PAUSE in at the begining of PW character sequences, and this
-        // PW character sequences has more than 2 PAUSE and WAIT Characters,skip P, append W
-        if (isPause(c) &&  (nextNonPwCharIndex > (currPwIndex + 1))) {
+        // if there is a PAUSE in at the beginning of PW character sequences, and this
+        // PW character sequences has more than 2 PAUSE and WAIT Characters,skip PAUSE,
+        // append WAIT.
+        if (isPause(c) && (nextNonPwCharIndex > (currPwIndex + 2))) {
             ret = PhoneNumberUtils.WAIT;
         }
         return ret;
     }
 
-
     /**
-     * format orignal dial string
+     * format original dial string
      * 1) convert international dialing prefix "+" to
      *    string specified per region
      *
@@ -892,20 +889,10 @@
         StringBuilder ret = new StringBuilder();
         char c;
         int currIndex = 0;
+
         while (currIndex < length) {
             c = phoneNumber.charAt(currIndex);
-            if (PhoneNumberUtils.isDialable(c)) {
-                if (c == '+') {
-                    String ps = null;
-                    SystemProperties.get(TelephonyProperties.PROPERTY_IDP_STRING, ps);
-                    if (TextUtils.isEmpty(ps)) {
-                        ps = "011";
-                    }
-                    ret.append(ps);
-                } else {
-                    ret.append(c);
-                }
-            } else if (isPause(c) || isWait(c)) {
+            if (isPause(c) || isWait(c)) {
                 if (currIndex < length - 1) {
                     // if PW not at the end
                     int nextIndex = findNextPCharOrNonPOrNonWCharIndex(phoneNumber, currIndex);
@@ -913,8 +900,10 @@
                     if (nextIndex < length) {
                         char pC = findPOrWCharToAppend(phoneNumber, currIndex, nextIndex);
                         ret.append(pC);
-                        // If PW char is immediately followed by non-PW char
-                        if (nextIndex > (currIndex + 1)) {
+                        // If PW char sequence has more than 2 PW characters,
+                        // skip to the last character since the sequence already be
+                        // converted to WAIT character
+                        if (nextIndex > (currIndex + 2)) {
                             currIndex = nextIndex - 1;
                         }
                     } else if (nextIndex == length) {
@@ -927,7 +916,7 @@
             }
             currIndex++;
         }
-        return ret.toString();
+        return PhoneNumberUtils.cdmaCheckAndProcessPlusCode(ret.toString());
     }
 
     private void log(String msg) {
diff --git a/tests/CoreTests/com/android/internal/telephony/PhoneNumberUtilsTest.java b/tests/CoreTests/com/android/internal/telephony/PhoneNumberUtilsTest.java
index ff73b32..466b555 100644
--- a/tests/CoreTests/com/android/internal/telephony/PhoneNumberUtilsTest.java
+++ b/tests/CoreTests/com/android/internal/telephony/PhoneNumberUtilsTest.java
@@ -335,4 +335,73 @@
         assertEquals("(800) 222-3334",
                      PhoneNumberUtils.convertKeypadLettersToDigits("(800) ABC-DEFG"));
     }
+
+    @SmallTest
+    public void testCheckAndProcessPlusCode() {
+        assertEquals("8475797000",
+                PhoneNumberUtils.cdmaCheckAndProcessPlusCode("+8475797000"));
+        assertEquals("18475797000",
+                PhoneNumberUtils.cdmaCheckAndProcessPlusCode("+18475797000"));
+        assertEquals("0111234567",
+                PhoneNumberUtils.cdmaCheckAndProcessPlusCode("+1234567"));
+        assertEquals("01123456700000",
+                PhoneNumberUtils.cdmaCheckAndProcessPlusCode("+23456700000"));
+        assertEquals("01111875767800",
+                PhoneNumberUtils.cdmaCheckAndProcessPlusCode("+11875767800"));
+        assertEquals("8475797000,18475231753",
+                PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000,+18475231753"));
+        assertEquals("8475797000,18475231753",
+                PhoneNumberUtils.cdmaCheckAndProcessPlusCode("+8475797000,+18475231753"));
+        assertEquals("8475797000;8475231753",
+                PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000;+8475231753"));
+        assertEquals("8475797000,0111234567",
+                PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000,+1234567"));
+        assertEquals("847597000;01111875767000",
+                PhoneNumberUtils.cdmaCheckAndProcessPlusCode("847597000;+11875767000"));
+        assertEquals("8475797000,,8475231753",
+                PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000,,+8475231753"));
+        assertEquals("8475797000;,8475231753",
+                PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000;,+8475231753"));
+        assertEquals("8475797000,;18475231753",
+                PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000,;+18475231753"));
+        assertEquals("8475797000;,01111875767000",
+                PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000;,+11875767000"));
+        assertEquals("8475797000,;01111875767000",
+                PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000,;+11875767000"));
+        assertEquals("8475797000,,,01111875767000",
+                PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000,,,+11875767000"));
+        assertEquals("8475797000;,,01111875767000",
+                PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000;,,+11875767000"));
+        assertEquals("+;,8475797000",
+                PhoneNumberUtils.cdmaCheckAndProcessPlusCode("+;,8475797000"));
+        assertEquals("8475797000,",
+                PhoneNumberUtils.cdmaCheckAndProcessPlusCode("8475797000,"));
+        assertEquals("847+579-7000",
+                PhoneNumberUtils.cdmaCheckAndProcessPlusCode("847+579-7000"));
+        assertEquals(",8475797000",
+                PhoneNumberUtils.cdmaCheckAndProcessPlusCode(",8475797000"));
+        assertEquals(";;8475797000,,",
+                PhoneNumberUtils.cdmaCheckAndProcessPlusCode(";;8475797000,,"));
+        assertEquals("+this+is$weird;,+",
+                PhoneNumberUtils.cdmaCheckAndProcessPlusCode("+this+is$weird;,+"));
+        assertEquals("",
+                PhoneNumberUtils.cdmaCheckAndProcessPlusCode(""));
+        assertNull(PhoneNumberUtils.cdmaCheckAndProcessPlusCode(null));
+    }
+
+    @SmallTest
+    public void testCheckAndProcessPlusCodeByNumberFormat() {
+        assertEquals("+8475797000",
+                PhoneNumberUtils.cdmaCheckAndProcessPlusCodeByNumberFormat("+8475797000",
+                PhoneNumberUtils.FORMAT_JAPAN));
+        assertEquals("+0384756700",
+                PhoneNumberUtils.cdmaCheckAndProcessPlusCodeByNumberFormat("+0384756700",
+                PhoneNumberUtils.FORMAT_JAPAN));
+        assertEquals("+1234567",
+                PhoneNumberUtils.cdmaCheckAndProcessPlusCodeByNumberFormat("+1234567",
+                PhoneNumberUtils.FORMAT_UNKNOWN));
+        assertEquals("+23456700000",
+                PhoneNumberUtils.cdmaCheckAndProcessPlusCodeByNumberFormat("+23456700000",
+                PhoneNumberUtils.FORMAT_UNKNOWN));
+    }
 }
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 8e7d48f..8d44ac08 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
@@ -1047,6 +1047,11 @@
             // pass for now.
         }
 
+        @SuppressWarnings("unused")
+        public void dispatchWallpaperOffsets(float x, float y) {
+            // pass for now.
+        }
+
         public IBinder asBinder() {
             // pass for now.
             return null;