Merge change 26047 into eclair

* changes:
  Fix up the first-backup-ever tracking
diff --git a/api/current.xml b/api/current.xml
index 0495764..bb13bf0 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -61135,6 +61135,17 @@
  visibility="public"
 >
 </field>
+<field name="YCbCr_422_I"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="20"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="YCbCr_422_SP"
  type="int"
  transient="false"
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index c1b9f28..7366b8b 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2531,6 +2531,7 @@
      *
      * @param uri The URI to turn into an Intent.
      * @param flags Additional processing flags.  Either 0 or
+     * {@link #URI_INTENT_SCHEME}.
      *
      * @return Intent The newly created Intent object.
      *
@@ -2664,24 +2665,24 @@
 
         int i = uri.lastIndexOf('#');
         if (i >= 0) {
-            Uri data = null;
             String action = null;
-            if (i > 0) {
-                data = Uri.parse(uri.substring(0, i));
-            }
+            final int intentFragmentStart = i;
+            boolean isIntentFragment = false;
 
             i++;
 
             if (uri.regionMatches(i, "action(", 0, 7)) {
+                isIntentFragment = true;
                 i += 7;
                 int j = uri.indexOf(')', i);
                 action = uri.substring(i, j);
                 i = j + 1;
             }
 
-            intent = new Intent(action, data);
+            intent = new Intent(action);
 
             if (uri.regionMatches(i, "categories(", 0, 11)) {
+                isIntentFragment = true;
                 i += 11;
                 int j = uri.indexOf(')', i);
                 while (i < j) {
@@ -2696,6 +2697,7 @@
             }
 
             if (uri.regionMatches(i, "type(", 0, 5)) {
+                isIntentFragment = true;
                 i += 5;
                 int j = uri.indexOf(')', i);
                 intent.mType = uri.substring(i, j);
@@ -2703,6 +2705,7 @@
             }
 
             if (uri.regionMatches(i, "launchFlags(", 0, 12)) {
+                isIntentFragment = true;
                 i += 12;
                 int j = uri.indexOf(')', i);
                 intent.mFlags = Integer.decode(uri.substring(i, j)).intValue();
@@ -2710,6 +2713,7 @@
             }
 
             if (uri.regionMatches(i, "component(", 0, 10)) {
+                isIntentFragment = true;
                 i += 10;
                 int j = uri.indexOf(')', i);
                 int sep = uri.indexOf('!', i);
@@ -2722,6 +2726,7 @@
             }
 
             if (uri.regionMatches(i, "extras(", 0, 7)) {
+                isIntentFragment = true;
                 i += 7;
 
                 final int closeParen = uri.indexOf(')', i);
@@ -2793,6 +2798,12 @@
                 }
             }
 
+            if (isIntentFragment) {
+                intent.mData = Uri.parse(uri.substring(0, intentFragmentStart));
+            } else {
+                intent.mData = Uri.parse(uri);
+            }
+            
             if (intent.mAction == null) {
                 // By default, if no action is specified, then use VIEW.
                 intent.mAction = ACTION_VIEW;
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 13effe0..a27307a 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -673,6 +673,7 @@
         // Formats for setPreviewFormat and setPictureFormat.
         private static final String PIXEL_FORMAT_YUV422SP = "yuv422sp";
         private static final String PIXEL_FORMAT_YUV420SP = "yuv420sp";
+        private static final String PIXEL_FORMAT_YUV422I = "yuv422i-yuyv";
         private static final String PIXEL_FORMAT_RGB565 = "rgb565";
         private static final String PIXEL_FORMAT_JPEG = "jpeg";
 
@@ -957,7 +958,13 @@
          */
         public List<Integer> getSupportedPreviewFormats() {
             String str = get(KEY_PREVIEW_FORMAT + SUPPORTED_VALUES_SUFFIX);
-            return splitInt(str);
+            ArrayList<Integer> formats = new ArrayList<Integer>();
+            for (String s : split(str)) {
+                int f = pixelFormatForCameraFormat(s);
+                if (f == PixelFormat.UNKNOWN) continue;
+                formats.add(f);
+            }
+            return formats;
         }
 
         /**
@@ -1036,6 +1043,7 @@
             switch(pixel_format) {
             case PixelFormat.YCbCr_422_SP: return PIXEL_FORMAT_YUV422SP;
             case PixelFormat.YCbCr_420_SP: return PIXEL_FORMAT_YUV420SP;
+            case PixelFormat.YCbCr_422_I:  return PIXEL_FORMAT_YUV422I;
             case PixelFormat.RGB_565:      return PIXEL_FORMAT_RGB565;
             case PixelFormat.JPEG:         return PIXEL_FORMAT_JPEG;
             default:                       return null;
@@ -1052,6 +1060,9 @@
             if (format.equals(PIXEL_FORMAT_YUV420SP))
                 return PixelFormat.YCbCr_420_SP;
 
+            if (format.equals(PIXEL_FORMAT_YUV422I))
+                return PixelFormat.YCbCr_422_I;
+
             if (format.equals(PIXEL_FORMAT_RGB565))
                 return PixelFormat.RGB_565;
 
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index ba0a0d4..84c11e6 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -266,8 +266,8 @@
         }
         String name = propValues[0];
         if (name.equals("Name")) {
-            Intent intent = new Intent(BluetoothDevice.ACTION_NAME_CHANGED);
-            intent.putExtra(BluetoothDevice.EXTRA_NAME, propValues[1]);
+            Intent intent = new Intent(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
+            intent.putExtra(BluetoothAdapter.EXTRA_LOCAL_NAME, propValues[1]);
             mContext.sendBroadcast(intent, BLUETOOTH_PERM);
             mBluetoothService.setProperty(name, propValues[1]);
         } else if (name.equals("Pairable") || name.equals("Discoverable")) {
diff --git a/core/java/com/android/internal/widget/RotarySelector.java b/core/java/com/android/internal/widget/RotarySelector.java
index 750b2a9..f610211 100644
--- a/core/java/com/android/internal/widget/RotarySelector.java
+++ b/core/java/com/android/internal/widget/RotarySelector.java
@@ -25,6 +25,7 @@
 import android.util.Log;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.SoundEffectConstants;
 import android.view.animation.AccelerateInterpolator;
 import static android.view.animation.AnimationUtils.currentAnimationTimeMillis;
 import com.android.internal.R;
@@ -65,8 +66,9 @@
     // state of the animation used to bring the handle back to its start position when
     // the user lets go before triggering an action
     private boolean mAnimating = false;
-    private long mAnimationEndTime;
-    private int mAnimatingDelta;
+    private long mAnimationStartTime; // set to the end point of the animatino
+    private long mAnimationDuration;
+    private int mAnimatingDeltaXStart;   // the animation will interpolate from this delta down to zero
     private AccelerateInterpolator mInterpolator;
 
     /**
@@ -102,14 +104,15 @@
     /**
      * How far from the edge of the screen the user must drag to trigger the event.
      */
-    private static final int EDGE_TRIGGER_DIP = 65;
+    private static final int EDGE_TRIGGER_DIP = 100;
 
     /**
      * Dimensions of arc in background drawable.
      */
     static final int OUTER_ROTARY_RADIUS_DIP = 390;
     static final int ROTARY_STROKE_WIDTH_DIP = 83;
-    private static final int ANIMATION_DURATION_MILLIS = 300;
+    static final int SNAP_BACK_ANIMATION_DURATION_MILLIS = 300;
+    static final int SPIN_ANIMATION_DURATION_MILLIS = 800;
 
     private static final boolean DRAW_CENTER_DIMPLE = false;
     private int mEdgeTriggerThresh;
@@ -249,14 +252,19 @@
 
         // update animating state before we draw anything
         if (mAnimating) {
-            long millisLeft = mAnimationEndTime - currentAnimationTimeMillis();
+            final long millisSoFar = currentAnimationTimeMillis() - mAnimationStartTime;
+            final long millisLeft = mAnimationDuration - millisSoFar;
             if (DBG) log("millisleft for animating: " + millisLeft);
             if (millisLeft <= 0) {
                 reset();
             } else {
+                // we always use the snap back duration as the denominator for interpolation
+                // to get a consistent velocity (bascially this makes us happy for the snap back
+                // and the spin around one).
+                final long denom = SNAP_BACK_ANIMATION_DURATION_MILLIS; // mAnimationDuration
                 float interpolation = mInterpolator.getInterpolation(
-                        (float) millisLeft / ANIMATION_DURATION_MILLIS);
-                mTouchDragOffset = (int) (mAnimatingDelta * interpolation);
+                        (float) millisLeft / denom);
+                mTouchDragOffset = (int) (mAnimatingDeltaXStart * interpolation);
             }
         }
 
@@ -423,8 +431,9 @@
                         dispatchTriggerEvent(OnDialTriggerListener.LEFT_HANDLE);
                         // set up "spin around animation"
                         mAnimating = true;
-                        mAnimationEndTime = currentAnimationTimeMillis() + ANIMATION_DURATION_MILLIS;
-                        mAnimatingDelta = -mBackgroundWidth;
+                        mAnimationStartTime = currentAnimationTimeMillis();
+                        mAnimationDuration = SPIN_ANIMATION_DURATION_MILLIS;
+                        mAnimatingDeltaXStart = -mBackgroundWidth*3;
                         mTouchDragOffset = 0;
                         mGrabbedState = NOTHING_GRABBED;
                         invalidate();
@@ -438,8 +447,9 @@
                         dispatchTriggerEvent(OnDialTriggerListener.RIGHT_HANDLE);
                         // set up "spin around animation"
                         mAnimating = true;
-                        mAnimationEndTime = currentAnimationTimeMillis() + ANIMATION_DURATION_MILLIS;
-                        mAnimatingDelta = mBackgroundWidth;
+                        mAnimationStartTime = currentAnimationTimeMillis();
+                        mAnimationDuration = SPIN_ANIMATION_DURATION_MILLIS;
+                        mAnimatingDeltaXStart = mBackgroundWidth*3;
                         mTouchDragOffset = 0;
                         mGrabbedState = NOTHING_GRABBED;
                         invalidate();
@@ -453,14 +463,16 @@
                         && Math.abs(eventX - mLeftHandleX) > 5) {
                     // set up "snap back" animation
                     mAnimating = true;
-                    mAnimationEndTime = currentAnimationTimeMillis() + ANIMATION_DURATION_MILLIS;
-                    mAnimatingDelta = eventX - mLeftHandleX;
+                    mAnimationStartTime = currentAnimationTimeMillis();
+                    mAnimationDuration = SNAP_BACK_ANIMATION_DURATION_MILLIS;
+                    mAnimatingDeltaXStart = eventX - mLeftHandleX;
                 } else if (mGrabbedState == RIGHT_HANDLE_GRABBED
                         && Math.abs(eventX - mRightHandleX) > 5) {
                     // set up "snap back" animation
                     mAnimating = true;
-                    mAnimationEndTime = currentAnimationTimeMillis() + ANIMATION_DURATION_MILLIS;
-                    mAnimatingDelta = eventX - mRightHandleX;
+                    mAnimationStartTime = currentAnimationTimeMillis();
+                    mAnimationDuration = SNAP_BACK_ANIMATION_DURATION_MILLIS;
+                    mAnimatingDeltaXStart = eventX - mRightHandleX;
                 }
 
                 mTouchDragOffset = 0;
diff --git a/graphics/java/android/graphics/PixelFormat.java b/graphics/java/android/graphics/PixelFormat.java
index 221c2f8..c76cee7 100644
--- a/graphics/java/android/graphics/PixelFormat.java
+++ b/graphics/java/android/graphics/PixelFormat.java
@@ -60,6 +60,13 @@
      */
     public static final int YCbCr_420_SP= 0x11;
 
+    /** YCbCr format used for images, which uses YUYV (YUY2) encoding format.
+     *  This is an alternative format for camera preview images. Whether this
+     *  format is supported by the camera hardware can be determined by
+     *  {@link android.hardware.Camera.Parameters#getSupportedPreviewFormats()}.
+     */
+    public static final int YCbCr_422_I = 0x14;
+
     /**
      * Encoded formats.  These are not necessarily supported by the hardware.
      */
diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp
index f80843d..a5a8cc9 100644
--- a/libs/utils/ResourceTypes.cpp
+++ b/libs/utils/ResourceTypes.cpp
@@ -1740,7 +1740,11 @@
     const int e = Res_GETENTRY(resID);
 
     if (p < 0) {
-        LOGW("No package identifier when getting name for resource number 0x%08x", resID);
+        if (Res_GETPACKAGE(resID)+1 == 0) {
+            LOGW("No package identifier when getting name for resource number 0x%08x", resID);
+        } else {
+            LOGW("Resources don't contain pacakge for resource number 0x%08x", resID);
+        }
         return false;
     }
     if (t < 0) {
@@ -1786,7 +1790,11 @@
     const int e = Res_GETENTRY(resID);
 
     if (p < 0) {
-        LOGW("No package identifier when getting value for resource number 0x%08x", resID);
+        if (Res_GETPACKAGE(resID)+1 == 0) {
+            LOGW("No package identifier when getting name for resource number 0x%08x", resID);
+        } else {
+            LOGW("Resources don't contain pacakge for resource number 0x%08x", resID);
+        }
         return BAD_INDEX;
     }
     if (t < 0) {
diff --git a/obex/javax/obex/HeaderSet.java b/obex/javax/obex/HeaderSet.java
index 8b457f6..b89b707 100644
--- a/obex/javax/obex/HeaderSet.java
+++ b/obex/javax/obex/HeaderSet.java
@@ -35,7 +35,7 @@
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.util.Calendar;
-import java.util.Random;
+import java.security.SecureRandom;
 
 /**
  * This class implements the javax.obex.HeaderSet interface for OBEX over
@@ -209,7 +209,7 @@
 
     private Long[] mIntegerUserDefined; // 4 byte unsigned integer
 
-    private final Random mRandom;
+    private final SecureRandom mRandom;
 
     /*package*/ byte[] nonce;
 
@@ -231,7 +231,7 @@
         mByteUserDefined = new Byte[16];
         mIntegerUserDefined = new Long[16];
         responseCode = -1;
-        mRandom = new Random();
+        mRandom = new SecureRandom();
     }
 
     /**
diff --git a/telephony/java/com/android/internal/telephony/BaseCommands.java b/telephony/java/com/android/internal/telephony/BaseCommands.java
index 3edca66..52f25f6 100644
--- a/telephony/java/com/android/internal/telephony/BaseCommands.java
+++ b/telephony/java/com/android/internal/telephony/BaseCommands.java
@@ -64,6 +64,7 @@
     protected RegistrantList mLineControlInfoRegistrants = new RegistrantList();
     protected RegistrantList mT53ClirInfoRegistrants = new RegistrantList();
     protected RegistrantList mT53AudCntrlInfoRegistrants = new RegistrantList();
+    protected RegistrantList mRingbackToneRegistrants = new RegistrantList();
 
     protected Registrant mSMSRegistrant;
     protected Registrant mNITZTimeRegistrant;
@@ -569,6 +570,15 @@
         mT53AudCntrlInfoRegistrants.remove(h);
     }
 
+    public void registerForRingbackTone(Handler h, int what, Object obj) {
+        Registrant r = new Registrant (h, what, obj);
+        mRingbackToneRegistrants.add(r);
+    }
+
+    public void unregisterForRingbackTone(Handler h) {
+        mRingbackToneRegistrants.remove(h);
+    }
+
     //***** Protected Methods
     /**
      * Store new RadioState and send notification based on the changes
diff --git a/telephony/java/com/android/internal/telephony/CommandsInterface.java b/telephony/java/com/android/internal/telephony/CommandsInterface.java
index 63bdc2c..9d83556 100644
--- a/telephony/java/com/android/internal/telephony/CommandsInterface.java
+++ b/telephony/java/com/android/internal/telephony/CommandsInterface.java
@@ -525,6 +525,17 @@
      void registerForCdmaOtaProvision(Handler h,int what, Object obj);
      void unregisterForCdmaOtaProvision(Handler h);
 
+     /**
+      * Registers the handler when out-band ringback tone is needed.<p>
+      *
+      *  Messages received from this:
+      *  Message.obj will be an AsyncResult
+      *  AsyncResult.userObj = obj
+      *  AsyncResult.result = boolean. <p>
+      */
+     void registerForRingbackTone(Handler h, int what, Object obj);
+     void unregisterForRingbackTone(Handler h);
+
     /**
      * Supply the ICC PIN to the ICC card
      *
diff --git a/telephony/java/com/android/internal/telephony/Phone.java b/telephony/java/com/android/internal/telephony/Phone.java
index f32837f..fffd128 100644
--- a/telephony/java/com/android/internal/telephony/Phone.java
+++ b/telephony/java/com/android/internal/telephony/Phone.java
@@ -379,6 +379,23 @@
 
     void unregisterForIncomingRing(Handler h);
 
+    /**
+     * Notifies when out-band ringback tone is needed.<p>
+     *
+     *  Messages received from this:
+     *  Message.obj will be an AsyncResult
+     *  AsyncResult.userObj = obj
+     *  AsyncResult.result = boolean, true to start play ringback tone
+     *                       and false to stop. <p>
+     */
+    void registerForRingbackTone(Handler h, int what, Object obj);
+
+    /**
+     * Unregisters for ringback tone notification.
+     */
+
+    void unregisterForRingbackTone(Handler h);
+
 
     /**
      * Notifies when a voice connection has disconnected, either due to local
diff --git a/telephony/java/com/android/internal/telephony/PhoneBase.java b/telephony/java/com/android/internal/telephony/PhoneBase.java
index e340f85..1c62a82 100644
--- a/telephony/java/com/android/internal/telephony/PhoneBase.java
+++ b/telephony/java/com/android/internal/telephony/PhoneBase.java
@@ -482,6 +482,16 @@
         mServiceStateRegistrants.remove(h);
     }
 
+    // Inherited documentation suffices.
+    public void registerForRingbackTone(Handler h, int what, Object obj) {
+        mCM.registerForRingbackTone(h,what,obj);
+    }
+
+    // Inherited documentation suffices.
+    public void unregisterForRingbackTone(Handler h) {
+        mCM.unregisterForRingbackTone(h);
+    }
+
     /**
      * Subclasses of Phone probably want to replace this with a
      * version scoped to their packages
diff --git a/telephony/java/com/android/internal/telephony/PhoneProxy.java b/telephony/java/com/android/internal/telephony/PhoneProxy.java
index 711a48c..c4f663a 100644
--- a/telephony/java/com/android/internal/telephony/PhoneProxy.java
+++ b/telephony/java/com/android/internal/telephony/PhoneProxy.java
@@ -331,6 +331,14 @@
         mActivePhone.unregisterForEcmTimerReset(h);
     }
 
+    public void registerForRingbackTone(Handler h, int what, Object obj) {
+        mActivePhone.registerForRingbackTone(h,what,obj);
+    }
+
+    public void unregisterForRingbackTone(Handler h) {
+        mActivePhone.unregisterForRingbackTone(h);
+    }
+
     public boolean getIccRecordsLoaded() {
         return mActivePhone.getIccRecordsLoaded();
     }
diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java
index cd6340e..d1b446b 100644
--- a/telephony/java/com/android/internal/telephony/RIL.java
+++ b/telephony/java/com/android/internal/telephony/RIL.java
@@ -2313,6 +2313,7 @@
             case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: ret = responseInts(p); break;
             case RIL_UNSOL_CDMA_INFO_REC: ret = responseCdmaInformationRecord(p); break;
             case RIL_UNSOL_OEM_HOOK_RAW: ret = responseRaw(p); break;
+            case RIL_UNSOL_RINGBACK_TONE: ret = responseInts(p); break;
 
             default:
                 throw new RuntimeException("Unrecognized unsol response: " + response);
@@ -2597,6 +2598,14 @@
                     mUnsolOemHookRawRegistrant.notifyRegistrant(new AsyncResult(null, ret, null));
                 }
                 break;
+
+            case RIL_UNSOL_RINGBACK_TONE:
+                if (RILJ_LOGD) unsljLogvRet(response, ret);
+                if (mRingbackToneRegistrants != null) {
+                    boolean playtone = (((int[])ret)[0] == 1);
+                    mRingbackToneRegistrants.notifyRegistrants(
+                                        new AsyncResult (null, playtone, null));
+                }
         }
     }
 
@@ -3209,6 +3218,7 @@
             case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: return "UNSOL_CDMA_OTA_PROVISION_STATUS";
             case RIL_UNSOL_CDMA_INFO_REC: return "UNSOL_CDMA_INFO_REC";
             case RIL_UNSOL_OEM_HOOK_RAW: return "UNSOL_OEM_HOOK_RAW";
+            case RIL_UNSOL_RINGBACK_TONE: return "UNSOL_RINGBACK_TONG";
             default: return "<unknown reponse>";
         }
     }
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index 90a82f9..3e9d8ad 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -258,4 +258,5 @@
     int RIL_UNSOL_CDMA_OTA_PROVISION_STATUS = 1026;
     int RIL_UNSOL_CDMA_INFO_REC = 1027;
     int RIL_UNSOL_OEM_HOOK_RAW = 1028;
+    int RIL_UNSOL_RINGBACK_TONE = 1029;
 }
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index f2cdf75..4742341 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -712,7 +712,8 @@
                                 LARGE_SCREEN_ATTR, NULL, 1);
                     } else if (tag == "uses-feature") {
                         String8 name = getAttribute(tree, NAME_ATTR, &error);
-                        if (error == "") {
+
+                        if (name != "" && error == "") {
                             int req = getIntegerAttribute(tree,
                                     REQUIRED_ATTR, NULL, 1);
                             if (name == "android.hardware.camera") {
@@ -729,7 +730,7 @@
                         }
                     } else if (tag == "uses-permission") {
                         String8 name = getAttribute(tree, NAME_ATTR, &error);
-                        if (error == "") {
+                        if (name != "" && error == "") {
                             if (name == "android.permission.CAMERA") {
                                 hasCameraPermission = true;
                             }