Merge change 22154 into eclair

* changes:
  Fix fastscroll overlay size on WVGA by using dip.
diff --git a/api/current.xml b/api/current.xml
index 881c71f..6059946 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -7489,6 +7489,17 @@
  visibility="public"
 >
 </field>
+<field name="supportsUploading"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843414"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="syncable"
  type="int"
  transient="false"
@@ -36124,6 +36135,8 @@
 </parameter>
 <parameter name="userVisible" type="boolean">
 </parameter>
+<parameter name="supportsUploading" type="boolean">
+</parameter>
 </constructor>
 <constructor name="SyncAdapterType"
  type="android.content.SyncAdapterType"
@@ -36146,6 +36159,17 @@
  visibility="public"
 >
 </method>
+<method name="isUserVisible"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="newKey"
  return="android.content.SyncAdapterType"
  abstract="false"
@@ -36161,6 +36185,17 @@
 <parameter name="accountType" type="java.lang.String">
 </parameter>
 </method>
+<method name="supportsUploading"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="writeToParcel"
  return="void"
  abstract="false"
@@ -36206,7 +36241,7 @@
  visibility="public"
 >
 </field>
-<field name="userVisible"
+<field name="isKey"
  type="boolean"
  transient="false"
  volatile="false"
diff --git a/cmds/stagefright/JPEGSource.cpp b/cmds/stagefright/JPEGSource.cpp
index 338a3d5..a7994ed 100644
--- a/cmds/stagefright/JPEGSource.cpp
+++ b/cmds/stagefright/JPEGSource.cpp
@@ -60,6 +60,7 @@
       mHeight(0),
       mOffset(0) {
     CHECK_EQ(parseJPEG(), OK);
+    CHECK(mSource->getSize(&mSize) == OK);
 }
 
 JPEGSource::~JPEGSource() {
@@ -73,10 +74,6 @@
         return UNKNOWN_ERROR;
     }
 
-    if (mSource->getSize(&mSize) != OK) {
-        return UNKNOWN_ERROR;
-    }
-
     mGroup = new MediaBufferGroup;
     mGroup->add_buffer(new MediaBuffer(mSize));
 
@@ -105,6 +102,7 @@
     meta->setCString(kKeyMIMEType, "image/jpeg");
     meta->setInt32(kKeyWidth, mWidth);
     meta->setInt32(kKeyHeight, mHeight);
+    meta->setInt32(kKeyCompressedSize, mSize);
 
     return meta;
 }
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index 185e6ac..6b2d8ad 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -23,6 +23,8 @@
 #include <binder/IServiceManager.h>
 #include <binder/ProcessState.h>
 #include <media/IMediaPlayerService.h>
+#include <media/stagefright/CachingDataSource.h>
+#include <media/stagefright/HTTPDataSource.h>
 #include <media/stagefright/MediaDebug.h>
 #include <media/stagefright/MediaPlayerImpl.h>
 #include <media/stagefright/MediaExtractor.h>
@@ -191,7 +193,13 @@
     for (int k = 0; k < argc; ++k) {
         const char *filename = argv[k];
 
-        sp<MmapSource> dataSource = new MmapSource(filename);
+        sp<DataSource> dataSource;
+        if (!strncasecmp("http://", filename, 7)) {
+            dataSource = new HTTPDataSource(filename);
+            dataSource = new CachingDataSource(dataSource, 64 * 1024, 10);
+        } else {
+            dataSource = new MmapSource(filename);
+        }
 
         bool isJPEG = false;
 
diff --git a/core/java/android/content/SyncAdapterType.java b/core/java/android/content/SyncAdapterType.java
index 93b61ec..25cbdb1 100644
--- a/core/java/android/content/SyncAdapterType.java
+++ b/core/java/android/content/SyncAdapterType.java
@@ -27,9 +27,12 @@
 public class SyncAdapterType implements Parcelable {
     public final String authority;
     public final String accountType;
-    public final boolean userVisible;
+    public final boolean isKey;
+    private final boolean userVisible;
+    private final boolean supportsUploading;
 
-    public SyncAdapterType(String authority, String accountType, boolean userVisible) {
+    public SyncAdapterType(String authority, String accountType, boolean userVisible, 
+            boolean supportsUploading) {
         if (TextUtils.isEmpty(authority)) {
             throw new IllegalArgumentException("the authority must not be empty: " + authority);
         }
@@ -39,17 +42,49 @@
         this.authority = authority;
         this.accountType = accountType;
         this.userVisible = userVisible;
+        this.supportsUploading = supportsUploading;
+        this.isKey = false;
+    }
+
+    private SyncAdapterType(String authority, String accountType) {
+        if (TextUtils.isEmpty(authority)) {
+            throw new IllegalArgumentException("the authority must not be empty: " + authority);
+        }
+        if (TextUtils.isEmpty(accountType)) {
+            throw new IllegalArgumentException("the accountType must not be empty: " + accountType);
+        }
+        this.authority = authority;
+        this.accountType = accountType;
+        this.userVisible = true;
+        this.supportsUploading = true;
+        this.isKey = true;
+    }
+
+    public boolean supportsUploading() {
+        if (isKey) {
+            throw new IllegalStateException(
+                    "this method is not allowed to be called when this is a key");
+        }
+        return supportsUploading;
+    }
+
+    public boolean isUserVisible() {
+        if (isKey) {
+            throw new IllegalStateException(
+                    "this method is not allowed to be called when this is a key");
+        }
+        return userVisible;
     }
 
     public static SyncAdapterType newKey(String authority, String accountType) {
-        return new SyncAdapterType(authority, accountType, true);
+        return new SyncAdapterType(authority, accountType);
     }
 
     public boolean equals(Object o) {
         if (o == this) return true;
         if (!(o instanceof SyncAdapterType)) return false;
         final SyncAdapterType other = (SyncAdapterType)o;
-        // don't include userVisible in the equality check
+        // don't include userVisible or supportsUploading in the equality check
         return authority.equals(other.authority) && accountType.equals(other.accountType);
     }
 
@@ -57,13 +92,22 @@
         int result = 17;
         result = 31 * result + authority.hashCode();
         result = 31 * result + accountType.hashCode();
-        // don't include userVisible in the hash
+        // don't include userVisible or supportsUploading  the hash
         return result;
     }
 
     public String toString() {
-        return "SyncAdapterType {name=" + authority + ", type=" + accountType
-                + ", userVisible=" + userVisible + "}";
+        if (isKey) {
+            return "SyncAdapterType Key {name=" + authority
+                    + ", type=" + accountType
+                    + "}";
+        } else {
+            return "SyncAdapterType {name=" + authority
+                    + ", type=" + accountType
+                    + ", userVisible=" + userVisible
+                    + ", supportsUploading=" + supportsUploading
+                    + "}";
+        }
     }
 
     public int describeContents() {
@@ -71,13 +115,22 @@
     }
 
     public void writeToParcel(Parcel dest, int flags) {
+        if (isKey) {
+            throw new IllegalStateException("keys aren't parcelable");
+        }
+
         dest.writeString(authority);
         dest.writeString(accountType);
         dest.writeInt(userVisible ? 1 : 0);
+        dest.writeInt(supportsUploading ? 1 : 0);
     }
 
     public SyncAdapterType(Parcel source) {
-        this(source.readString(), source.readString(), source.readInt() != 0);
+        this(
+                source.readString(),
+                source.readString(),
+                source.readInt() != 0,
+                source.readInt() != 0);
     }
 
     public static final Creator<SyncAdapterType> CREATOR = new Creator<SyncAdapterType>() {
diff --git a/core/java/android/content/SyncAdaptersCache.java b/core/java/android/content/SyncAdaptersCache.java
index c27fd25..7d9f1de 100644
--- a/core/java/android/content/SyncAdaptersCache.java
+++ b/core/java/android/content/SyncAdaptersCache.java
@@ -49,7 +49,10 @@
             }
             final boolean userVisible =
                     sa.getBoolean(com.android.internal.R.styleable.SyncAdapter_userVisible, true);
-            return new SyncAdapterType(authority, accountType, userVisible);
+            final boolean supportsUploading =
+                    sa.getBoolean(com.android.internal.R.styleable.SyncAdapter_supportsUploading,
+                            true);
+            return new SyncAdapterType(authority, accountType, userVisible, supportsUploading);
         } finally {
             sa.recycle();
         }
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index 34efc51..82cf23f 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -526,13 +526,6 @@
     public void scheduleSync(Account requestedAccount, String requestedAuthority,
             Bundle extras, long delay, boolean onlyThoseWithUnkownSyncableState) {
         boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE);
-        if (isLoggable) {
-            Log.v(TAG, "scheduleSync:"
-                    + " delay " + delay
-                    + ", account " + requestedAccount
-                    + ", authority " + requestedAuthority
-                    + ", extras " + ((extras == null) ? "(null)" : extras));
-        }
 
         if (!isSyncEnabled()) {
             if (isLoggable) {
@@ -617,13 +610,27 @@
                 if (onlyThoseWithUnkownSyncableState && isSyncable >= 0) {
                     continue;
                 }
-                if (mSyncAdapters.getServiceInfo(SyncAdapterType.newKey(authority, account.type))
-                        != null) {
+                final RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo =
+                        mSyncAdapters.getServiceInfo(
+                                SyncAdapterType.newKey(authority, account.type));
+                if (syncAdapterInfo != null) {
+                    if (!syncAdapterInfo.type.supportsUploading() && uploadOnly) {
+                        continue;
+                    }
                     // make this an initialization sync if the isSyncable state is unknown
-                    Bundle extrasCopy = new Bundle(extras);
+                    Bundle extrasCopy = extras;
                     if (isSyncable < 0) {
+                        extrasCopy = new Bundle(extras);
                         extrasCopy.putBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, true);
                     }
+                    if (isLoggable) {
+                        Log.v(TAG, "scheduleSync:"
+                                + " delay " + delay
+                                + ", source " + source
+                                + ", account " + account
+                                + ", authority " + authority
+                                + ", extras " + extrasCopy);
+                    }
                     scheduleSyncOperation(
                             new SyncOperation(account, source, authority, extrasCopy, delay));
                 }
diff --git a/core/java/android/preference/CheckBoxPreference.java b/core/java/android/preference/CheckBoxPreference.java
index cf5664c..f16a7e4 100644
--- a/core/java/android/preference/CheckBoxPreference.java
+++ b/core/java/android/preference/CheckBoxPreference.java
@@ -149,14 +149,12 @@
      * @param checked The checked state.
      */
     public void setChecked(boolean checked) {
-
-        mChecked = checked;
-
-        persistBoolean(checked);
-
-        notifyDependencyChange(shouldDisableDependents());
-        
-        notifyChanged();
+        if (mChecked != checked) {
+            mChecked = checked;
+            persistBoolean(checked);
+            notifyDependencyChange(shouldDisableDependents());
+            notifyChanged();
+        }
     }
 
     /**
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 1861095..84e07f0 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3390,6 +3390,13 @@
                 "google_calendar_sync_window_days";
 
         /**
+         * How often to update the calendar sync window.
+         * The window will be advanced every n days.
+         */
+        public static final String GOOGLE_CALENDAR_SYNC_WINDOW_UPDATE_DAYS =
+                "google_calendar_sync_window_update_days";
+
+        /**
          * @deprecated
          * @hide
          */
diff --git a/core/java/android/widget/MediaController.java b/core/java/android/widget/MediaController.java
index 9910c37..446a992 100644
--- a/core/java/android/widget/MediaController.java
+++ b/core/java/android/widget/MediaController.java
@@ -282,6 +282,9 @@
 
         if (!mShowing && mAnchor != null) {
             setProgress();
+            if (mPauseButton != null) {
+                mPauseButton.requestFocus();
+            }
             disableUnsupportedButtons();
 
             int [] anchorpos = new int[2];
@@ -416,6 +419,9 @@
                 keyCode ==  KeyEvent.KEYCODE_SPACE)) {
             doPauseResume();
             show(sDefaultTimeout);
+            if (mPauseButton != null) {
+                mPauseButton.requestFocus();
+            }
             return true;
         } else if (keyCode ==  KeyEvent.KEYCODE_MEDIA_STOP) {
             if (mPlayer.isPlaying()) {
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index e03211d..729b1db 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -3410,6 +3410,7 @@
         <attr name="contentAuthority" format="string"/>
         <attr name="accountType"/>
         <attr name="userVisible" format="boolean"/>
+        <attr name="supportsUploading" format="boolean"/>
     </declare-styleable>
 
     <!-- =============================== -->
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index bbeb78d..4bc376b 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1159,4 +1159,5 @@
   <public type="style" name="Theme.Wallpaper.NoTitleBar" />
   <public type="style" name="Theme.Wallpaper.NoTitleBar.Fullscreen" />
 
+  <public type="attr" name="supportsUploading" />
 </resources>
diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs
index 11f8c7b..0b33739 100644
--- a/docs/html/guide/guide_toc.cs
+++ b/docs/html/guide/guide_toc.cs
@@ -139,6 +139,7 @@
           <li><a href="<?cs var:toroot ?>guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</a></li>
           <li><a href="<?cs var:toroot ?>guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></li>
           <li><a href="<?cs var:toroot ?>guide/topics/manifest/meta-data-element.html">&lt;meta-data&gt;</a></li>
+          <li><a href="<?cs var:toroot ?>guide/topics/manifest/path-permission-element.html">&lt;path-permission&gt;</a></li>
           <li><a href="<?cs var:toroot ?>guide/topics/manifest/permission-element.html">&lt;permission&gt;</a></li>
           <li><a href="<?cs var:toroot ?>guide/topics/manifest/permission-group-element.html">&lt;permission-group&gt;</a></li>
           <li><a href="<?cs var:toroot ?>guide/topics/manifest/permission-tree-element.html">&lt;permission-tree&gt;</a></li>
diff --git a/docs/html/guide/topics/manifest/manifest-intro.jd b/docs/html/guide/topics/manifest/manifest-intro.jd
index 9e1b18d..89171c1 100644
--- a/docs/html/guide/topics/manifest/manifest-intro.jd
+++ b/docs/html/guide/topics/manifest/manifest-intro.jd
@@ -112,6 +112,7 @@
 
         <a href="{@docRoot}guide/topics/manifest/provider-element.html">&lt;provider&gt;</a>
             <a href="{@docRoot}guide/topics/manifest/grant-uri-permission-element.html">&lt;grant-uri-permission /&gt;</a>
+            <a href="{@docRoot}guide/topics/manifest/path-permission-element.html">&lt;path-permission /&gt;</a>
             <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">&lt;meta-data /&gt;</a>
         <a href="{@docRoot}guide/topics/manifest/provider-element.html">&lt;/provider&gt;</a>
 
@@ -140,6 +141,7 @@
 <br/><code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</a></code>
 <br/><code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code>
 <br/><code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html">&lt;meta-data&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/path-permission-element.html">&lt;path-permission /&gt;</a></code>
 <br/><code><a href="{@docRoot}guide/topics/manifest/permission-element.html">&lt;permission&gt;</a></code>
 <br/><code><a href="{@docRoot}guide/topics/manifest/permission-group-element.html">&lt;permission-group&gt;</a></code>
 <br/><code><a href="{@docRoot}guide/topics/manifest/permission-tree-element.html">&lt;permission-tree&gt;</a></code>
diff --git a/docs/html/guide/topics/manifest/path-permission-element.jd b/docs/html/guide/topics/manifest/path-permission-element.jd
new file mode 100644
index 0000000..5c271a7
--- /dev/null
+++ b/docs/html/guide/topics/manifest/path-permission-element.jd
@@ -0,0 +1,104 @@
+page.title=&lt;path-permission&gt;
+@jd:body
+
+<dl class="xml">
+<dt>syntax:</dt>
+<dd><pre class="stx">
+&lt;path-permission android:<a href="#path">path</a>="<i>string</i>"
+                 android:<a href="#pathPrefix">pathPrefix</a>="<i>string</i>"
+                 android:<a href="#pathPattern">pathPattern</a>="<i>string</i>"
+                 android:<a href="#permission">permission</a>="<i>string</i>"
+                 android:<a href="#readPermission">readPermission</a>="<i>string</i>"
+                 android:<a href="#writePermission">writePermission</a>="<i>string</i>" /&gt;
+</pre></dd>
+
+<dt>contained in:</dt>
+<dd><code><a href="{@docRoot}guide/topics/manifest/provider-element.html">&lt;provider&gt;</a></code></dd>
+
+<!--
+<dt>can contain:</dt>
+</dd>
+-->
+
+<dt>description:</dt>
+<dd>Defines the path and required permissions for a specific subset of data
+within a content provider. This element can be
+specified multiple times to supply multiple paths.
+
+</dd>
+
+<dt>attributes:</dt>
+
+<dd><dl class="attr">
+<dt><a name="path"></a>{@code android:path}</dt>
+<dd>A complete URI path for a subset of content provider data. 
+Permission can be granted only to the particular data identified by this path. 
+When used to provide search suggestion content, it must be appended 
+with "/search_suggest_query".
+</dd>
+
+<dt><a name="pathPrefix"></a>{@code android:pathPrefix}</dt>
+<dd>The initial part of a URI path for a subset of content provider data.
+Permission can be granted to all data subsets with paths that share this initial part.
+</dd>
+
+<dt><a name="pathPattern"></a>{@code android:pathPattern}</dt>
+<dd>A complete URI path for a subset of content provider data,
+but one that can use the following wildcards:
+ 
+<ul> 
+<li>An asterisk ('<code class="Code prettyprint">*</code>'). This matches a sequence of 0 to many occurrences of
+the immediately preceding character.</li> 
+ 
+<li>A period followed by an asterisk ("<code class="Code prettyprint">.*</code>"). This matches any sequence of 
+0 or more characters.</li> 
+</ul> 
+ 
+<p> 
+Because '<code class="Code prettyprint">\</code>' is used as an escape character when the string is read 
+from XML (before it is parsed as a pattern), you will need to double-escape.
+For example, a literal '<code class="Code prettyprint">*</code>' would be written as "<code class="Code prettyprint">\\*</code>" and a 
+literal '<code class="Code prettyprint">\</code>' would be written as "<code class="Code prettyprint">\\</code>".  This is basically 
+the same as what you would need to write if constructing the string in Java code.
+</p> 
+<p> 
+For more information on these types of patterns, see the descriptions of 
+<a href="/reference/android/os/PatternMatcher.html#PATTERN_LITERAL">PATTERN_LITERAL</a>,
+<a href="/reference/android/os/PatternMatcher.html#PATTERN_PREFIX">PATTERN_PREFIX</a>, and
+<a href="/reference/android/os/PatternMatcher.html#PATTERN_SIMPLE_GLOB">PATTERN_SIMPLE_GLOB</a> in the
+<a href="/reference/android/os/PatternMatcher.html">PatternMatcher</a> class.
+</p>
+</dd>
+
+<dt><a name="permission"></a>{@code android:permission}</dt>
+<dd>The name of a permission that clients must have in order to read or write the
+content provider's data.  This attribute is a convenient way of setting a 
+single permission for both reading and writing.  However, the 
+<code>readPermission</code> and 
+<code>writePermission</code> attributes take precedence
+over this one.
+</dd> 
+
+<dt><a name="readPermission"></a>{@code android:readPermission}</dt>
+<dd>A permission that clients must have in order to query the content provider.
+</dd> 
+
+<dt><a name="writePermission"></a>{@code android:writePermission}</dt>
+<dd>A permission that clients must have in order to make changes to the data controlled by the content provider.
+</dd> 
+
+
+
+</dl></dd>
+
+<!-- ##api level indication## -->
+<dt>introduced in:</dt>
+<dd>API Level 4</dd>
+
+<dt>see also:</dt>
+<dd>{@link android.app.SearchManager}</dd>
+<dd>{@link android.Manifest.permission}</dd>
+<dd><a href="/guide/topics/security/security.html">Security and
+Permissions</a></dd>
+
+</dl>
diff --git a/docs/html/guide/topics/manifest/provider-element.jd b/docs/html/guide/topics/manifest/provider-element.jd
index 2bb4ff4..3942f95 100644
--- a/docs/html/guide/topics/manifest/provider-element.jd
+++ b/docs/html/guide/topics/manifest/provider-element.jd
@@ -25,7 +25,9 @@
 
 <dt>can contain:</dt>
 <dd><code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html">&lt;meta-data&gt;</a></code>
-<br/><code><a href="{@docRoot}guide/topics/manifest/grant-uri-permission-element.html">&lt;grant-uri-permission&gt;</a></code></dd>
+<br/><code><a href="{@docRoot}guide/topics/manifest/grant-uri-permission-element.html">&lt;grant-uri-permission&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/path-permission-element.html">&lt;path-permission /&gt;</a></code>
+</dd>
 
 <dt>description:</dt>
 <dd>Declares a content provider &mdash; a subclass of 
diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h
index 6ce2581..be60565 100644
--- a/include/media/stagefright/MetaData.h
+++ b/include/media/stagefright/MetaData.h
@@ -45,6 +45,7 @@
     kKeyPlatformPrivate   = 'priv',
     kKeyDecoderComponent  = 'decC',
     kKeyBufferID          = 'bfID',
+    kKeyCompressedSize    = 'cmpS',
 };
 
 enum {
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
index c8ee255..0b94118 100644
--- a/include/media/stagefright/OMXCodec.h
+++ b/include/media/stagefright/OMXCodec.h
@@ -108,7 +108,7 @@
     Vector<CodecSpecificData *> mCodecSpecificData;
     size_t mCodecSpecificDataIndex;
 
-    sp<MemoryDealer> mDealer;
+    sp<MemoryDealer> mDealer[2];
 
     State mState;
     Vector<BufferInfo> mPortBuffers[2];
@@ -148,6 +148,9 @@
     void setImageOutputFormat(
             OMX_COLOR_FORMATTYPE format, OMX_U32 width, OMX_U32 height);
 
+    void setJPEGInputFormat(
+            OMX_U32 width, OMX_U32 height, OMX_U32 compressedSize);
+
     status_t allocateBuffers();
     status_t allocateBuffersOnPort(OMX_U32 portIndex);
 
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 1774eaf..ec9f6d3 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -302,7 +302,7 @@
         int32_t width, height;
         bool success = meta->findInt32(kKeyWidth, &width);
         success = success && meta->findInt32(kKeyHeight, &height);
-        assert(success);
+        CHECK(success);
 
         if (createEncoder) {
             codec->setVideoInputFormat(mime, width, height);
@@ -321,9 +321,16 @@
         int32_t width, height;
         bool success = meta->findInt32(kKeyWidth, &width);
         success = success && meta->findInt32(kKeyHeight, &height);
-        assert(success);
+
+        int32_t compressedSize;
+        success = success && meta->findInt32(
+                kKeyCompressedSize, &compressedSize);
+
+        CHECK(success);
+        CHECK(compressedSize > 0);
 
         codec->setImageOutputFormat(format, width, height);
+        codec->setJPEGInputFormat(width, height, (OMX_U32)compressedSize);
     }
 
     codec->initOutputFormat(meta);
@@ -355,7 +362,7 @@
         }
 
         // The following assertion is violated by TI's video decoder.
-        // assert(format.nIndex == index);
+        // CHECK_EQ(format.nIndex, index);
 
 #if 1
         LOGI("portIndex: %ld, index: %ld, eCompressionFormat=%d eColorFormat=%d",
@@ -618,7 +625,6 @@
       mComponentName(strdup(componentName)),
       mSource(source),
       mCodecSpecificDataIndex(0),
-      mDealer(new MemoryDealer(5 * 1024 * 1024)),
       mState(LOADED),
       mSignalledEOS(false),
       mNoMoreOutputData(false),
@@ -716,8 +722,11 @@
         return err;
     }
 
+    size_t totalSize = def.nBufferCountActual * def.nBufferSize;
+    mDealer[portIndex] = new MemoryDealer(totalSize);
+
     for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
-        sp<IMemory> mem = mDealer->allocate(def.nBufferSize);
+        sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
         CHECK(mem.get() != NULL);
 
         IOMX::buffer_id buffer;
@@ -1491,23 +1500,33 @@
             break;
     }
 
+    def.nBufferCountActual = def.nBufferCountMin;
+
     err = mOMX->set_parameter(
             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
     CHECK_EQ(err, OK);
+}
 
-    ////
-
+void OMXCodec::setJPEGInputFormat(
+        OMX_U32 width, OMX_U32 height, OMX_U32 compressedSize) {
+    OMX_PARAM_PORTDEFINITIONTYPE def;
+    def.nSize = sizeof(def);
+    def.nVersion.s.nVersionMajor = 1;
+    def.nVersion.s.nVersionMinor = 1;
     def.nPortIndex = kPortIndexInput;
 
-    err = mOMX->get_parameter(
+    status_t err = mOMX->get_parameter(
             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
     CHECK_EQ(err, OK);
 
+    CHECK_EQ(def.eDomain, OMX_PortDomainImage);
+    OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
+
     CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingJPEG);
     imageDef->nFrameWidth = width;
     imageDef->nFrameHeight = height;
 
-    def.nBufferSize = 128 * 1024;
+    def.nBufferSize = compressedSize;
     def.nBufferCountActual = def.nBufferCountMin;
 
     err = mOMX->set_parameter(
@@ -1558,7 +1577,7 @@
 }
 
 status_t OMXCodec::stop() {
-    LOGI("stop");
+    LOGV("stop");
 
     Mutex::Autolock autoLock(mLock);
 
diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
index 9c04305..1597427 100755
--- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
@@ -29,6 +29,7 @@
 import com.android.internal.telephony.cdma.sms.CdmaSmsAddress;
 import com.android.internal.telephony.cdma.sms.SmsEnvelope;
 import com.android.internal.telephony.cdma.sms.UserData;
+import com.android.internal.util.HexDump;
 
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
@@ -67,6 +68,7 @@
  */
 public class SmsMessage extends SmsMessageBase {
     static final String LOG_TAG = "CDMA";
+    private final static Boolean DBG_SMS = false;
 
     /**
      *  Status of a previously submitted SMS.
@@ -541,6 +543,11 @@
             return;
         }
         mBearerData = BearerData.decode(mEnvelope.bearerData);
+        if (DBG_SMS) {
+            Log.d(LOG_TAG, "MT raw BearerData = '" +
+                      HexDump.toHexString(mEnvelope.bearerData) + "'");
+            Log.d(LOG_TAG, "MT (decoded) BearerData = " + mBearerData);
+        }
         messageRef = mBearerData.messageId;
         if (mBearerData.userData != null) {
             userData = mBearerData.userData.payload;
@@ -644,14 +651,17 @@
         bearerData.reportReq = false;
 
         bearerData.userData = userData;
-        bearerData.hasUserDataHeader = (userData.userDataHeader != null);
+
+        byte[] encodedBearerData = BearerData.encode(bearerData);
+        if (DBG_SMS) {
+            Log.d(LOG_TAG, "MO (encoded) BearerData = " + bearerData);
+            Log.d(LOG_TAG, "MO raw BearerData = '" + HexDump.toHexString(encodedBearerData) + "'");
+        }
+        if (encodedBearerData == null) return null;
 
         int teleservice = bearerData.hasUserDataHeader ?
                 SmsEnvelope.TELESERVICE_WEMT : SmsEnvelope.TELESERVICE_WMT;
 
-        byte[] encodedBearerData = BearerData.encode(bearerData);
-        if (encodedBearerData == null) return null;
-
         SmsEnvelope envelope = new SmsEnvelope();
         envelope.messageType = SmsEnvelope.MESSAGE_TYPE_POINT_TO_POINT;
         envelope.teleService = teleservice;
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
index fefeb12..721729d 100644
--- a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
+++ b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
@@ -484,7 +484,7 @@
             Gsm7bitCodingResult result = new Gsm7bitCodingResult();
             result.data = new byte[fullData.length - 1];
             System.arraycopy(fullData, 1, result.data, 0, fullData.length - 1);
-            result.septets = fullData[0];
+            result.septets = fullData[0] & 0x00FF;
             return result;
         } catch (com.android.internal.telephony.EncodeException ex) {
             throw new CodingException("7bit GSM encode failed: " + ex);
@@ -498,6 +498,7 @@
         int udhSeptets = ((udhBytes * 8) + 6) / 7;
         Gsm7bitCodingResult gcr = encode7bitGsm(uData.payloadStr, udhSeptets, force);
         uData.msgEncoding = UserData.ENCODING_GSM_7BIT_ALPHABET;
+        uData.msgEncodingSet = true;
         uData.numFields = gcr.septets;
         uData.payload = gcr.data;
         uData.payload[0] = (byte)udhData.length;
@@ -512,6 +513,8 @@
         int udhCodeUnits = (udhBytes + 1) / 2;
         int udhPadding = udhBytes % 2;
         int payloadCodeUnits = payload.length / 2;
+        uData.msgEncoding = UserData.ENCODING_UNICODE_16;
+        uData.msgEncodingSet = true;
         uData.numFields = udhCodeUnits + payloadCodeUnits;
         uData.payload = new byte[uData.numFields * 2];
         uData.payload[0] = (byte)udhData.length;
@@ -606,14 +609,16 @@
          * copies by passing outStream directly.
          */
         encodeUserDataPayload(bData.userData);
+        bData.hasUserDataHeader = bData.userData.userDataHeader != null;
+
         if (bData.userData.payload.length > SmsMessage.MAX_USER_DATA_BYTES) {
             throw new CodingException("encoded user data too large (" +
                                       bData.userData.payload.length +
                                       " > " + SmsMessage.MAX_USER_DATA_BYTES + " bytes)");
         }
 
-        /**
-         * XXX/TODO: figure out what the right answer is WRT padding bits
+        /*
+         * TODO(cleanup): figure out what the right answer is WRT paddingBits field
          *
          *   userData.paddingBits = (userData.payload.length * 8) - (userData.numFields * 7);
          *   userData.paddingBits = 0; // XXX this seems better, but why?
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/UserData.java b/telephony/java/com/android/internal/telephony/cdma/sms/UserData.java
index 9b6e19d..d93852c 100644
--- a/telephony/java/com/android/internal/telephony/cdma/sms/UserData.java
+++ b/telephony/java/com/android/internal/telephony/cdma/sms/UserData.java
@@ -154,7 +154,7 @@
         builder.append("{ msgEncoding=" + (msgEncodingSet ? msgEncoding : "unset"));
         builder.append(", msgType=" + msgType);
         builder.append(", paddingBits=" + paddingBits);
-        builder.append(", numFields=" + (int)numFields);
+        builder.append(", numFields=" + numFields);
         builder.append(", userDataHeader=" + userDataHeader);
         builder.append(", payload='" + HexDump.toHexString(payload) + "'");
         builder.append(", payloadStr='" + payloadStr + "'");