Merge change 7490

* changes:
  Fix master build errors post merge with master_gl branch.
diff --git a/api/current.xml b/api/current.xml
index a31208a..76b5f7f 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -115065,6 +115065,38 @@
 <parameter name="listener" type="android.speech.tts.TextToSpeech.OnInitListener">
 </parameter>
 </constructor>
+<method name="addEarcon"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="earcon" type="java.lang.String">
+</parameter>
+<parameter name="packagename" type="java.lang.String">
+</parameter>
+<parameter name="resourceId" type="int">
+</parameter>
+</method>
+<method name="addEarcon"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="earcon" type="java.lang.String">
+</parameter>
+<parameter name="filename" type="java.lang.String">
+</parameter>
+</method>
 <method name="addSpeech"
  return="int"
  abstract="false"
@@ -115374,6 +115406,144 @@
 >
 </field>
 </class>
+<class name="TextToSpeech.Engine"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="TextToSpeech.Engine"
+ type="android.speech.tts.TextToSpeech.Engine"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
+<field name="CHECK_VOICE_DATA_BAD_DATA"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="-1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="CHECK_VOICE_DATA_FAIL"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="0"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="CHECK_VOICE_DATA_MISSING_DATA"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="-2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="CHECK_VOICE_DATA_MISSING_VOLUME"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="-3"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="CHECK_VOICE_DATA_PASS"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TTS_DEFAULT_STREAM"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="3"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TTS_KEY_PARAM_STREAM"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;streamType&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TTS_KEY_PARAM_UTTERANCE_ID"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;utteranceId&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="VOICE_DATA_FILES"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;dataFiles&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="VOICE_DATA_FILES_INFO"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;dataFilesInfo&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="VOICE_DATA_ROOT_DIRECTORY"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;dataRoot&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
 <interface name="TextToSpeech.OnInitListener"
  abstract="true"
  static="true"
@@ -175418,6 +175588,17 @@
 <parameter name="yOffset" type="int">
 </parameter>
 </method>
+<method name="getSoftInputMode"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="getWidth"
  return="int"
  abstract="false"
@@ -175623,6 +175804,19 @@
 <parameter name="touchable" type="boolean">
 </parameter>
 </method>
+<method name="setSoftInputMode"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="mode" type="int">
+</parameter>
+</method>
 <method name="setTouchInterceptor"
  return="void"
  abstract="false"
diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java
index 2b165fc..444f222 100644
--- a/core/java/android/app/Dialog.java
+++ b/core/java/android/app/Dialog.java
@@ -20,6 +20,7 @@
 
 import android.content.Context;
 import android.content.DialogInterface;
+import android.content.ComponentName;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.os.Bundle;
@@ -86,6 +87,7 @@
 
     private Message mCancelMessage;
     private Message mDismissMessage;
+    private Message mShowMessage;
 
     /**
      * Whether to cancel the dialog when a touch is received outside of the
@@ -140,7 +142,7 @@
         w.setWindowManager(mWindowManager, null, null);
         w.setGravity(Gravity.CENTER);
         mUiThread = Thread.currentThread();
-        mDismissCancelHandler = new DismissCancelHandler(this);
+        mListenersHandler = new ListenersHandler(this);
     }
 
     /**
@@ -235,6 +237,8 @@
         }
         mWindowManager.addView(mDecor, l);
         mShowing = true;
+
+        sendShowMessage();
     }
     
     /**
@@ -289,6 +293,13 @@
         }
     }
 
+    private void sendShowMessage() {
+        if (mShowMessage != null) {
+            // Obtain a new message so this dialog can be re-used
+            Message.obtain(mShowMessage).sendToTarget();
+        }
+    }
+
     // internal method to make sure mcreated is set properly without requiring
     // users to call through to super in onCreate
     void dispatchOnCreate(Bundle savedInstanceState) {
@@ -774,8 +785,17 @@
      * This hook is called when the user signals the desire to start a search.
      */
     public boolean onSearchRequested() {
-        // not during dialogs, no.
-        return false;
+        final SearchManager searchManager = (SearchManager) mContext
+                .getSystemService(Context.SEARCH_SERVICE);
+
+        // associate search with owner activity if possible (otherwise it will default to
+        // global search).
+        final ComponentName appName = mOwnerActivity == null ? null
+                : mOwnerActivity.getComponentName();
+        final boolean globalSearch = (appName == null);
+        searchManager.startSearch(null, false, appName, null, globalSearch);
+        dismiss();
+        return true;
     }
 
 
@@ -890,7 +910,7 @@
      */
     public void setOnCancelListener(final OnCancelListener listener) {
         if (listener != null) {
-            mCancelMessage = mDismissCancelHandler.obtainMessage(CANCEL, listener);
+            mCancelMessage = mListenersHandler.obtainMessage(CANCEL, listener);
         } else {
             mCancelMessage = null;
         }
@@ -911,13 +931,26 @@
      */
     public void setOnDismissListener(final OnDismissListener listener) {
         if (listener != null) {
-            mDismissMessage = mDismissCancelHandler.obtainMessage(DISMISS, listener);
+            mDismissMessage = mListenersHandler.obtainMessage(DISMISS, listener);
         } else {
             mDismissMessage = null;
         }
     }
 
     /**
+     * Sets a listener to be invoked when the dialog is shown.
+     *
+     * @hide Pending API council approval
+     */
+    public void setOnShowListener(OnShowListener listener) {
+        if (listener != null) {
+            mShowMessage = mListenersHandler.obtainMessage(SHOW, listener);
+        } else {
+            mShowMessage = null;
+        }
+    }
+
+    /**
      * Set a message to be sent when the dialog is dismissed.
      * @param msg The msg to send when the dialog is dismissed.
      */
@@ -951,13 +984,14 @@
 
     private static final int DISMISS = 0x43;
     private static final int CANCEL = 0x44;
+    private static final int SHOW = 0x45;
 
-    private Handler mDismissCancelHandler;
+    private Handler mListenersHandler;
 
-    private static final class DismissCancelHandler extends Handler {
+    private static final class ListenersHandler extends Handler {
         private WeakReference<DialogInterface> mDialog;
 
-        public DismissCancelHandler(Dialog dialog) {
+        public ListenersHandler(Dialog dialog) {
             mDialog = new WeakReference<DialogInterface>(dialog);
         }
 
@@ -970,6 +1004,9 @@
                 case CANCEL:
                     ((OnCancelListener) msg.obj).onCancel(mDialog.get());
                     break;
+                case SHOW:
+                    ((OnShowListener) msg.obj).onShow(mDialog.get());
+                    break;
             }
         }
     }
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index 13eb034..e70b570 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -90,6 +90,9 @@
     private static final String INSTANCE_KEY_STORED_APPDATA = "sData";
     private static final String INSTANCE_KEY_PREVIOUS_COMPONENTS = "sPrev";
     private static final String INSTANCE_KEY_USER_QUERY = "uQry";
+    
+    // The extra key used in an intent to the speech recognizer for in-app voice search.
+    private static final String EXTRA_CALLING_PACKAGE = "calling_package";
 
     private static final int SEARCH_PLATE_LEFT_PADDING_GLOBAL = 12;
     private static final int SEARCH_PLATE_LEFT_PADDING_NON_GLOBAL = 7;
@@ -337,16 +340,7 @@
         mActivityContext = mSearchable.getActivityContext(getContext());
         
         // show the dialog. this will call onStart().
-        if (!isShowing()) {
-            // First make sure the keyboard is showing (if needed), so that we get the right height
-            // for the dropdown to respect the IME.
-            if (getContext().getResources().getConfiguration().hardKeyboardHidden ==
-                Configuration.HARDKEYBOARDHIDDEN_YES) {
-                InputMethodManager inputManager = (InputMethodManager)
-                getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
-                        inputManager.showSoftInputUnchecked(0, null);
-            }
-            
+        if (!isShowing()) {            
             // The Dialog uses a ContextThemeWrapper for the context; use this to change the
             // theme out from underneath us, between the global search theme and the in-app
             // search theme. They are identical except that the global search theme does not
@@ -856,11 +850,13 @@
      * @return A completely-configured intent ready to send to the voice search activity
      */
     private Intent createVoiceAppSearchIntent(Intent baseIntent) {
+        ComponentName searchActivity = mSearchable.getSearchActivity();
+        
         // create the necessary intent to set up a search-and-forward operation
         // in the voice search system.   We have to keep the bundle separate,
         // because it becomes immutable once it enters the PendingIntent
         Intent queryIntent = new Intent(Intent.ACTION_SEARCH);
-        queryIntent.setComponent(mSearchable.getSearchActivity());
+        queryIntent.setComponent(searchActivity);
         PendingIntent pending = PendingIntent.getActivity(
                 getContext(), 0, queryIntent, PendingIntent.FLAG_ONE_SHOT);
         
@@ -900,6 +896,8 @@
         voiceIntent.putExtra(RecognizerIntent.EXTRA_PROMPT, prompt);
         voiceIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, language);
         voiceIntent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, maxResults);
+        voiceIntent.putExtra(EXTRA_CALLING_PACKAGE,
+                searchActivity == null ? null : searchActivity.toShortString());
         
         // Add the values that configure forwarding the results
         voiceIntent.putExtra(RecognizerIntent.EXTRA_RESULTS_PENDINGINTENT, pending);
@@ -1535,7 +1533,22 @@
         @Override
         public void performCompletion() {
         }
-        
+
+        /**
+         * We override this method to be sure and show the soft keyboard if appropriate when
+         * the TextView has focus.
+         */
+        @Override
+        public void onWindowFocusChanged(boolean hasWindowFocus) {
+            super.onWindowFocusChanged(hasWindowFocus);
+
+            if (hasWindowFocus) {
+                InputMethodManager inputManager = (InputMethodManager)
+                        getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+                inputManager.showSoftInput(this, 0);
+            }
+        }
+                
         /**
          * We override this method so that we can allow a threshold of zero, which ACTV does not.
          */
diff --git a/core/java/android/appwidget/AppWidgetProviderInfo.java b/core/java/android/appwidget/AppWidgetProviderInfo.java
index 8530c35..a2e0ba0a 100644
--- a/core/java/android/appwidget/AppWidgetProviderInfo.java
+++ b/core/java/android/appwidget/AppWidgetProviderInfo.java
@@ -57,6 +57,9 @@
      *
      * <p>This field corresponds to the <code>android:updatePeriodMillis</code> attribute in
      * the AppWidget meta-data file.
+     *
+     * <p class="note"><b>Note:</b> Updates requested with <code>updatePeriodMillis</code>
+     * will not be delivered more than once every 30 minutes.</p>
      */
     public int updatePeriodMillis;
 
diff --git a/core/java/android/content/DialogInterface.java b/core/java/android/content/DialogInterface.java
index 4afa294..9f1036e 100644
--- a/core/java/android/content/DialogInterface.java
+++ b/core/java/android/content/DialogInterface.java
@@ -92,6 +92,21 @@
     }
 
     /**
+     * Interface used to allow the creator of a dialog to run some code when the
+     * dialog is shown.
+     * @hide Pending API council approval
+     */
+    interface OnShowListener {
+        /**
+         * This method will be invoked when the dialog is shown.
+         *
+         * @param dialog The dialog that was shown will be passed into the
+         *            method.
+         */
+        public void onShow(DialogInterface dialog);
+    }
+
+    /**
      * Interface used to allow the creator of a dialog to run some code when an
      * item on the dialog is clicked..
      */
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index f73b394..d54e260 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -1588,7 +1588,7 @@
                             ContentResolver.SYNC_EXTRAS_MANUAL, false);
                     final boolean syncAutomatically =
                             mSyncStorageEngine.getSyncAutomatically(op.account, op.authority)
-                                    || mSyncStorageEngine.getMasterSyncAutomatically();
+                                    && mSyncStorageEngine.getMasterSyncAutomatically();
                     boolean syncAllowed =
                             manualSync || (backgroundDataUsageAllowed && syncAutomatically);
                     if (!syncAllowed) {
diff --git a/core/java/android/content/SyncStorageEngine.java b/core/java/android/content/SyncStorageEngine.java
index 9d2efb5..8cc0642 100644
--- a/core/java/android/content/SyncStorageEngine.java
+++ b/core/java/android/content/SyncStorageEngine.java
@@ -110,6 +110,8 @@
     
     private static final int MSG_WRITE_STATISTICS = 2;
     private static final long WRITE_STATISTICS_DELAY = 1000*60*30; // 1/2 hour
+
+    private static final boolean SYNC_ENABLED_DEFAULT = false;
     
     public static class PendingOperation {
         final Account account;
@@ -158,7 +160,7 @@
             this.account = account;
             this.authority = authority;
             this.ident = ident;
-            enabled = true;
+            enabled = SYNC_ENABLED_DEFAULT;
         }
     }
     
@@ -376,23 +378,30 @@
     }
 
     public void setSyncAutomatically(Account account, String providerName, boolean sync) {
+        boolean wasEnabled;
         synchronized (mAuthorities) {
-            AuthorityInfo authority = getAuthorityLocked(account, providerName,
-                    "setSyncAutomatically");
-            if (authority != null) {
-                authority.enabled = sync;
-            }
+            AuthorityInfo authority = getOrCreateAuthorityLocked(account, providerName, -1, false);
+            wasEnabled = authority.enabled;
+            authority.enabled = sync;
             writeAccountInfoLocked();
         }
-        
+
+        if (!wasEnabled && sync) {
+            mContext.getContentResolver().requestSync(account, providerName, new Bundle());
+        }
         reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS);
     }
 
     public void setMasterSyncAutomatically(boolean flag) {
+        boolean old;
         synchronized (mAuthorities) {
+            old = mMasterSyncAutomatically;
             mMasterSyncAutomatically = flag;
             writeAccountInfoLocked();
         }
+        if (!old && flag) {
+            mContext.getContentResolver().requestSync(null, null, new Bundle());
+        }
         reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS);
         mContext.sendBroadcast(SYNC_CONNECTION_SETTING_CHANGED_INTENT);
     }
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 8de938d..a9aa1ee 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -34,6 +34,7 @@
 import android.util.SparseArray;
 import android.util.TypedValue;
 import android.util.LongSparseArray;
+import android.view.Display;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -87,6 +88,7 @@
     PluralRules mPluralRule;
     
     private final CompatibilityInfo mCompatibilityInfo;
+    private Display mDefaultDisplay;
 
     private static final LongSparseArray<Object> EMPTY_ARRAY = new LongSparseArray<Object>() {
         @Override
@@ -1915,6 +1917,24 @@
                 + Integer.toHexString(id));
     }
 
+    /**
+     * Returns the display adjusted for the Resources' metrics.
+     * @hide
+     */
+    public Display getDefaultDisplay(Display defaultDisplay) {
+        if (mDefaultDisplay == null) {
+            if (!mCompatibilityInfo.isScalingRequired() && mCompatibilityInfo.supportsScreen()) {
+                // the app supports the display. just use the default one.
+                mDefaultDisplay = defaultDisplay;
+            } else {
+                // display needs adjustment.
+                mDefaultDisplay = Display.createMetricsBasedDisplay(
+                        defaultDisplay.getDisplayId(), mMetrics);
+            }
+        }
+        return mDefaultDisplay;
+    }
+
     private TypedArray getCachedStyledAttributes(int len) {
         synchronized (mTmpValue) {
             TypedArray attrs = mCachedStyledAttributes;
diff --git a/core/java/android/net/http/Request.java b/core/java/android/net/http/Request.java
index 3fb3d3f..e160ab6 100644
--- a/core/java/android/net/http/Request.java
+++ b/core/java/android/net/http/Request.java
@@ -67,9 +67,6 @@
     /** Set if I'm using a proxy server */
     HttpHost mProxyHost;
 
-    /** True if request is .html, .js, .css */
-    boolean mHighPriority;
-
     /** True if request has been cancelled */
     volatile boolean mCancelled = false;
 
@@ -102,17 +99,15 @@
      * @param eventHandler request will make progress callbacks on
      * this interface
      * @param headers reqeust headers
-     * @param highPriority true for .html, css, .cs
      */
     Request(String method, HttpHost host, HttpHost proxyHost, String path,
             InputStream bodyProvider, int bodyLength,
             EventHandler eventHandler,
-            Map<String, String> headers, boolean highPriority) {
+            Map<String, String> headers) {
         mEventHandler = eventHandler;
         mHost = host;
         mProxyHost = proxyHost;
         mPath = path;
-        mHighPriority = highPriority;
         mBodyProvider = bodyProvider;
         mBodyLength = bodyLength;
 
@@ -356,7 +351,7 @@
      * for debugging
      */
     public String toString() {
-        return (mHighPriority ? "P*" : "") + mPath;
+        return mPath;
     }
 
 
diff --git a/core/java/android/net/http/RequestHandle.java b/core/java/android/net/http/RequestHandle.java
index 6a97951..190ae7a 100644
--- a/core/java/android/net/http/RequestHandle.java
+++ b/core/java/android/net/http/RequestHandle.java
@@ -419,6 +419,6 @@
         mRequest = mRequestQueue.queueRequest(
                 mUrl, mUri, mMethod, mHeaders, mRequest.mEventHandler,
                 mBodyProvider,
-                mBodyLength, mRequest.mHighPriority).mRequest;
+                mBodyLength).mRequest;
     }
 }
diff --git a/core/java/android/net/http/RequestQueue.java b/core/java/android/net/http/RequestQueue.java
index 4d3e7c3..b6f295e 100644
--- a/core/java/android/net/http/RequestQueue.java
+++ b/core/java/android/net/http/RequestQueue.java
@@ -52,47 +52,10 @@
 
     private Context mContext;
 
-    private static class RequestSet {
-        private final LinkedList<Request> mHighPriority;
-        private final LinkedList<Request> mLowPriority;
-
-        RequestSet() {
-            mHighPriority = new LinkedList<Request>();
-            mLowPriority = new LinkedList<Request>();
-        }
-
-        void add(Request req, boolean head) {
-            LinkedList l = mLowPriority;
-            if (req.mHighPriority) {
-                l = mHighPriority;
-            }
-            if (head) {
-                l.addFirst(req);
-            } else {
-                l.add(req);
-            }
-        }
-
-        Request removeFirst() {
-            if (!mHighPriority.isEmpty()) {
-                return mHighPriority.removeFirst();
-            } else if (!mLowPriority.isEmpty()) {
-                return mLowPriority.removeFirst();
-            }
-            return null;
-        }
-
-        boolean isEmpty() {
-            return mHighPriority.isEmpty() && mLowPriority.isEmpty();
-        }
-    };
     /**
      * Requests, indexed by HttpHost (scheme, host, port)
      */
-    private LinkedHashMap<HttpHost, RequestSet> mPending;
-
-    /* Support for notifying a client when queue is empty */
-    private boolean mClientWaiting = false;
+    private LinkedHashMap<HttpHost, LinkedList<Request>> mPending;
 
     /** true if connected */
     boolean mNetworkConnected = true;
@@ -382,7 +345,7 @@
     public RequestQueue(Context context, int connectionCount) {
         mContext = context;
 
-        mPending = new LinkedHashMap<HttpHost, RequestSet>(32);
+        mPending = new LinkedHashMap<HttpHost, LinkedList<Request>>(32);
 
         mActivePool = new ActivePool(connectionCount);
         mActivePool.startup();
@@ -472,16 +435,14 @@
      * data.  Callbacks will be made on the supplied instance.
      * @param bodyProvider InputStream providing HTTP body, null if none
      * @param bodyLength length of body, must be 0 if bodyProvider is null
-     * @param highPriority If true, queues before low priority
-     *     requests if possible
      */
     public RequestHandle queueRequest(
             String url, String method,
             Map<String, String> headers, EventHandler eventHandler,
-            InputStream bodyProvider, int bodyLength, boolean highPriority) {
+            InputStream bodyProvider, int bodyLength) {
         WebAddress uri = new WebAddress(url);
         return queueRequest(url, uri, method, headers, eventHandler,
-                            bodyProvider, bodyLength, highPriority);
+                            bodyProvider, bodyLength);
     }
 
     /**
@@ -494,14 +455,11 @@
      * data.  Callbacks will be made on the supplied instance.
      * @param bodyProvider InputStream providing HTTP body, null if none
      * @param bodyLength length of body, must be 0 if bodyProvider is null
-     * @param highPriority If true, queues before low priority
-     *     requests if possible
      */
     public RequestHandle queueRequest(
             String url, WebAddress uri, String method, Map<String, String> headers,
             EventHandler eventHandler,
-            InputStream bodyProvider, int bodyLength,
-            boolean highPriority) {
+            InputStream bodyProvider, int bodyLength) {
 
         if (HttpLog.LOGV) HttpLog.v("RequestQueue.queueRequest " + uri);
 
@@ -516,7 +474,7 @@
 
         // set up request
         req = new Request(method, httpHost, mProxyHost, uri.mPath, bodyProvider,
-                          bodyLength, eventHandler, headers, highPriority);
+                          bodyLength, eventHandler, headers);
 
         queueRequest(req, false);
 
@@ -558,24 +516,19 @@
         HttpLog.v("dump()");
         StringBuilder dump = new StringBuilder();
         int count = 0;
-        Iterator<Map.Entry<HttpHost, RequestSet>> iter;
+        Iterator<Map.Entry<HttpHost, LinkedList<Request>>> iter;
 
         // mActivePool.log(dump);
 
         if (!mPending.isEmpty()) {
             iter = mPending.entrySet().iterator();
             while (iter.hasNext()) {
-                Map.Entry<HttpHost, RequestSet> entry = iter.next();
+                Map.Entry<HttpHost, LinkedList<Request>> entry = iter.next();
                 String hostName = entry.getKey().getHostName();
                 StringBuilder line = new StringBuilder("p" + count++ + " " + hostName + " ");
 
-                RequestSet reqList = entry.getValue();
-                ListIterator reqIter = reqList.mHighPriority.listIterator(0);
-                while (iter.hasNext()) {
-                    Request request = (Request)iter.next();
-                    line.append(request + " ");
-                }
-                reqIter = reqList.mLowPriority.listIterator(0);
+                LinkedList<Request> reqList = entry.getValue();
+                ListIterator reqIter = reqList.listIterator(0);
                 while (iter.hasNext()) {
                     Request request = (Request)iter.next();
                     line.append(request + " ");
@@ -607,9 +560,10 @@
         Request ret = null;
 
         if (mNetworkConnected && mPending.containsKey(host)) {
-            RequestSet reqList = mPending.get(host);
-            ret = reqList.removeFirst();
-            if (reqList.isEmpty()) {
+            LinkedList<Request> reqList = mPending.get(host);
+            if (!reqList.isEmpty()) {
+                ret = reqList.removeFirst();
+            } else {
                 mPending.remove(host);
             }
         }
@@ -640,14 +594,18 @@
 
     protected synchronized void queueRequest(Request request, boolean head) {
         HttpHost host = request.mProxyHost == null ? request.mHost : request.mProxyHost;
-        RequestSet reqList;
+        LinkedList<Request> reqList;
         if (mPending.containsKey(host)) {
             reqList = mPending.get(host);
         } else {
-            reqList = new RequestSet();
+            reqList = new LinkedList<Request>();
             mPending.put(host, reqList);
         }
-        reqList.add(request, head);
+        if (head) {
+            reqList.addFirst(request);
+        } else {
+            reqList.add(request);
+        }
     }
 
 
@@ -660,14 +618,15 @@
     }
 
     /* helper */
-    private Request removeFirst(LinkedHashMap<HttpHost, RequestSet> requestQueue) {
+    private Request removeFirst(LinkedHashMap<HttpHost, LinkedList<Request>> requestQueue) {
         Request ret = null;
-        Iterator<Map.Entry<HttpHost, RequestSet>> iter = requestQueue.entrySet().iterator();
+        Iterator<Map.Entry<HttpHost, LinkedList<Request>>> iter = requestQueue.entrySet().iterator();
         if (iter.hasNext()) {
-            Map.Entry<HttpHost, RequestSet> entry = iter.next();
-            RequestSet reqList = entry.getValue();
-            ret = reqList.removeFirst();
-            if (reqList.isEmpty()) {
+            Map.Entry<HttpHost, LinkedList<Request>> entry = iter.next();
+            LinkedList<Request> reqList = entry.getValue();
+            if (!reqList.isEmpty()) {
+                ret = reqList.removeFirst();
+            } else {
                 requestQueue.remove(entry.getKey());
             }
         }
diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java
index 3d14af7..b54ad5d 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -151,34 +151,20 @@
                 int presentation, int callType, long start, int duration) {
             final ContentResolver resolver = context.getContentResolver();
 
-            // TODO(Moto): Which is correct: original code, this only changes the
-            // number if the number is empty and never changes the caller info name.
-        if (false) {
-            if (TextUtils.isEmpty(number)) {
-                if (presentation == Connection.PRESENTATION_RESTRICTED) {
-                    number = CallerInfo.PRIVATE_NUMBER;
-                } else if (presentation == Connection.PRESENTATION_PAYPHONE) {
-                    number = CallerInfo.PAYPHONE_NUMBER;
-                } else {
-                    number = CallerInfo.UNKNOWN_NUMBER;
-                }
-            }
-        } else {
-            // NEWCODE: From Motorola
-
-            //If this is a private number then set the number to Private, otherwise check
-            //if the number field is empty and set the number to Unavailable
+            // If this is a private number then set the number to Private, otherwise check
+            // if the number field is empty and set the number to Unavailable
             if (presentation == Connection.PRESENTATION_RESTRICTED) {
                 number = CallerInfo.PRIVATE_NUMBER;
-                ci.name = "";
+                if (ci != null) ci.name = "";
             } else if (presentation == Connection.PRESENTATION_PAYPHONE) {
                 number = CallerInfo.PAYPHONE_NUMBER;
-                ci.name = "";
-            } else if (TextUtils.isEmpty(number) || presentation == Connection.PRESENTATION_UNKNOWN) {
+                if (ci != null) ci.name = "";
+            } else if (TextUtils.isEmpty(number)
+                    || presentation == Connection.PRESENTATION_UNKNOWN) {
                 number = CallerInfo.UNKNOWN_NUMBER;
-                ci.name = "";
+                if (ci != null) ci.name = "";
             }
-        }
+
             ContentValues values = new ContentValues(5);
 
             values.put(NUMBER, number);
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 718a120..3f7d5b1 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -79,13 +79,7 @@
         }
     }
 
-    public interface AggregatesColumns {
-        /**
-         * The display name for the contact.
-         * <P>Type: TEXT</P>
-         */
-        public static final String DISPLAY_NAME = "display_name";
-
+    public interface ContactOptionsColumns {
         /**
          * The number of times a person has been contacted
          * <P>Type: INTEGER</P>
@@ -116,6 +110,14 @@
          * <P>Type: INTEGER (0 for false, 1 for true)</P>
          */
         public static final String SEND_TO_VOICEMAIL = "send_to_voicemail";
+    }
+
+    public interface AggregatesColumns {
+        /**
+         * The display name for the contact.
+         * <P>Type: TEXT</P>
+         */
+        public static final String DISPLAY_NAME = "display_name";
 
         /**
          * Reference to the row in the data table holding the primary phone number.
@@ -146,7 +148,8 @@
      * Constants for the aggregates table, which contains a record per group
      * of contact representing the same person.
      */
-    public static final class Aggregates implements BaseColumns, AggregatesColumns {
+    public static final class Aggregates implements BaseColumns, AggregatesColumns,
+            ContactOptionsColumns {
         /**
          * This utility class cannot be instantiated
          */
@@ -187,6 +190,9 @@
         public static final Uri CONTENT_SUMMARY_STREQUENT_FILTER_URI = Uri.withAppendedPath(
                 CONTENT_SUMMARY_STREQUENT_URI, "filter");
 
+        public static final Uri CONTENT_SUMMARY_GROUP_URI = Uri.withAppendedPath(
+                CONTENT_SUMMARY_URI, "group");
+
         /**
          * The MIME type of {@link #CONTENT_URI} providing a directory of
          * people.
@@ -244,7 +250,7 @@
     /**
      * Constants for the contacts table, which contains the base contact information.
      */
-    public static final class Contacts implements BaseColumns {
+    public static final class Contacts implements BaseColumns, ContactOptionsColumns {
         /**
          * This utility class cannot be instantiated
          */
@@ -322,6 +328,29 @@
         public static final String DIRTY = "dirty";
 
         /**
+         * The aggregation mode for this contact.
+         * <P>Type: INTEGER</P>
+         */
+        public static final String AGGREGATION_MODE = "aggregation_mode";
+
+        /**
+         * Aggregation mode: aggregate asynchronously.
+         */
+        public static final int AGGREGATION_MODE_DEFAULT = 0;
+
+        /**
+         * Aggregation mode: aggregate at the time the contact is inserted/updated.
+         */
+        public static final int AGGREGATION_MODE_IMMEDITATE = 1;
+
+        /**
+         * Aggregation mode: never aggregate this contact (note that the contact will not
+         * have a corresponding Aggregate and therefore will not be included in Aggregates
+         * query results.)
+         */
+        public static final int AGGREGATION_MODE_DISABLED = 2;
+
+        /**
          * A sub-directory of a single contact that contains all of their {@link Data} rows.
          * To access this directory append
          */
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 6f707cb..df3001d 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -2714,6 +2714,12 @@
         public static final String GMAIL_NUM_RETRY_UPHILL_OP = "gmail_discard_error_uphill_op";
 
         /**
+         * Controls if the protocol buffer version of the protocol will use a multipart request for
+         * attachment uploads. Value must be an integer where non-zero means true. Defaults to 0.
+         */
+        public static final String GMAIL_USE_MULTIPART_PROTOBUF = "gmail_use_multipart_protobuf";
+
+        /**
          * the transcoder URL for mobile devices.
          */
         public static final String TRANSCODER_URL = "mobile_transcoder_url";
@@ -2814,7 +2820,7 @@
                 "gtalk_nosync_heartbeat_ping_interval_ms";
 
         /**
-         * The maximum heartbeat interval used while on the WIFI network. 
+         * The maximum heartbeat interval used while on the WIFI network.
          */
         public static final String GTALK_SERVICE_WIFI_MAX_HEARTBEAT_INTERVAL_MS =
                 "gtalk_wifi_max_heartbeat_ping_interval_ms";
@@ -2885,7 +2891,38 @@
          */
         public static final String PUSH_MESSAGING_REGISTRATION_URL =
                 "push_messaging_registration_url";
-        
+
+        /**
+         * This is gdata url to lookup album and picture info from picasa web.
+         */
+        public static final String GTALK_PICASA_ALBUM_URL =
+            "gtalk_picasa_album_url";
+
+        /**
+         * This is the url to lookup picture info from flickr.
+         */
+        public static final String GTALK_FLICKR_PHOTO_INFO_URL =
+            "gtalk_flickr_photo_info_url";
+
+        /**
+         * This is the url to lookup an actual picture from flickr.
+         */
+        public static final String GTALK_FLICKR_PHOTO_URL =
+            "gtalk_flickr_photo_url";
+
+        /**
+         * This is the gdata url to lookup info on a youtube video.
+         */
+        public static final String GTALK_YOUTUBE_VIDEO_URL =
+            "gtalk_youtube_video_url";
+
+
+        /**
+         * This is the url for getting the app token for server-to-device data messaging.
+         */
+        public static final String DATA_MESSAGE_GET_APP_TOKEN_URL =
+                "data_messaging_get_app_token_url";
+
         /**
          * Enable use of ssl session caching.
          * 'db' - save each session in a (per process) database
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index 47a1285d..7a6f6bb 100644
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -44,7 +44,7 @@
  */
 public final class Telephony {
     private static final String TAG = "Telephony";
-    private static final boolean DEBUG = false;
+    private static final boolean DEBUG = true;
     private static final boolean LOCAL_LOGV = DEBUG ? Config.LOGD : Config.LOGV;
 
     // Constructor
@@ -1148,8 +1148,14 @@
             }
 
             Uri uri = uriBuilder.build();
+            if (DEBUG) {
+                Log.v(TAG, "getOrCreateThreadId uri: " + uri);
+            }
             Cursor cursor = SqliteWrapper.query(context, context.getContentResolver(),
                     uri, ID_PROJECTION, null, null, null);
+            if (DEBUG) {
+                Log.v(TAG, "getOrCreateThreadId cursor cnt: " + cursor.getCount());
+            }
             if (cursor != null) {
                 try {
                     if (cursor.moveToFirst()) {
@@ -1642,7 +1648,7 @@
          *
          * It is recommended to display <em>plmn</em> before / above <em>spn</em> if
          * both are displayed.
-         * 
+         *
          * <p>Note this is a protected intent that can only be sent
          * by the system.
          */
diff --git a/core/java/android/server/BluetoothDeviceService.java b/core/java/android/server/BluetoothDeviceService.java
index 77b1b1d..13d980d3 100644
--- a/core/java/android/server/BluetoothDeviceService.java
+++ b/core/java/android/server/BluetoothDeviceService.java
@@ -285,6 +285,7 @@
                 if (isEnabled()) {
                     SystemService.start("hsag");
                     SystemService.start("hfag");
+                    SystemService.start("opush");
                 }
                 break;
             case MESSAGE_FINISH_DISABLE:
diff --git a/core/java/android/server/search/SearchDialogWrapper.java b/core/java/android/server/search/SearchDialogWrapper.java
index 67be6a6..70c7d73 100644
--- a/core/java/android/server/search/SearchDialogWrapper.java
+++ b/core/java/android/server/search/SearchDialogWrapper.java
@@ -49,7 +49,7 @@
 
     private static final String SEARCH_UI_THREAD_NAME = "SearchDialog";
     private static final int SEARCH_UI_THREAD_PRIORITY =
-        android.os.Process.THREAD_PRIORITY_FOREGROUND;
+        android.os.Process.THREAD_PRIORITY_DEFAULT;
 
     // Takes no arguments
     private static final int MSG_INIT = 0;
diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index a2e70b8..4794fe1 100755
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -113,43 +113,131 @@
     /**
      * Internal constants for the TTS functionality
      *
-     * {@hide}
      */
     public class Engine {
         // default values for a TTS engine when settings are not found in the provider
+        /**
+         * {@hide}
+         */
         public static final int FALLBACK_TTS_DEFAULT_RATE = 100; // 1x
+        /**
+         * {@hide}
+         */
         public static final int FALLBACK_TTS_DEFAULT_PITCH = 100;// 1x
+        /**
+         * {@hide}
+         */
         public static final int FALLBACK_TTS_USE_DEFAULTS = 0; // false
+        /**
+         * {@hide}
+         */
         public static final String FALLBACK_TTS_DEFAULT_SYNTH = "com.svox.pico";
 
         // default values for rendering
         public static final int TTS_DEFAULT_STREAM = AudioManager.STREAM_MUSIC;
 
         // return codes for a TTS engine's check data activity
+        /**
+         * Indicates success when checking the installation status of the resources used by the
+         * text-to-speech engine with the android.intent.action.CHECK_TTS_DATA intent.
+         */
         public static final int CHECK_VOICE_DATA_PASS = 1;
+        /**
+         * Indicates failure when checking the installation status of the resources used by the
+         * text-to-speech engine with the android.intent.action.CHECK_TTS_DATA intent.
+         */
         public static final int CHECK_VOICE_DATA_FAIL = 0;
+        /**
+         * Indicates erroneous data when checking the installation status of the resources used by
+         * the text-to-speech engine with the android.intent.action.CHECK_TTS_DATA intent.
+         */
         public static final int CHECK_VOICE_DATA_BAD_DATA = -1;
+        /**
+         * Indicates missing resources when checking the installation status of the resources used
+         * by the text-to-speech engine with the android.intent.action.CHECK_TTS_DATA intent.
+         */
         public static final int CHECK_VOICE_DATA_MISSING_DATA = -2;
-        public static final int CHECK_VOICE_DATA_MISSING_DATA_NO_SDCARD = -3;
+        /**
+         * Indicates missing storage volume when checking the installation status of the resources
+         * used by the text-to-speech engine with the android.intent.action.CHECK_TTS_DATA intent.
+         */
+        public static final int CHECK_VOICE_DATA_MISSING_VOLUME = -3;
 
         // return codes for a TTS engine's check data activity
+        /**
+         * Extra information received with the android.intent.action.CHECK_TTS_DATA intent where
+         * the text-to-speech engine specifies the path to its resources.
+         */
         public static final String VOICE_DATA_ROOT_DIRECTORY = "dataRoot";
+        /**
+         * Extra information received with the android.intent.action.CHECK_TTS_DATA intent where
+         * the text-to-speech engine specifies the file names of its resources under the
+         * resource path.
+         */
         public static final String VOICE_DATA_FILES = "dataFiles";
+        /**
+         * Extra information received with the android.intent.action.CHECK_TTS_DATA intent where
+         * the text-to-speech engine specifies the locale associated with each resource file.
+         */
         public static final String VOICE_DATA_FILES_INFO = "dataFilesInfo";
 
-        // keys for the parameters passed with speak commands
+        // keys for the parameters passed with speak commands. Hidden keys are used internally
+        // to maintain engine state for each TextToSpeech instance.
+        /**
+         * {@hide}
+         */
         public static final String TTS_KEY_PARAM_RATE = "rate";
+        /**
+         * {@hide}
+         */
         public static final String TTS_KEY_PARAM_LANGUAGE = "language";
+        /**
+         * {@hide}
+         */
         public static final String TTS_KEY_PARAM_COUNTRY = "country";
+        /**
+         * {@hide}
+         */
         public static final String TTS_KEY_PARAM_VARIANT = "variant";
+        /**
+         * Parameter key to specify the audio stream type to be used when speaking text
+         * or playing back a file.
+         */
         public static final String TTS_KEY_PARAM_STREAM = "streamType";
+        /**
+         * Parameter key to identify an utterance in the completion listener after text has been
+         * spoken, a file has been played back or a silence duration has elapsed.
+         */
         public static final String TTS_KEY_PARAM_UTTERANCE_ID = "utteranceId";
+
+        // key positions in the array of cached parameters
+        /**
+         * {@hide}
+         */
         protected static final int TTS_PARAM_POSITION_RATE = 0;
+        /**
+         * {@hide}
+         */
         protected static final int TTS_PARAM_POSITION_LANGUAGE = 2;
+        /**
+         * {@hide}
+         */
         protected static final int TTS_PARAM_POSITION_COUNTRY = 4;
+        /**
+         * {@hide}
+         */
         protected static final int TTS_PARAM_POSITION_VARIANT = 6;
+        /**
+         * {@hide}
+         */
         protected static final int TTS_PARAM_POSITION_STREAM = 8;
+        /**
+         * {@hide}
+         */
         protected static final int TTS_PARAM_POSITION_UTTERANCE_ID = 10;
+        /**
+         * {@hide}
+         */
         protected static final int TTS_NB_CACHED_PARAMS = 6;
     }
 
@@ -362,6 +450,109 @@
 
 
     /**
+     * Adds a mapping between a string of text and a sound resource in a
+     * package.
+     *
+     * @see #TTS.playEarcon(String earcon, int queueMode, String[] params)
+     *
+     * @param earcon The name of the earcon
+     *            Example: <b><code>"[tick]"</code></b><br/>
+     *
+     * @param packagename
+     *            Pass the packagename of the application that contains the
+     *            resource. If the resource is in your own application (this is
+     *            the most common case), then put the packagename of your
+     *            application here.<br/>
+     *            Example: <b>"com.google.marvin.compass"</b><br/>
+     *            The packagename can be found in the AndroidManifest.xml of
+     *            your application.
+     *            <p>
+     *            <code>&lt;manifest xmlns:android=&quot;...&quot;
+     *      package=&quot;<b>com.google.marvin.compass</b>&quot;&gt;</code>
+     *            </p>
+     *
+     * @param resourceId
+     *            Example: <b><code>R.raw.tick_snd</code></b>
+     *
+     * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
+     */
+    public int addEarcon(String earcon, String packagename, int resourceId) {
+        synchronized(mStartLock) {
+            if (!mStarted) {
+                return TTS_ERROR;
+            }
+            try {
+                mITts.addEarcon(mPackageName, earcon, packagename, resourceId);
+                return TTS_SUCCESS;
+            } catch (RemoteException e) {
+                // TTS died; restart it.
+                Log.e("TextToSpeech.java - addEarcon", "RemoteException");
+                e.printStackTrace();
+                mStarted = false;
+                initTts();
+            } catch (NullPointerException e) {
+                // TTS died; restart it.
+                Log.e("TextToSpeech.java - addEarcon", "NullPointerException");
+                e.printStackTrace();
+                mStarted = false;
+                initTts();
+            } catch (IllegalStateException e) {
+                // TTS died; restart it.
+                Log.e("TextToSpeech.java - addEarcon", "IllegalStateException");
+                e.printStackTrace();
+                mStarted = false;
+                initTts();
+            }
+            return TTS_ERROR;
+        }
+    }
+
+
+    /**
+     * Adds a mapping between a string of text and a sound file. Using this, it
+     * is possible to add custom earcons.
+     *
+     * @param earcon
+     *            The name of the earcon
+     * @param filename
+     *            The full path to the sound file (for example:
+     *            "/sdcard/mysounds/tick.wav")
+     *
+     * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
+     */
+    public int addEarcon(String earcon, String filename) {
+        synchronized (mStartLock) {
+            if (!mStarted) {
+                return TTS_ERROR;
+            }
+            try {
+                mITts.addEarconFile(mPackageName, earcon, filename);
+                return TTS_SUCCESS;
+            } catch (RemoteException e) {
+                // TTS died; restart it.
+                Log.e("TextToSpeech.java - addEarcon", "RemoteException");
+                e.printStackTrace();
+                mStarted = false;
+                initTts();
+            } catch (NullPointerException e) {
+                // TTS died; restart it.
+                Log.e("TextToSpeech.java - addEarcon", "NullPointerException");
+                e.printStackTrace();
+                mStarted = false;
+                initTts();
+            } catch (IllegalStateException e) {
+                // TTS died; restart it.
+                Log.e("TextToSpeech.java - addEarcon", "IllegalStateException");
+                e.printStackTrace();
+                mStarted = false;
+                initTts();
+            }
+            return TTS_ERROR;
+        }
+    }
+
+
+    /**
      * Speaks the string using the specified queuing strategy and speech
      * parameters. Note that the speech parameters are not universally supported
      * by all engines and will be treated as a hint. The TTS library will try to
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 09ebeed5..5551f64 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -117,5 +117,32 @@
     
     private static final Object mStaticInit = new Object();
     private static boolean mInitialized = false;
+
+    /**
+     * Returns a display object which uses the metric's width/height instead.
+     * @hide
+     */
+    public static Display createMetricsBasedDisplay(int displayId, DisplayMetrics metrics) {
+        return new CompatibleDisplay(displayId, metrics);
+    }
+
+    private static class CompatibleDisplay extends Display {
+        private final DisplayMetrics mMetrics;
+
+        private CompatibleDisplay(int displayId, DisplayMetrics metrics) {
+            super(displayId);
+            mMetrics = metrics;
+        }
+
+        @Override
+        public int getWidth() {
+            return mMetrics.widthPixels;
+        }
+
+        @Override
+        public int getHeight() {
+            return mMetrics.heightPixels;
+        }
+    }
 }
 
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index 5776851..1e3cdb3 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -1374,6 +1374,15 @@
             // is non-null and we just want to scroll to whatever that
             // rectangle is).
             View focus = mRealFocusedView;
+
+            // When in touch mode, focus points to the previously focused view,
+            // which may have been removed from the view hierarchy. The following
+            // line checks whether the view is still in the hierarchy
+            if (focus == null || focus.getParent() == null) {
+                mRealFocusedView = null;
+                return false;
+            }
+
             if (focus != mLastScrolledFocus) {
                 // If the focus has changed, then ignore any requests to scroll
                 // to a rectangle; first we want to make sure the entire focus
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 2c32d8b..02e0515 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -358,6 +358,8 @@
     private class LocalWindowManager implements WindowManager {
         LocalWindowManager(WindowManager wm) {
             mWindowManager = wm;
+            mDefaultDisplay = mContext.getResources().getDefaultDisplay(
+                    mWindowManager.getDefaultDisplay());
         }
 
         public final void addView(View view, ViewGroup.LayoutParams params) {
@@ -420,10 +422,12 @@
         }
 
         public Display getDefaultDisplay() {
-            return mWindowManager.getDefaultDisplay();
+            return mDefaultDisplay;
         }
         
-        WindowManager mWindowManager;
+        private final WindowManager mWindowManager;
+
+        private final Display mDefaultDisplay;
     }
 
     /**
diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index e04ae72..5a7a233 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -465,8 +465,6 @@
      * @param postData If the method is "POST" postData is sent as the request
      *                 body. Is null when empty.
      * @param cacheMode The cache mode to use when loading this resource.
-     * @param isHighPriority True if this resource needs to be put at the front
-     *                       of the network queue.
      * @param synchronous True if the load is synchronous.
      * @return A newly created LoadListener object.
      */
@@ -476,7 +474,6 @@
                                               HashMap headers,
                                               byte[] postData,
                                               int cacheMode,
-                                              boolean isHighPriority,
                                               boolean synchronous) {
         PerfChecker checker = new PerfChecker();
 
@@ -542,8 +539,8 @@
 
         if (DebugFlags.BROWSER_FRAME) {
             Log.v(LOGTAG, "startLoadingResource: url=" + url + ", method="
-                    + method + ", postData=" + postData + ", isHighPriority="
-                    + isHighPriority + ", isMainFramePage=" + isMainFramePage);
+                    + method + ", postData=" + postData + ", isMainFramePage="
+                    + isMainFramePage);
         }
 
         // Create a LoadListener
@@ -568,8 +565,7 @@
             CacheManager.endCacheTransaction();
         }
 
-        FrameLoader loader = new FrameLoader(loadListener, mSettings,
-                method, isHighPriority);
+        FrameLoader loader = new FrameLoader(loadListener, mSettings, method);
         loader.setHeaders(headers);
         loader.setPostData(postData);
         // Set the load mode to the mode used for the current page.
diff --git a/core/java/android/webkit/FrameLoader.java b/core/java/android/webkit/FrameLoader.java
index f98c5d3..8298729 100644
--- a/core/java/android/webkit/FrameLoader.java
+++ b/core/java/android/webkit/FrameLoader.java
@@ -28,7 +28,6 @@
 
     private final LoadListener mListener;
     private final String mMethod;
-    private final boolean mIsHighPriority;
     private final WebSettings mSettings;
     private Map<String, String> mHeaders;
     private byte[] mPostData;
@@ -52,11 +51,10 @@
     private static final String LOGTAG = "webkit";
     
     FrameLoader(LoadListener listener, WebSettings settings,
-            String method, boolean highPriority) {
+            String method) {
         mListener = listener;
         mHeaders = null;
         mMethod = method;
-        mIsHighPriority = highPriority;
         mCacheMode = WebSettings.LOAD_NORMAL;
         mSettings = settings;
     }
@@ -175,8 +173,7 @@
             // as response from the cache could be a redirect
             // and we may need to initiate a network request if the cache
             // can't satisfy redirect URL
-            mListener.setRequestData(mMethod, mHeaders, mPostData, 
-                    mIsHighPriority);
+            mListener.setRequestData(mMethod, mHeaders, mPostData);
             return true;
         }
 
@@ -190,7 +187,7 @@
         
         try {
             ret = mNetwork.requestURL(mMethod, mHeaders,
-                    mPostData, mListener, mIsHighPriority);
+                    mPostData, mListener);
         } catch (android.net.ParseException ex) {
             error = EventHandler.ERROR_BAD_URL;
         } catch (java.lang.RuntimeException ex) {
diff --git a/core/java/android/webkit/LoadListener.java b/core/java/android/webkit/LoadListener.java
index ea12f36..c0b6dab 100644
--- a/core/java/android/webkit/LoadListener.java
+++ b/core/java/android/webkit/LoadListener.java
@@ -38,6 +38,7 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
 import java.util.Vector;
 import java.util.regex.Pattern;
@@ -70,7 +71,12 @@
     private static final int HTTP_NOT_FOUND = 404;
     private static final int HTTP_PROXY_AUTH = 407;
 
-    private static final String CERT_MIMETYPE = "application/x-x509-ca-cert";
+    private static HashSet<String> sCertificateMimeTypeMap;
+    static {
+        sCertificateMimeTypeMap = new HashSet<String>();
+        sCertificateMimeTypeMap.add("application/x-x509-ca-cert");
+        sCertificateMimeTypeMap.add("application/x-pkcs12");
+    }
 
     private static int sNativeLoaderCount;
 
@@ -104,7 +110,6 @@
     private String mMethod;
     private Map<String, String> mRequestHeaders;
     private byte[] mPostData;
-    private boolean mIsHighPriority;
     // Flag to indicate that this load is synchronous.
     private boolean mSynchronous;
     private Vector<Message> mMessageQueue;
@@ -312,7 +317,17 @@
             if (mMimeType.equals("text/plain") ||
                     mMimeType.equals("application/octet-stream")) {
 
-                String newMimeType = guessMimeTypeFromExtension();
+                // for attachment, use the filename in the Content-Disposition
+                // to guess the mimetype
+                String contentDisposition = headers.getContentDisposition();
+                String url = null;
+                if (contentDisposition != null) {
+                    url = URLUtil.parseContentDisposition(contentDisposition);
+                }
+                if (url == null) {
+                    url = mUrl;
+                }
+                String newMimeType = guessMimeTypeFromExtension(url);
                 if (newMimeType != null) {
                     mMimeType = newMimeType;
                 }
@@ -775,14 +790,12 @@
      * @param method
      * @param headers
      * @param postData
-     * @param isHighPriority
      */
     void setRequestData(String method, Map<String, String> headers, 
-            byte[] postData, boolean isHighPriority) {
+            byte[] postData) {
         mMethod = method;
         mRequestHeaders = headers;
         mPostData = postData;
-        mIsHighPriority = isHighPriority;
     }
 
     /**
@@ -921,7 +934,7 @@
 
     // This commits the headers without checking the response status code.
     private void commitHeaders() {
-        if (mIsMainPageLoader && CERT_MIMETYPE.equals(mMimeType)) {
+        if (mIsMainPageLoader && sCertificateMimeTypeMap.contains(mMimeType)) {
             // In the case of downloading certificate, we will save it to the
             // Keystore in commitLoad. Do not call webcore.
             return;
@@ -966,7 +979,7 @@
     private void commitLoad() {
         if (mCancelled) return;
 
-        if (mIsMainPageLoader && CERT_MIMETYPE.equals(mMimeType)) {
+        if (mIsMainPageLoader && sCertificateMimeTypeMap.contains(mMimeType)) {
             // In the case of downloading certificate, we will save it to the
             // Keystore and stop the current loading so that it will not
             // generate a new history page
@@ -1178,7 +1191,7 @@
                     // Network.requestURL.
                     Network network = Network.getInstance(getContext());
                     if (!network.requestURL(mMethod, mRequestHeaders,
-                            mPostData, this, mIsHighPriority)) {
+                            mPostData, this)) {
                         // Signal a bad url error if we could not load the
                         // redirection.
                         handleError(EventHandler.ERROR_BAD_URL,
@@ -1396,7 +1409,7 @@
             // of frames. If no content-type was specified, it is fine to
             // default to text/html.
             mMimeType = "text/html";
-            String newMimeType = guessMimeTypeFromExtension();
+            String newMimeType = guessMimeTypeFromExtension(mUrl);
             if (newMimeType != null) {
                 mMimeType = newMimeType;
             }
@@ -1406,14 +1419,14 @@
     /**
      * guess MIME type based on the file extension.
      */
-    private String guessMimeTypeFromExtension() {
+    private String guessMimeTypeFromExtension(String url) {
         // PENDING: need to normalize url
         if (DebugFlags.LOAD_LISTENER) {
-            Log.v(LOGTAG, "guessMimeTypeFromExtension: mURL = " + mUrl);
+            Log.v(LOGTAG, "guessMimeTypeFromExtension: url = " + url);
         }
 
         return MimeTypeMap.getSingleton().getMimeTypeFromExtension(
-                MimeTypeMap.getFileExtensionFromUrl(mUrl));
+                MimeTypeMap.getFileExtensionFromUrl(url));
     }
 
     /**
diff --git a/core/java/android/webkit/MimeTypeMap.java b/core/java/android/webkit/MimeTypeMap.java
index 096f38a..648ec27 100644
--- a/core/java/android/webkit/MimeTypeMap.java
+++ b/core/java/android/webkit/MimeTypeMap.java
@@ -335,6 +335,7 @@
             sMimeTypeMap.loadEntry("application/x-object", "o", false);
             sMimeTypeMap.loadEntry("application/x-oz-application", "oza", 
                     false);
+            sMimeTypeMap.loadEntry("application/x-pkcs12", "p12", false);
             sMimeTypeMap.loadEntry("application/x-pkcs7-certreqresp", "p7r", 
                     false);
             sMimeTypeMap.loadEntry("application/x-pkcs7-crl", "crl", false);
diff --git a/core/java/android/webkit/Network.java b/core/java/android/webkit/Network.java
index 8c2b09b..fb60109 100644
--- a/core/java/android/webkit/Network.java
+++ b/core/java/android/webkit/Network.java
@@ -149,14 +149,12 @@
      * @param headers The http headers.
      * @param postData The body of the request.
      * @param loader A LoadListener for receiving the results of the request.
-     * @param isHighPriority True if this is high priority request.
      * @return True if the request was successfully queued.
      */
     public boolean requestURL(String method,
                               Map<String, String> headers,
                               byte [] postData,
-                              LoadListener loader,
-                              boolean isHighPriority) {
+                              LoadListener loader) {
 
         String url = loader.url();
 
@@ -188,7 +186,7 @@
 
         RequestHandle handle = q.queueRequest(
                 url, loader.getWebAddress(), method, headers, loader,
-                bodyProvider, bodyLength, isHighPriority);
+                bodyProvider, bodyLength);
         loader.attachRequestHandle(handle);
 
         if (loader.isSynchronous()) {
diff --git a/core/java/android/webkit/URLUtil.java b/core/java/android/webkit/URLUtil.java
index de70fc2..1d18289 100644
--- a/core/java/android/webkit/URLUtil.java
+++ b/core/java/android/webkit/URLUtil.java
@@ -348,7 +348,7 @@
      * This header provides a filename for content that is going to be
      * downloaded to the file system. We only support the attachment type.
      */
-    private static String parseContentDisposition(String contentDisposition) {
+    static String parseContentDisposition(String contentDisposition) {
         try {
             Matcher m = CONTENT_DISPOSITION_PATTERN.matcher(contentDisposition);
             if (m.find()) {
diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java
index be3dd19..ae509c5 100644
--- a/core/java/android/widget/AutoCompleteTextView.java
+++ b/core/java/android/widget/AutoCompleteTextView.java
@@ -31,6 +31,7 @@
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.WindowManager;
 import android.view.inputmethod.CompletionInfo;
 import android.view.inputmethod.InputMethodManager;
 import android.view.inputmethod.EditorInfo;
@@ -141,6 +142,7 @@
 
         mPopup = new PopupWindow(context, attrs,
                 com.android.internal.R.attr.autoCompleteTextViewStyle);
+        mPopup.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
 
         TypedArray a =
             context.obtainStyledAttributes(
diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java
index 54f2707..3b9f1de 100644
--- a/core/java/android/widget/DatePicker.java
+++ b/core/java/android/widget/DatePicker.java
@@ -110,6 +110,8 @@
                  * subtract by one to ensure our internal state is always 0-11
                  */
                 mMonth = newVal - 1;
+                // Adjust max day of the month
+                adjustMaxDay();
                 if (mOnDateChangedListener != null) {
                     mOnDateChangedListener.onDateChanged(DatePicker.this, mYear, mMonth, mDay);
                 }
@@ -121,9 +123,12 @@
         mYearPicker.setOnChangeListener(new OnChangedListener() {
             public void onChanged(NumberPicker picker, int oldVal, int newVal) {
                 mYear = newVal;
+                // Adjust max day for leap years if needed
+                adjustMaxDay();
                 if (mOnDateChangedListener != null) {
                     mOnDateChangedListener.onDateChanged(DatePicker.this, mYear, mMonth, mDay);
                 }
+                updateDaySpinner();
             }
         });
         
@@ -318,4 +323,14 @@
     public int getDayOfMonth() {
         return mDay;
     }
+
+    private void adjustMaxDay(){
+        Calendar cal = Calendar.getInstance();
+        cal.set(Calendar.YEAR, mYear);
+        cal.set(Calendar.MONTH, mMonth);
+        int max = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
+        if (mDay > max) {
+            mDay = max;
+        }
+    }
 }
diff --git a/core/java/android/widget/Filter.java b/core/java/android/widget/Filter.java
index 7e55c78..bdecf62 100644
--- a/core/java/android/widget/Filter.java
+++ b/core/java/android/widget/Filter.java
@@ -85,7 +85,8 @@
     public final void filter(CharSequence constraint, FilterListener listener) {
         synchronized (mLock) {
             if (mThreadHandler == null) {
-                HandlerThread thread = new HandlerThread(THREAD_NAME);
+                HandlerThread thread = new HandlerThread(
+                        THREAD_NAME, android.os.Process.THREAD_PRIORITY_BACKGROUND);
                 thread.start();
                 mThreadHandler = new RequestHandler(thread.getLooper());
             }
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index 0c2cd55..90fbb77 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -27,7 +27,6 @@
 import android.view.Gravity;
 import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
-import android.view.WindowManagerImpl;
 import android.view.ViewTreeObserver.OnScrollChangedListener;
 import android.view.View.OnTouchListener;
 import android.graphics.PixelFormat;
@@ -82,6 +81,7 @@
     private View mPopupView;
     private boolean mFocusable;
     private int mInputMethodMode = INPUT_METHOD_FROM_FOCUSABLE;
+    private int mSoftInputMode;
     private boolean mTouchable = true;
     private boolean mOutsideTouchable = false;
     private boolean mClippingEnabled = true;
@@ -446,6 +446,30 @@
     public void setInputMethodMode(int mode) {
         mInputMethodMode = mode;
     }
+
+    /**
+     * Sets the operating mode for the soft input area.
+     *
+     * @param mode The desired mode, see
+     *        {@link android.view.WindowManager.LayoutParams#softInputMode}
+     *        for the full list
+     *
+     * @see android.view.WindowManager.LayoutParams#softInputMode
+     * @see #getSoftInputMode()
+     */
+    public void setSoftInputMode(int mode) {
+        mSoftInputMode = mode;
+    }
+
+    /**
+     * Returns the current value in {@link #setSoftInputMode(int)}.
+     *
+     * @see #setSoftInputMode(int)
+     * @see android.view.WindowManager.LayoutParams#softInputMode
+     */
+    public int getSoftInputMode() {
+        return mSoftInputMode;
+    }
     
     /**
      * <p>Indicates whether the popup window receives touch events.</p>
@@ -822,7 +846,7 @@
         p.flags = computeFlags(p.flags);
         p.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
         p.token = token;
-        p.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
+        p.softInputMode = mSoftInputMode;
         p.setTitle("PopupWindow:" + Integer.toHexString(hashCode()));
 
         return p;
diff --git a/core/java/com/android/internal/widget/NumberPicker.java b/core/java/com/android/internal/widget/NumberPicker.java
index 2f08c8d..0424ced 100644
--- a/core/java/com/android/internal/widget/NumberPicker.java
+++ b/core/java/com/android/internal/widget/NumberPicker.java
@@ -243,9 +243,11 @@
     private void validateCurrentView(CharSequence str) {
         int val = getSelectedPos(str.toString());
         if ((val >= mStart) && (val <= mEnd)) {
-            mPrevious = mCurrent;
-            mCurrent = val;
-            notifyChange();
+            if (mCurrent != val) {
+                mPrevious = mCurrent;
+                mCurrent = val;
+                notifyChange();
+            }
         }
         updateView();
     }
diff --git a/core/jni/.android_server_BluetoothEventLoop.cpp.swp b/core/jni/.android_server_BluetoothEventLoop.cpp.swp
new file mode 100644
index 0000000..d36e403
--- /dev/null
+++ b/core/jni/.android_server_BluetoothEventLoop.cpp.swp
Binary files differ
diff --git a/core/res/res/values-he-rIL/donottranslate-cldr.xml b/core/res/res/values-he-rIL/donottranslate-cldr.xml
index e3feb1e..3378ed7 100644
--- a/core/res/res/values-he-rIL/donottranslate-cldr.xml
+++ b/core/res/res/values-he-rIL/donottranslate-cldr.xml
@@ -61,20 +61,20 @@
     <string name="day_of_week_long_friday">יום שישי</string>
     <string name="day_of_week_long_saturday">יום שבת</string>
 
-    <string name="day_of_week_medium_sunday">יום א'</string>
-    <string name="day_of_week_medium_monday">יום ב'</string>
-    <string name="day_of_week_medium_tuesday">יום ג'</string>
-    <string name="day_of_week_medium_wednesday">יום ד'</string>
-    <string name="day_of_week_medium_thursday">יום ה'</string>
-    <string name="day_of_week_medium_friday">יום ו'</string>
+    <string name="day_of_week_medium_sunday">יום א\'</string>
+    <string name="day_of_week_medium_monday">יום ב\'</string>
+    <string name="day_of_week_medium_tuesday">יום ג\'</string>
+    <string name="day_of_week_medium_wednesday">יום ד\'</string>
+    <string name="day_of_week_medium_thursday">יום ה\'</string>
+    <string name="day_of_week_medium_friday">יום ו\'</string>
     <string name="day_of_week_medium_saturday">שבת</string>
 
-    <string name="day_of_week_short_sunday">יום א'</string>
-    <string name="day_of_week_short_monday">יום ב'</string>
-    <string name="day_of_week_short_tuesday">יום ג'</string>
-    <string name="day_of_week_short_wednesday">יום ד'</string>
-    <string name="day_of_week_short_thursday">יום ה'</string>
-    <string name="day_of_week_short_friday">יום ו'</string>
+    <string name="day_of_week_short_sunday">יום א\'</string>
+    <string name="day_of_week_short_monday">יום ב\'</string>
+    <string name="day_of_week_short_tuesday">יום ג\'</string>
+    <string name="day_of_week_short_wednesday">יום ד\'</string>
+    <string name="day_of_week_short_thursday">יום ה\'</string>
+    <string name="day_of_week_short_friday">יום ו\'</string>
     <string name="day_of_week_short_saturday">שבת</string>
 
     <string name="day_of_week_shortest_sunday">א</string>
diff --git a/core/res/res/values-pt-rBR/donottranslate-cldr.xml b/core/res/res/values-pt-rBR/donottranslate-cldr.xml
index 4729055..1111658 100644
--- a/core/res/res/values-pt-rBR/donottranslate-cldr.xml
+++ b/core/res/res/values-pt-rBR/donottranslate-cldr.xml
@@ -95,7 +95,7 @@
     <string name="hour_minute_ampm">%-l:%M %p</string>
     <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
     <string name="twelve_hour_time_format">h:mm a</string>
-    <string name="twenty_four_hour_time_format">H'h'mm</string>
+    <string name="twenty_four_hour_time_format">H\'h\'mm</string>
     <string name="numeric_date">%d/%m/%Y</string>
     <string name="numeric_date_format">dd/MM/yyyy</string>
     <string name="numeric_date_template">"%s/%s/%s"</string>
diff --git a/core/res/res/values-pt-rPT/donottranslate-cldr.xml b/core/res/res/values-pt-rPT/donottranslate-cldr.xml
index f38a2d0..197cb6e 100644
--- a/core/res/res/values-pt-rPT/donottranslate-cldr.xml
+++ b/core/res/res/values-pt-rPT/donottranslate-cldr.xml
@@ -95,7 +95,7 @@
     <string name="hour_minute_ampm">%-l:%M %p</string>
     <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
     <string name="twelve_hour_time_format">h:mm a</string>
-    <string name="twenty_four_hour_time_format">H'h'mm</string>
+    <string name="twenty_four_hour_time_format">H\'h\'mm</string>
     <string name="numeric_date">%d/%m/%Y</string>
     <string name="numeric_date_format">dd/MM/yyyy</string>
     <string name="numeric_date_template">"%s/%s/%s"</string>
diff --git a/core/res/res/values-pt/donottranslate-cldr.xml b/core/res/res/values-pt/donottranslate-cldr.xml
index 4729055..1111658 100644
--- a/core/res/res/values-pt/donottranslate-cldr.xml
+++ b/core/res/res/values-pt/donottranslate-cldr.xml
@@ -95,7 +95,7 @@
     <string name="hour_minute_ampm">%-l:%M %p</string>
     <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
     <string name="twelve_hour_time_format">h:mm a</string>
-    <string name="twenty_four_hour_time_format">H'h'mm</string>
+    <string name="twenty_four_hour_time_format">H\'h\'mm</string>
     <string name="numeric_date">%d/%m/%Y</string>
     <string name="numeric_date_format">dd/MM/yyyy</string>
     <string name="numeric_date_template">"%s/%s/%s"</string>
diff --git a/core/res/res/values-vi-rVN/donottranslate-cldr.xml b/core/res/res/values-vi-rVN/donottranslate-cldr.xml
index 72ff8b6..6f2d342 100644
--- a/core/res/res/values-vi-rVN/donottranslate-cldr.xml
+++ b/core/res/res/values-vi-rVN/donottranslate-cldr.xml
@@ -133,8 +133,8 @@
     <string name="same_month_md1_time1_md2_time2">%3$s %2$s %5$s - %8$s %7$s %10$s</string>
     <string name="same_year_wday1_md1_time1_wday2_md2_time2">%1$s %3$s %2$s %5$s - %6$s %8$s %7$s %10$s</string>
     <string name="same_month_wday1_md1_time1_wday2_md2_time2">%1$s %3$s %2$s %5$s - %6$s %8$s %7$s %10$s</string>
-    <string name="same_year_mdy1_time1_mdy2_time2">Ngày %3$s tháng %2$s năm %4$s %5$s - 'Ngày %8$s tháng %7$s năm %9$s %10$s</string>
-    <string name="same_month_mdy1_time1_mdy2_time2">Ngày %3$s tháng %2$s năm %4$s %5$s - 'Ngày %8$s tháng %7$s năm %9$s %10$s</string>
+    <string name="same_year_mdy1_time1_mdy2_time2">Ngày %3$s tháng %2$s năm %4$s %5$s - \'Ngày %8$s tháng %7$s năm %9$s %10$s</string>
+    <string name="same_month_mdy1_time1_mdy2_time2">Ngày %3$s tháng %2$s năm %4$s %5$s - \'Ngày %8$s tháng %7$s năm %9$s %10$s</string>
     <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%1$s, %3$s %2$s %4$s %5$s - %6$s, %8$s %7$s %9$s %10$s</string>
     <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%1$s, %3$s %2$s %4$s %5$s - %6$s, %8$s %7$s %9$s %10$s</string>
     <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %3$s %2$s %4$s - %6$s, %8$s %7$s %9$s</string>
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index a3579c7..20aa6e7 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -133,6 +133,7 @@
     <assign-permission name="android.permission.READ_FRAME_BUFFER" uid="shell" />
     <assign-permission name="android.permission.DEVICE_POWER" uid="shell" />
     <assign-permission name="android.permission.INSTALL_LOCATION_PROVIDER" uid="shell" />
+    <assign-permission name="android.permission.BACKUP" uid="shell" />
 
     <assign-permission name="android.permission.MODIFY_AUDIO_SETTINGS" uid="media" />
     <assign-permission name="android.permission.ACCESS_DRM" uid="media" />
@@ -147,5 +148,7 @@
             file="/system/framework/android.test.runner.jar" />
     <library name="com.android.im.plugin"
             file="/system/framework/com.android.im.plugin.jar"/>          
+    <library name="javax.obex"
+            file="/system/framework/javax.obex.jar"/>
 
 </permissions>
diff --git a/data/sounds/AudioPackage2.mk b/data/sounds/AudioPackage2.mk
index aea3f0b..649787e 100644
--- a/data/sounds/AudioPackage2.mk
+++ b/data/sounds/AudioPackage2.mk
@@ -23,7 +23,7 @@
 	$(LOCAL_PATH)/Ring_Digital_02.ogg:system/media/audio/ringtones/Ring_Digital_02.ogg \
 	$(LOCAL_PATH)/Ring_Synth_04.ogg:system/media/audio/ringtones/Ring_Synth_04.ogg \
 	$(LOCAL_PATH)/Ring_Synth_02.ogg:system/media/audio/ringtones/Ring_Synth_02.ogg \
-	$(LOCAL_PATH)/Silence.ogg:system/media/audio/ringtones/Silence.ogg \
+	$(LOCAL_PATH)/Silence.ogg:system/media/audio/ringtones/notifications/Silence.ogg \
 	$(LOCAL_PATH)/newwavelabs/BeatPlucker.ogg:system/media/audio/ringtones/BeatPlucker.ogg \
 	$(LOCAL_PATH)/newwavelabs/BentleyDubs.ogg:system/media/audio/ringtones/BentleyDubs.ogg \
 	$(LOCAL_PATH)/newwavelabs/BirdLoop.ogg:system/media/audio/ringtones/BirdLoop.ogg \
diff --git a/data/sounds/OriginalAudio.mk b/data/sounds/OriginalAudio.mk
index 8c8fc32..fc1e921 100644
--- a/data/sounds/OriginalAudio.mk
+++ b/data/sounds/OriginalAudio.mk
@@ -22,7 +22,7 @@
 	$(LOCAL_PATH)/Ring_Digital_02.ogg:system/media/audio/ringtones/Ring_Digital_02.ogg \
 	$(LOCAL_PATH)/Ring_Synth_04.ogg:system/media/audio/ringtones/Ring_Synth_04.ogg \
 	$(LOCAL_PATH)/Ring_Synth_02.ogg:system/media/audio/ringtones/Ring_Synth_02.ogg \
-	$(LOCAL_PATH)/Silence.ogg:system/media/audio/ringtones/Silence.ogg \
+	$(LOCAL_PATH)/Silence.ogg:system/media/audio/ringtones/notifications/Silence.ogg \
 	$(LOCAL_PATH)/newwavelabs/BeatPlucker.ogg:system/media/audio/ringtones/BeatPlucker.ogg \
 	$(LOCAL_PATH)/newwavelabs/BentleyDubs.ogg:system/media/audio/ringtones/BentleyDubs.ogg \
 	$(LOCAL_PATH)/newwavelabs/BirdLoop.ogg:system/media/audio/ringtones/BirdLoop.ogg \
diff --git a/include/media/PVPlayer.h b/include/media/PVPlayer.h
index eb4595b..d8a677f 100644
--- a/include/media/PVPlayer.h
+++ b/include/media/PVPlayer.h
@@ -63,6 +63,7 @@
     static void         run_set_video_surface(status_t s, void *cookie, bool cancelled);
     static void         run_set_audio_output(status_t s, void *cookie, bool cancelled);
     static void         run_prepare(status_t s, void *cookie, bool cancelled);
+    static void         check_for_live_streaming(status_t s, void *cookie, bool cancelled);
 
     PlayerDriver*               mPlayerDriver;
     char *                      mDataSourcePath;
diff --git a/include/private/ui/SharedState.h b/include/private/ui/SharedState.h
index 3bc7979..c9f6b5e 100644
--- a/include/private/ui/SharedState.h
+++ b/include/private/ui/SharedState.h
@@ -98,6 +98,8 @@
 
 struct per_client_cblk_t   // 4KB max
 {
+    per_client_cblk_t() : lock(Mutex::SHARED) { }
+
                 Mutex           lock;
                 Condition       cv;
                 layer_cblk_t    layers[NUM_LAYERS_MAX] __attribute__((aligned(32)));
diff --git a/include/ui/EventHub.h b/include/ui/EventHub.h
index e12c4f1..d9c0af2 100644
--- a/include/ui/EventHub.h
+++ b/include/ui/EventHub.h
@@ -73,6 +73,9 @@
     int getKeycodeState(int key) const;
     int getKeycodeState(int32_t deviceId, int key) const;
     
+    status_t scancodeToKeycode(int32_t deviceId, int scancode,
+            int32_t* outKeycode, uint32_t* outFlags) const;
+    
     // special type codes when devices are added/removed.
     enum {
         DEVICE_ADDED = 0x10000000,
@@ -121,7 +124,7 @@
     mutable Mutex   mLock;
     
     bool            mHaveFirstKeyboard;
-    int32_t         mFirstKeyboardId; // the API is that the build in keyboard is id 0, so map it
+    int32_t         mFirstKeyboardId; // the API is that the built-in keyboard is id 0, so map it
     
     struct device_ent {
         device_t* device;
diff --git a/include/utils/threads.h b/include/utils/threads.h
index 5c03965..e9b0788 100644
--- a/include/utils/threads.h
+++ b/include/utils/threads.h
@@ -190,8 +190,14 @@
  */
 class Mutex {
 public:
+    enum {
+        NORMAL = 0,
+        SHARED = 1
+    };
+    
                 Mutex();
                 Mutex(const char* name);
+                Mutex(int type, const char* name = NULL);
                 ~Mutex();
 
     // lock or unlock the mutex
@@ -235,6 +241,17 @@
 inline Mutex::Mutex(const char* name) {
     pthread_mutex_init(&mMutex, NULL);
 }
+inline Mutex::Mutex(int type, const char* name) {
+    if (type == SHARED) {
+        pthread_mutexattr_t attr;
+        pthread_mutexattr_init(&attr);
+        pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
+        pthread_mutex_init(&mMutex, &attr);
+        pthread_mutexattr_destroy(&attr);
+    } else {
+        pthread_mutex_init(&mMutex, NULL);
+    }
+}
 inline Mutex::~Mutex() {
     pthread_mutex_destroy(&mMutex);
 }
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
index 598a356..ffc0278 100644
--- a/libs/audioflinger/AudioFlinger.cpp
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -212,6 +212,7 @@
     } else {
         mA2dpMixerThread->getTracks_l(tracks, activeTracks);
         mHardwareMixerThread->putTracks_l(tracks, activeTracks);
+        mA2dpMixerThread->mOutput->standby();
     }
     mA2dpEnabled = enable;
     mNotifyA2dpChange = true;
diff --git a/libs/ui/EventHub.cpp b/libs/ui/EventHub.cpp
index 13c30a7..a72f055 100644
--- a/libs/ui/EventHub.cpp
+++ b/libs/ui/EventHub.cpp
@@ -240,6 +240,35 @@
     return 0;
 }
 
+status_t EventHub::scancodeToKeycode(int32_t deviceId, int scancode,
+        int32_t* outKeycode, uint32_t* outFlags) const
+{
+    AutoMutex _l(mLock);
+    device_t* device = getDevice(deviceId);
+    
+    if (device != NULL && device->layoutMap != NULL) {
+        status_t err = device->layoutMap->map(scancode, outKeycode, outFlags);
+        if (err == NO_ERROR) {
+            return NO_ERROR;
+        }
+    }
+    
+    if (mHaveFirstKeyboard) {
+        device = getDevice(mFirstKeyboardId);
+        
+        if (device != NULL && device->layoutMap != NULL) {
+            status_t err = device->layoutMap->map(scancode, outKeycode, outFlags);
+            if (err == NO_ERROR) {
+                return NO_ERROR;
+            }
+        }
+    }
+    
+    *outKeycode = 0;
+    *outFlags = 0;
+    return NAME_NOT_FOUND;
+}
+
 EventHub::device_t* EventHub::getDevice(int32_t deviceId) const
 {
     if (deviceId == 0) deviceId = mFirstKeyboardId;
diff --git a/libs/utils/BackupData.cpp b/libs/utils/BackupData.cpp
index cce754a..be04777 100644
--- a/libs/utils/BackupData.cpp
+++ b/libs/utils/BackupData.cpp
@@ -298,10 +298,12 @@
     }
     if (m_header.entity.dataSize > 0) {
         int pos = lseek(m_fd, m_dataEndPos, SEEK_SET);
-        return pos == -1 ? (int)errno : (int)NO_ERROR;
-    } else {
-        return NO_ERROR;
+        if (pos == -1) {
+            return errno;
+        }
     }
+    SKIP_PADDING();
+    return NO_ERROR;
 }
 
 ssize_t
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index af7dae5..7b9eda7 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -891,7 +891,7 @@
 // =========================================================================
 
 audio_track_cblk_t::audio_track_cblk_t()
-    : user(0), server(0), userBase(0), serverBase(0), buffers(0), frameCount(0),
+    : lock(Mutex::SHARED), user(0), server(0), userBase(0), serverBase(0), buffers(0), frameCount(0),
     loopStart(UINT_MAX), loopEnd(UINT_MAX), loopCount(0), volumeLR(0), flowControlFlag(1), forceReady(0)
 {
 }
diff --git a/obex/javax/obex/Authenticator.java b/obex/javax/obex/Authenticator.java
index 7246e91..ec226fb 100644
--- a/obex/javax/obex/Authenticator.java
+++ b/obex/javax/obex/Authenticator.java
@@ -34,53 +34,50 @@
 
 /**
  * This interface provides a way to respond to authentication challenge and
- * authentication response headers.  When a client or server receives an
+ * authentication response headers. When a client or server receives an
  * authentication challenge or authentication response header, the
  * <code>onAuthenticationChallenge()</code> or
- * <code>onAuthenticationResponse()</code> will be called, respectively, by
- * the implementation.
+ * <code>onAuthenticationResponse()</code> will be called, respectively, by the
+ * implementation.
  * <P>
  * For more information on how the authentication procedure works in OBEX,
- * please review the IrOBEX specification at
- * <A HREF="http://www.irda.org">http://www.irda.org</A>.
+ * please review the IrOBEX specification at <A
+ * HREF="http://www.irda.org">http://www.irda.org</A>.
  * <P>
  * <STRONG>Authentication Challenges</STRONG>
  * <P>
  * When a client or server receives an authentication challenge header, the
- * <code>onAuthenticationChallenge()</code> method will be invoked by the
- * OBEX API implementation.  The application will then return the user name
- * (if needed) and password via a <code>PasswordAuthentication</code> object.
- * The password in this object is not sent in the authentication response.
- * Instead, the 16-byte challenge received in the authentication challenge is
- * combined with the password returned from the
- * <code>onAuthenticationChallenge()</code> method and passed through the MD5
- * hash algorithm.  The resulting value is sent in the authentication response
- * along with the user name if it was provided.
+ * <code>onAuthenticationChallenge()</code> method will be invoked by the OBEX
+ * API implementation. The application will then return the user name (if
+ * needed) and password via a <code>PasswordAuthentication</code> object. The
+ * password in this object is not sent in the authentication response. Instead,
+ * the 16-byte challenge received in the authentication challenge is combined
+ * with the password returned from the <code>onAuthenticationChallenge()</code>
+ * method and passed through the MD5 hash algorithm. The resulting value is sent
+ * in the authentication response along with the user name if it was provided.
  * <P>
  * <STRONG>Authentication Responses</STRONG>
  * <P>
  * When a client or server receives an authentication response header, the
  * <code>onAuthenticationResponse()</code> method is invoked by the API
  * implementation with the user name received in the authentication response
- * header.  (The user name will be <code>null</code> if no user name was
- * provided in the authentication response header.)  The application must
- * determine the correct password.  This value should be returned from the
- * <code>onAuthenticationResponse()</code> method.  If the authentication
- * request should fail without the implementation checking the password,
- * <code>null</code> should
- * be returned by the application.  (This is needed for reasons like not
- * recognizing the user name, etc.)  If the returned value is not
- * <code>null</code>, the OBEX API implementation will combine the password
+ * header. (The user name will be <code>null</code> if no user name was provided
+ * in the authentication response header.) The application must determine the
+ * correct password. This value should be returned from the
+ * <code>onAuthenticationResponse()</code> method. If the authentication request
+ * should fail without the implementation checking the password,
+ * <code>null</code> should be returned by the application. (This is needed for
+ * reasons like not recognizing the user name, etc.) If the returned value is
+ * not <code>null</code>, the OBEX API implementation will combine the password
  * returned from the <code>onAuthenticationResponse()</code> method and
  * challenge sent via the authentication challenge, apply the MD5 hash
  * algorithm, and compare the result to the response hash received in the
- * authentication response header.  If the values are not equal, an
- * <code>IOException</code> will be thrown if the client requested authentication.
- * If the server requested authentication, the
+ * authentication response header. If the values are not equal, an
+ * <code>IOException</code> will be thrown if the client requested
+ * authentication. If the server requested authentication, the
  * <code>onAuthenticationFailure()</code> method will be called on the
- * <code>ServerRequestHandler</code> that failed authentication.  The
- * connection is <B>not</B> closed if authentication failed.
- *
+ * <code>ServerRequestHandler</code> that failed authentication. The connection
+ * is <B>not</B> closed if authentication failed.
  * @hide
  */
 public interface Authenticator {
@@ -90,35 +87,29 @@
      * header. It should respond to the challenge with a
      * <code>PasswordAuthentication</code> that contains the correct user name
      * and password for the challenge.
-     *
-     * @param description the description of which user name and password
-     * should be used; if no description is provided in the authentication
-     * challenge or the description is encoded in an encoding scheme that is
-     * not supported, an empty string will be provided
-     *
+     * @param description the description of which user name and password should
+     *        be used; if no description is provided in the authentication
+     *        challenge or the description is encoded in an encoding scheme that
+     *        is not supported, an empty string will be provided
      * @param isUserIdRequired <code>true</code> if the user ID is required;
-     * <code>false</code> if the user ID is not required
-     *
-     * @param isFullAccess <code>true</code> if full access to the server
-     * will be granted; <code>false</code> if read only access will be
-     * granted
-     *
-     * @return a <code>PasswordAuthentication</code> object containing the
-     * user name and password used for authentication
+     *        <code>false</code> if the user ID is not required
+     * @param isFullAccess <code>true</code> if full access to the server will
+     *        be granted; <code>false</code> if read only access will be granted
+     * @return a <code>PasswordAuthentication</code> object containing the user
+     *         name and password used for authentication
      */
     PasswordAuthentication onAuthenticationChallenge(String description, boolean isUserIdRequired,
             boolean isFullAccess);
 
     /**
      * Called when a client or server receives an authentication response
-     * header.  This method will provide the user name and expect the correct
+     * header. This method will provide the user name and expect the correct
      * password to be returned.
-     *
-     * @param userName the user name provided in the authentication response;
-     * may be <code>null</code>
-     *
+     * @param userName the user name provided in the authentication response; may
+     *        be <code>null</code>
      * @return the correct password for the user name provided; if
-     * <code>null</code> is returned then the authentication request failed
+     *         <code>null</code> is returned then the authentication request
+     *         failed
      */
     byte[] onAuthenticationResponse(byte[] userName);
 }
diff --git a/obex/javax/obex/BaseStream.java b/obex/javax/obex/BaseStream.java
index c32717f..022ad4f 100644
--- a/obex/javax/obex/BaseStream.java
+++ b/obex/javax/obex/BaseStream.java
@@ -37,46 +37,39 @@
 /**
  * This interface defines the methods needed by a parent that uses the
  * PrivateInputStream and PrivateOutputStream objects defined in this package.
- *
  * @hide
  */
 public interface BaseStream {
 
     /**
      * Verifies that this object is still open.
-     *
      * @throws IOException if the object is closed
      */
     void ensureOpen() throws IOException;
 
     /**
-     * Verifies that additional information may be sent.  In other words, the
+     * Verifies that additional information may be sent. In other words, the
      * operation is not done.
-     *
      * @throws IOException if the operation is completed
      */
     void ensureNotDone() throws IOException;
 
     /**
      * Continues the operation since there is no data to read.
-     *
-     * @param sendEmpty <code>true</code> if the operation should send an
-     * empty packet or not send anything if there is no data to send
-     * @param inStream  <code>true</code> if the stream is input stream or
-     * is output stream
+     * @param sendEmpty <code>true</code> if the operation should send an empty
+     *        packet or not send anything if there is no data to send
+     * @param inStream <code>true</code> if the stream is input stream or is
+     *        output stream
      * @return <code>true</code> if the operation was completed;
-     * <code>false</code> if no operation took place
-     *
+     *         <code>false</code> if no operation took place
      * @throws IOException if an IO error occurs
      */
     boolean continueOperation(boolean sendEmpty, boolean inStream) throws IOException;
 
     /**
      * Called when the output or input stream is closed.
-     *
      * @param inStream <code>true</code> if the input stream is closed;
-     * <code>false</code> if the output stream is closed
-     *
+     *        <code>false</code> if the output stream is closed
      * @throws IOException if an IO error occurs
      */
     void streamClosed(boolean inStream) throws IOException;
diff --git a/obex/javax/obex/ClientOperation.java b/obex/javax/obex/ClientOperation.java
index b3807af..65663b1 100644
--- a/obex/javax/obex/ClientOperation.java
+++ b/obex/javax/obex/ClientOperation.java
@@ -40,9 +40,8 @@
 import java.io.ByteArrayOutputStream;
 
 /**
- * This class implements the <code>Operation</code> interface.  It will read
- * and write data via puts and gets.
- *
+ * This class implements the <code>Operation</code> interface. It will read and
+ * write data via puts and gets.
  * @hide
  */
 public final class ClientOperation implements Operation, BaseStream {
@@ -73,15 +72,14 @@
 
     private boolean mEndOfBodySent;
 
-    /** 
+    /**
      * Creates new OperationImpl to read and write data to a server
      * @param maxSize the maximum packet size
      * @param p the parent to this object
      * @param type <code>true</code> if this is a get request;
-     * <code>false</code. if this is a put request
-     * @param headers the headers to set in the initial request
-     *
-     * @throws IOExcpetion if the an IO error occured
+     *        <code>false</code. if this is a put request
+     * @param header the header to set in the initial request
+     * @throws IOException if the an IO error occurred
      */
     public ClientOperation(int maxSize, ClientSession p, HeaderSet header, boolean type)
             throws IOException {
@@ -126,20 +124,14 @@
     }
 
     /**
-     * Sends an ABORT message to the server.  By calling this method, the
+     * Sends an ABORT message to the server. By calling this method, the
      * corresponding input and output streams will be closed along with this
      * object.
-     *
-     * @throws IOException if the transaction has already ended or if an
-     * OBEX server called this method
+     * @throws IOException if the transaction has already ended or if an OBEX
+     *         server called this method
      */
     public synchronized void abort() throws IOException {
         ensureOpen();
-        // need check again .
-        //	if(isDone) {
-        //	     throw new IOException("Operation has already ended");
-        //	}
-
         //no compatible with sun-ri
         if ((mOperationDone) && (mReplyHeader.responseCode != ResponseCodes.OBEX_HTTP_CONTINUE)) {
             throw new IOException("Operation has already ended");
@@ -165,15 +157,14 @@
     }
 
     /**
-     * Retrieves the response code retrieved from the server.  Response codes
-     * are defined in the <code>ResponseCodes</code> interface.
-     *
+     * Retrieves the response code retrieved from the server. Response codes are
+     * defined in the <code>ResponseCodes</code> interface.
      * @return the response code retrieved from the server
-     *
      * @throws IOException if an error occurred in the transport layer during
-     * the transaction; if this method is called on a <code>HeaderSet</code>
-     * object created by calling <code>createHeaderSet</code> in a
-     * <code>ClientSession</code> object
+     *         the transaction; if this method is called on a
+     *         <code>HeaderSet</code> object created by calling
+     *         <code>createHeaderSet</code> in a <code>ClientSession</code>
+     *         object
      */
     public synchronized int getResponseCode() throws IOException {
         //avoid dup validateConnection
@@ -187,7 +178,6 @@
 
     /**
      * This method will always return <code>null</code>
-     *
      * @return <code>null</code>
      */
     public String getEncoding() {
@@ -198,9 +188,8 @@
      * Returns the type of content that the resource connected to is providing.
      * E.g. if the connection is via HTTP, then the value of the content-type
      * header field is returned.
-     *
      * @return the content type of the resource that the URL references, or
-     * <code>null</code> if not known
+     *         <code>null</code> if not known
      */
     public String getType() {
         try {
@@ -212,11 +201,10 @@
 
     /**
      * Returns the length of the content which is being provided. E.g. if the
-     * connection is via HTTP, then the value of the content-length header
-     * field is returned.
-     *
+     * connection is via HTTP, then the value of the content-length header field
+     * is returned.
      * @return the content length of the resource that this connection's URL
-     * references, or -1 if the content length is not known
+     *         references, or -1 if the content length is not known
      */
     public long getLength() {
         try {
@@ -234,9 +222,7 @@
 
     /**
      * Open and return an input stream for a connection.
-     *
      * @return an input stream
-     *
      * @throws IOException if an I/O error occurs
      */
     public InputStream openInputStream() throws IOException {
@@ -259,11 +245,9 @@
         return mPrivateInput;
     }
 
-    /**8
+    /**
      * Open and return a data input stream for a connection.
-     *
      * @return an input stream
-     *
      * @throws IOException if an I/O error occurs
      */
     public DataInputStream openDataInputStream() throws IOException {
@@ -272,9 +256,7 @@
 
     /**
      * Open and return an output stream for a connection.
-     *
      * @return an output stream
-     *
      * @throws IOException if an I/O error occurs
      */
     public OutputStream openOutputStream() throws IOException {
@@ -301,9 +283,7 @@
 
     /**
      * Open and return a data output stream for a connection.
-     *
      * @return an output stream
-     *
      * @throws IOException if an I/O error occurs
      */
     public DataOutputStream openDataOutputStream() throws IOException {
@@ -312,7 +292,6 @@
 
     /**
      * Closes the connection and ends the transaction
-     *
      * @throws IOException if the operation has already ended or is closed
      */
     public void close() throws IOException {
@@ -324,11 +303,9 @@
 
     /**
      * Returns the headers that have been received during the operation.
-     * Modifying the object returned has no effect on the headers that are
-     * sent or retrieved.
-     *
+     * Modifying the object returned has no effect on the headers that are sent
+     * or retrieved.
      * @return the headers received during this <code>Operation</code>
-     *
      * @throws IOException if this <code>Operation</code> has been closed
      */
     public HeaderSet getReceivedHeader() throws IOException {
@@ -340,15 +317,11 @@
     /**
      * Specifies the headers that should be sent in the next OBEX message that
      * is sent.
-     *
      * @param headers the headers to send in the next message
-     *
-     * @throws IOException  if this <code>Operation</code> has been closed
-     * or the transaction has ended and no further messages will be exchanged
-     *
+     * @throws IOException if this <code>Operation</code> has been closed or the
+     *         transaction has ended and no further messages will be exchanged
      * @throws IllegalArgumentException if <code>headers</code> was not created
-     * by a call to <code>ServerRequestHandler.createHeaderSet()</code>
-     *
+     *         by a call to <code>ServerRequestHandler.createHeaderSet()</code>
      * @throws NullPointerException if <code>headers</code> is <code>null</code>
      */
     public void sendHeaders(HeaderSet headers) throws IOException {
@@ -370,62 +343,8 @@
     }
 
     /**
-     * Reads a response from the server.  It will populate the appropriate body
-     * and headers.
-     *
-     * @return <code>true</code> if the transaction should end;
-     * <code>false</code> if the transaction should not end
-     *
-     * @throws IOException if an IO error occurred
-     */
-    /*
-    private boolean readResponse() throws IOException {
-        mReplyHeader.responseCode = mInput.read();
-        int packetLength = mInput.read();
-        packetLength = (packetLength << 8) + mInput.read();
-
-        if (packetLength > ObexHelper.MAX_PACKET_SIZE_INT) {
-            if (mExceptionMessage != null) {
-                abort();
-            }
-            throw new IOException("Received a packet that was too big");
-        }
-
-        if (packetLength > ObexHelper.BASE_PACKET_LENGTH) {
-            int dataLength = packetLength - ObexHelper.BASE_PACKET_LENGTH;
-            byte[] data = new byte[dataLength];
-            int readLength = mInput.read(data);
-            if (readLength != dataLength) {
-                throw new IOException("Received a packet without data as decalred length");
-            }
-            byte[] body = ObexHelper.updateHeaderSet(mReplyHeader, data);
-
-            if (body != null) {
-                mPrivateInput.writeBytes(body, 1);
-
-                /*
-                 * Determine if a body (0x48) header or an end of body (0x49)
-                 * was received.  If we received an end of body and
-                 * a response code of OBEX_HTTP_OK, then the operation should
-                 * end.
-                 *
-                if ((body[0] == 0x49) && (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_OK)) {
-                    return false;
-                }
-            }
-        }
-
-        if (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE) {
-            return true;
-        } else {
-            return false;
-        }
-    }
-    */
-    /**
-     * Verifies that additional information may be sent.  In other words, the
+     * Verifies that additional information may be sent. In other words, the
      * operation is not done.
-     *
      * @throws IOException if the operation is completed
      */
     public void ensureNotDone() throws IOException {
@@ -436,7 +355,6 @@
 
     /**
      * Verifies that the connection is open and no exceptions should be thrown.
-     *
      * @throws IOException if an exception needs to be thrown
      */
     public void ensureOpen() throws IOException {
@@ -452,7 +370,6 @@
 
     /**
      * Verifies that the connection is open and the proper data has been read.
-     *
      * @throws IOException if an IO error occurs
      */
     private void validateConnection() throws IOException {
@@ -466,15 +383,12 @@
 
     /**
      * Sends a request to the client of the specified type
-     *
-     * @param response the response code to send back to the client
-     *
+     * @param opCode the request code to send to the client
      * @return <code>true</code> if there is more data to send;
-     * <code>false</code> if there is no more data to send
-     *
+     *         <code>false</code> if there is no more data to send
      * @throws IOException if an IO error occurs
      */
-    private boolean sendRequest(int type) throws IOException {
+    private boolean sendRequest(int opCode) throws IOException {
         boolean returnValue = false;
         ByteArrayOutputStream out = new ByteArrayOutputStream();
         int bodyLength = -1;
@@ -519,7 +433,7 @@
 
                 byte[] sendHeader = new byte[end - start];
                 System.arraycopy(headerArray, start, sendHeader, 0, sendHeader.length);
-                if (!mParent.sendRequest(type, sendHeader, mReplyHeader, mPrivateInput)) {
+                if (!mParent.sendRequest(opCode, sendHeader, mReplyHeader, mPrivateInput)) {
                     return false;
                 }
 
@@ -559,7 +473,7 @@
              * (End of Body) otherwise, we need to send 0x48 (Body)
              */
             if ((mPrivateOutput.isClosed()) && (!returnValue) && (!mEndOfBodySent)
-                    && ((type & 0x80) != 0)) {
+                    && ((opCode & 0x80) != 0)) {
                 out.write(0x49);
                 mEndOfBodySent = true;
             } else {
@@ -577,7 +491,7 @@
 
         if (mPrivateOutputOpen && bodyLength <= 0 && !mEndOfBodySent) {
             // only 0x82 or 0x83 can send 0x49
-            if ((type & 0x80) == 0) {
+            if ((opCode & 0x80) == 0) {
                 out.write(0x48);
             } else {
                 out.write(0x49);
@@ -591,13 +505,13 @@
         }
 
         if (out.size() == 0) {
-            if (!mParent.sendRequest(type, null, mReplyHeader, mPrivateInput)) {
+            if (!mParent.sendRequest(opCode, null, mReplyHeader, mPrivateInput)) {
                 return false;
             }
             return returnValue;
         }
         if ((out.size() > 0)
-                && (!mParent.sendRequest(type, out.toByteArray(), mReplyHeader, mPrivateInput))) {
+                && (!mParent.sendRequest(opCode, out.toByteArray(), mReplyHeader, mPrivateInput))) {
             return false;
         }
 
@@ -610,10 +524,9 @@
     }
 
     /**
-     * This method starts the processing thread results.  It will send the
-     * initial request.  If the response takes more then one packet, a thread
+     * This method starts the processing thread results. It will send the
+     * initial request. If the response takes more then one packet, a thread
      * will be started to handle additional requests
-     *
      * @throws IOException if an IO error occurs
      */
     private synchronized void startProcessing() throws IOException {
@@ -659,11 +572,10 @@
 
     /**
      * Continues the operation since there is no data to read.
-     *
-     * @param sendEmpty <code>true</code> if the operation should send an
-     * empty packet or not send anything if there is no data to send
-     * @param inStream  <code>true</code> if the stream is input stream or
-     * is output stream
+     * @param sendEmpty <code>true</code> if the operation should send an empty
+     *        packet or not send anything if there is no data to send
+     * @param inStream <code>true</code> if the stream is input stream or is
+     *        output stream
      * @throws IOException if an IO error occurs
      */
     public synchronized boolean continueOperation(boolean sendEmpty, boolean inStream)
@@ -717,10 +629,8 @@
 
     /**
      * Called when the output or input stream is closed.
-     *
      * @param inStream <code>true</code> if the input stream is closed;
-     * <code>false</code> if the output stream is closed
-     *
+     *        <code>false</code> if the output stream is closed
      * @throws IOException if an IO error occurs
      */
     public void streamClosed(boolean inStream) throws IOException {
@@ -804,7 +714,6 @@
                 if (mReplyHeader.responseCode != ResponseCodes.OBEX_HTTP_CONTINUE) {
                     mOperationDone = true;
                 }
-
             }
         }
     }
diff --git a/obex/javax/obex/ClientSession.java b/obex/javax/obex/ClientSession.java
index d554922..0935383 100644
--- a/obex/javax/obex/ClientSession.java
+++ b/obex/javax/obex/ClientSession.java
@@ -39,7 +39,6 @@
 
 /**
  * This class in an implementation of the OBEX ClientSession.
- *
  * @hide
  */
 public final class ClientSession extends ObexSession {
@@ -163,7 +162,7 @@
     }
 
     /**
-     *  0xCB Connection Id an identifier used for OBEX connection multiplexing
+     * 0xCB Connection Id an identifier used for OBEX connection multiplexing
      */
     public void setConnectionID(long id) {
         if ((id < 0) || (id > 0xFFFFFFFFL)) {
@@ -365,7 +364,6 @@
 
     /**
      * Verifies that the connection is open.
-     *
      * @throws IOException if the connection is closed
      */
     public synchronized void ensureOpen() throws IOException {
@@ -375,9 +373,8 @@
     }
 
     /**
-     * Set request inactive.
-     * Allows Put and get operation objects to tell this object when they are
-     * done.
+     * Set request inactive. Allows Put and get operation objects to tell this
+     * object when they are done.
      */
     /*package*/synchronized void setRequestInactive() {
         mRequestActive = false;
@@ -395,27 +392,17 @@
     }
 
     /**
-     * Sends a standard request to the client.  It will then wait for the reply
-     * and update the header set object provided.  If any authentication
-     * headers (i.e. authentication challenge or authentication response) are
-     * received, they will be processed.
-     *
+     * Sends a standard request to the client. It will then wait for the reply
+     * and update the header set object provided. If any authentication headers
+     * (i.e. authentication challenge or authentication response) are received,
+     * they will be processed.
      * @param opCode the type of request to send to the client
-     *
-     * @param head the headers to send to the server
-     *
-     * @param challenge the nonce that was sent in the authentication
-     * challenge header located in <code>head</code>; <code>null</code>
-     * if no authentication header is included in <code>head</code>
-     *
+     * @param head the headers to send to the client
      * @param header the header object to update with the response
-     *
-     * @param input the input stream used by the Operation object; null if this
-     * is called on a CONNECT, SETPATH or DISCONNECT
-     *
-     * return <code>true</code> if the operation completed successfully;
-     * <code>false</code> if an authentication response failed to pass
-     *
+     * @param privateInput the input stream used by the Operation object; null
+     *        if this is called on a CONNECT, SETPATH or DISCONNECT return
+     *        <code>true</code> if the operation completed successfully;
+     *        <code>false</code> if an authentication response failed to pass
      * @throws IOException if an IO error occurs
      */
     public boolean sendRequest(int opCode, byte[] head, HeaderSet header,
diff --git a/obex/javax/obex/HeaderSet.java b/obex/javax/obex/HeaderSet.java
index f777da6..8b457f6 100644
--- a/obex/javax/obex/HeaderSet.java
+++ b/obex/javax/obex/HeaderSet.java
@@ -40,28 +40,27 @@
 /**
  * This class implements the javax.obex.HeaderSet interface for OBEX over
  * RFCOMM.
- *
  * @hide
  */
 public final class HeaderSet {
 
     /**
-     * Represents the OBEX Count header.  This allows the connection statement
-     * to tell the server how many objects it plans to send or retrieve.
+     * Represents the OBEX Count header. This allows the connection statement to
+     * tell the server how many objects it plans to send or retrieve.
      * <P>
      * The value of <code>COUNT</code> is 0xC0 (192).
      */
     public static final int COUNT = 0xC0;
 
     /**
-     * Represents the OBEX Name header.  This specifies the name of the object.
+     * Represents the OBEX Name header. This specifies the name of the object.
      * <P>
      * The value of <code>NAME</code> is 0x01 (1).
      */
     public static final int NAME = 0x01;
 
     /**
-     * Represents the OBEX Type header.  This allows a request to specify the
+     * Represents the OBEX Type header. This allows a request to specify the
      * type of the object (e.g. text, html, binary, etc.).
      * <P>
      * The value of <code>TYPE</code> is 0x42 (66).
@@ -69,7 +68,7 @@
     public static final int TYPE = 0x42;
 
     /**
-     * Represents the OBEX Length header.  This is the length of the object in
+     * Represents the OBEX Length header. This is the length of the object in
      * bytes.
      * <P>
      * The value of <code>LENGTH</code> is 0xC3 (195).
@@ -77,32 +76,32 @@
     public static final int LENGTH = 0xC3;
 
     /**
-     * Represents the OBEX Time header using the ISO 8601 standards.  This is
-     * the preferred time header.
+     * Represents the OBEX Time header using the ISO 8601 standards. This is the
+     * preferred time header.
      * <P>
      * The value of <code>TIME_ISO_8601</code> is 0x44 (68).
      */
     public static final int TIME_ISO_8601 = 0x44;
 
     /**
-     * Represents the OBEX Time header using the 4 byte representation.  This
-     * is only included for backwards compatibility.  It represents the number
-     * of seconds since January 1, 1970.
+     * Represents the OBEX Time header using the 4 byte representation. This is
+     * only included for backwards compatibility. It represents the number of
+     * seconds since January 1, 1970.
      * <P>
      * The value of <code>TIME_4_BYTE</code> is 0xC4 (196).
      */
     public static final int TIME_4_BYTE = 0xC4;
 
     /**
-     * Represents the OBEX Description header.  This is a text description of
-     * the object.
+     * Represents the OBEX Description header. This is a text description of the
+     * object.
      * <P>
      * The value of <code>DESCRIPTION</code> is 0x05 (5).
      */
     public static final int DESCRIPTION = 0x05;
 
     /**
-     * Represents the OBEX Target header.  This is the name of the service an
+     * Represents the OBEX Target header. This is the name of the service an
      * operation is targeted to.
      * <P>
      * The value of <code>TARGET</code> is 0x46 (70).
@@ -110,7 +109,7 @@
     public static final int TARGET = 0x46;
 
     /**
-     * Represents the OBEX HTTP header.  This allows an HTTP 1.X header to be
+     * Represents the OBEX HTTP header. This allows an HTTP 1.X header to be
      * included in a request or reply.
      * <P>
      * The value of <code>HTTP</code> is 0x47 (71).
@@ -132,7 +131,7 @@
     public static final int END_OF_BODY = 0x49;
 
     /**
-     * Represents the OBEX Who header.  Identifies the OBEX application to
+     * Represents the OBEX Who header. Identifies the OBEX application to
      * determine if the two peers are talking to each other.
      * <P>
      * The value of <code>WHO</code> is 0x4A (74).
@@ -149,7 +148,7 @@
     public static final int CONNECTION_ID = 0xCB;
 
     /**
-     * Represents the OBEX Application Parameter header.  This header specifies
+     * Represents the OBEX Application Parameter header. This header specifies
      * additional application request and response information.
      * <P>
      * The value of <code>APPLICATION_PARAMETER</code> is 0x4C (76).
@@ -171,8 +170,8 @@
     public static final int AUTH_RESPONSE = 0x4E;
 
     /**
-     * Represents the OBEX Object Class header.  This header specifies the
-     * OBEX object class of the object.
+     * Represents the OBEX Object Class header. This header specifies the OBEX
+     * object class of the object.
      * <P>
      * The value of <code>OBJECT_CLASS</code> is 0x4F (79).
      */
@@ -200,12 +199,6 @@
 
     private byte[] mAppParam; // byte sequence of the form tag length value
 
-    public byte[] mAuthChall; // The authentication challenge header
-
-    public byte[] mAuthResp; // The authentication response header
-
-    public byte[] mConnectionID; // THe connection ID
-
     private byte[] mObjectClass; // byte sequence
 
     private String[] mUnicodeUserDefined; //null terminated unicode string
@@ -216,15 +209,20 @@
 
     private Long[] mIntegerUserDefined; // 4 byte unsigned integer
 
-    /*package*/int responseCode;
-
-    /*package*/byte[] nonce;
-
     private final Random mRandom;
 
+    /*package*/ byte[] nonce;
+
+    public byte[] mAuthChall; // The authentication challenge header
+
+    public byte[] mAuthResp; // The authentication response header
+
+    public byte[] mConnectionID; // THe connection ID
+
+    public int responseCode;
+
     /**
      * Creates new <code>HeaderSet</code> object.
-     *
      * @param size the max packet size for this connection
      */
     public HeaderSet() {
@@ -237,20 +235,17 @@
     }
 
     /**
-     * Sets the value of the header identifier to the value provided.  The type
+     * Sets the value of the header identifier to the value provided. The type
      * of object must correspond to the Java type defined in the description of
-     * this interface.  If <code>null</code> is passed as the
+     * this interface. If <code>null</code> is passed as the
      * <code>headerValue</code> then the header will be removed from the set of
      * headers to include in the next request.
-     *
      * @param headerID the identifier to include in the message
-     *
      * @param headerValue the value of the header identifier
-     *
-     * @throws IllegalArgumentException if the header identifier provided is
-     * not one defined in this interface or a user-defined header; if the type of
-     * <code>headerValue</code> is not the correct Java type as defined in the
-     * description of this interface\
+     * @throws IllegalArgumentException if the header identifier provided is not
+     *         one defined in this interface or a user-defined header; if the
+     *         type of <code>headerValue</code> is not the correct Java type as
+     *         defined in the description of this interface\
      */
     public void setHeader(int headerID, Object headerValue) {
         long temp = -1;
@@ -435,20 +430,16 @@
     }
 
     /**
-     * Retrieves the value of the header identifier provided.  The type of the
+     * Retrieves the value of the header identifier provided. The type of the
      * Object returned is defined in the description of this interface.
-     *
      * @param headerID the header identifier whose value is to be returned
-     *
      * @return the value of the header provided or <code>null</code> if the
-     * header identifier specified is not part of this <code>HeaderSet</code>
-     * object
-     *
-     * @throws IllegalArgumentException if the <code>headerID</code> is not
-     * one defined in this interface or any of the user-defined headers
-     *
+     *         header identifier specified is not part of this
+     *         <code>HeaderSet</code> object
+     * @throws IllegalArgumentException if the <code>headerID</code> is not one
+     *         defined in this interface or any of the user-defined headers
      * @throws IOException if an error occurred in the transport layer during
-     * the operation or if the connection has been closed
+     *         the operation or if the connection has been closed
      */
     public Object getHeader(int headerID) throws IOException {
 
@@ -500,17 +491,14 @@
 
     /**
      * Retrieves the list of headers that may be retrieved via the
-     * <code>getHeader</code> method that will not return <code>null</code>.
-     * In other words, this method returns all the headers that are available
-     * in this object.
-     *
+     * <code>getHeader</code> method that will not return <code>null</code>. In
+     * other words, this method returns all the headers that are available in
+     * this object.
      * @see #getHeader
-     *
      * @return the array of headers that are set in this object or
-     * <code>null</code> if no headers are available
-     *
+     *         <code>null</code> if no headers are available
      * @throws IOException if an error occurred in the transport layer during
-     * the operation or the connection has been closed
+     *         the operation or the connection has been closed
      */
     public int[] getHeaderList() throws IOException {
         ByteArrayOutputStream out = new ByteArrayOutputStream();
@@ -594,51 +582,41 @@
     }
 
     /**
-     * Sets the authentication challenge header.  The <code>realm</code> will
-     * be encoded based upon the default encoding scheme used by the
-     * implementation to encode strings.  Therefore, the encoding scheme used
-     * to encode the <code>realm</code> is application dependent.
-     *
+     * Sets the authentication challenge header. The <code>realm</code> will be
+     * encoded based upon the default encoding scheme used by the implementation
+     * to encode strings. Therefore, the encoding scheme used to encode the
+     * <code>realm</code> is application dependent.
      * @param realm a short description that describes what password to use; if
-     * <code>null</code> no realm will be sent in the authentication challenge
-     * header
-     *
+     *        <code>null</code> no realm will be sent in the authentication
+     *        challenge header
      * @param userID if <code>true</code>, a user ID is required in the reply;
-     * if <code>false</code>, no user ID is required
-     *
+     *        if <code>false</code>, no user ID is required
      * @param access if <code>true</code> then full access will be granted if
-     * successful; if <code>false</code> then read-only access will be granted
-     * if successful
+     *        successful; if <code>false</code> then read-only access will be
+     *        granted if successful
      * @throws IOException
      */
     public void createAuthenticationChallenge(String realm, boolean userID, boolean access)
             throws IOException {
 
-        try {
-            nonce = new byte[16];
-            for (int i = 0; i < 16; i++) {
-                nonce[i] = (byte)mRandom.nextInt();
-            }
-
-            mAuthChall = ObexHelper.computeAuthenticationChallenge(nonce, realm, access, userID);
-        } catch (IOException e) {
-            throw e;
+        nonce = new byte[16];
+        for (int i = 0; i < 16; i++) {
+            nonce[i] = (byte)mRandom.nextInt();
         }
+
+        mAuthChall = ObexHelper.computeAuthenticationChallenge(nonce, realm, access, userID);
     }
 
     /**
-     * Returns the response code received from the server.  Response codes
-     * are defined in the <code>ResponseCodes</code> class.
-     *
+     * Returns the response code received from the server. Response codes are
+     * defined in the <code>ResponseCodes</code> class.
      * @see ResponseCodes
-     *
      * @return the response code retrieved from the server
-     *
      * @throws IOException if an error occurred in the transport layer during
-     * the transaction; if this method is called on a <code>HeaderSet</code>
-     * object created by calling <code>createHeaderSet()</code> in a
-     * <code>ClientSession</code> object; if this object was created by an OBEX
-     * server
+     *         the transaction; if this method is called on a
+     *         <code>HeaderSet</code> object created by calling
+     *         <code>createHeaderSet()</code> in a <code>ClientSession</code>
+     *         object; if this object was created by an OBEX server
      */
     public int getResponseCode() throws IOException {
         if (responseCode == -1) {
diff --git a/obex/javax/obex/ObexHelper.java b/obex/javax/obex/ObexHelper.java
index 511b7c6..f569595 100644
--- a/obex/javax/obex/ObexHelper.java
+++ b/obex/javax/obex/ObexHelper.java
@@ -43,16 +43,14 @@
 
 /**
  * This class defines a set of helper methods for the implementation of Obex.
- *
  * @hide
  */
 public final class ObexHelper {
 
     /**
-     * Defines the basic packet length used by OBEX.  Every OBEX packet has the
+     * Defines the basic packet length used by OBEX. Every OBEX packet has the
      * same basic format:<BR>
-     * Byte 0: Request or Response Code
-     * Byte 1&2: Length of the packet.
+     * Byte 0: Request or Response Code Byte 1&2: Length of the packet.
      */
     public static final int BASE_PACKET_LENGTH = 3;
 
@@ -61,17 +59,14 @@
     }
 
     /**
-     * The maximum packet size for OBEX packets that this client can handle.
-     * At present, this must be changed for each port.
-     *
-     * TODO: The max packet size should be the Max incoming MTU minus
-     * TODO: L2CAP package headers and RFCOMM package headers.
-     *
-     * TODO: Retrieve the max incoming MTU from
-     * TODO: LocalDevice.getProperty().
+     * The maximum packet size for OBEX packets that this client can handle. At
+     * present, this must be changed for each port. TODO: The max packet size
+     * should be the Max incoming MTU minus TODO: L2CAP package headers and
+     * RFCOMM package headers. TODO: Retrieve the max incoming MTU from TODO:
+     * LocalDevice.getProperty().
      */
-    /** android note
-     *  set as 0xFFFE to match remote MPS
+    /*
+     * android note set as 0xFFFE to match remote MPS
      */
     public static final int MAX_PACKET_SIZE_INT = 0xFFFE;
 
@@ -119,34 +114,46 @@
 
     /**
      * Updates the HeaderSet with the headers received in the byte array
-     * provided.  Invalid headers are ignored.
+     * provided. Invalid headers are ignored.
      * <P>
-     * The first two bits of an OBEX Header specifies the type of object that
-     * is being sent.  The table below specifies the meaning of the high
-     * bits.
+     * The first two bits of an OBEX Header specifies the type of object that is
+     * being sent. The table below specifies the meaning of the high bits.
      * <TABLE>
-     * <TR><TH>Bits 8 and 7</TH><TH>Value</TH><TH>Description</TH></TR>
-     * <TR><TD>00</TD><TD>0x00</TD><TD>Null Terminated Unicode text, prefixed
-     * with 2 byte unsigned integer</TD></TR>
-     * <TR><TD>01</TD><TD>0x40</TD><TD>Byte Sequence, length prefixed with
-     * 2 byte unsigned integer</TD></TR>
-     * <TR><TD>10</TD><TD>0x80</TD><TD>1 byte quantity</TD></TR>
-     * <TR><TD>11</TD><TD>0xC0</TD><TD>4 byte quantity - transmitted in
-     * network byte order (high byte first</TD></TR>
+     * <TR>
+     * <TH>Bits 8 and 7</TH>
+     * <TH>Value</TH>
+     * <TH>Description</TH>
+     * </TR>
+     * <TR>
+     * <TD>00</TD>
+     * <TD>0x00</TD>
+     * <TD>Null Terminated Unicode text, prefixed with 2 byte unsigned integer</TD>
+     * </TR>
+     * <TR>
+     * <TD>01</TD>
+     * <TD>0x40</TD>
+     * <TD>Byte Sequence, length prefixed with 2 byte unsigned integer</TD>
+     * </TR>
+     * <TR>
+     * <TD>10</TD>
+     * <TD>0x80</TD>
+     * <TD>1 byte quantity</TD>
+     * </TR>
+     * <TR>
+     * <TD>11</TD>
+     * <TD>0xC0</TD>
+     * <TD>4 byte quantity - transmitted in network byte order (high byte first</TD>
+     * </TR>
      * </TABLE>
      * This method uses the information in this table to determine the type of
-     * Java object to create and passes that object with the full header
-     * to setHeader() to update the HeaderSet object.  Invalid headers will
-     * cause an exception to be thrown.  When it is thrown, it is ignored.
-     *
+     * Java object to create and passes that object with the full header to
+     * setHeader() to update the HeaderSet object. Invalid headers will cause an
+     * exception to be thrown. When it is thrown, it is ignored.
      * @param header the HeaderSet to update
-     *
      * @param headerArray the byte array containing headers
-     *
      * @return the result of the last start body or end body header provided;
-     * the first byte in the result will specify if a body or end of body is
-     * received
-     *
+     *         the first byte in the result will specify if a body or end of
+     *         body is received
      * @throws IOException if an invalid header was found
      */
     public static byte[] updateHeaderSet(HeaderSet header, byte[] headerArray) throws IOException {
@@ -316,18 +323,13 @@
 
     /**
      * Creates the header part of OBEX packet based on the header provided.
-     *
-     * TODO: Could use getHeaderList() to get the array of headers to
-     * TODO: include and then use the high two bits to determine the
-     * TODO: the type of the object and construct the byte array from
-     * TODO: that.  This will make the size smaller.
-     *
+     * TODO: Could use getHeaderList() to get the array of headers to include
+     * and then use the high two bits to determine the the type of the object
+     * and construct the byte array from that. This will make the size smaller.
      * @param head the header used to construct the byte array
-     *
      * @param nullOut <code>true</code> if the header should be set to
-     * <code>null</code> once it is added to the array or <code>false</code>
-     * if it should not be nulled out
-     *
+     *        <code>null</code> once it is added to the array or
+     *        <code>false</code> if it should not be nulled out
      * @return the header of an OBEX packet
      */
     public static byte[] createHeader(HeaderSet head, boolean nullOut) {
@@ -342,9 +344,6 @@
         int length;
         HeaderSet headImpl = null;
         ByteArrayOutputStream out = new ByteArrayOutputStream();
-        if (!(head instanceof HeaderSet)) {
-            throw new IllegalArgumentException("Header not created by createHeaderSet");
-        }
         headImpl = head;
 
         try {
@@ -675,18 +674,14 @@
     }
 
     /**
-     * Determines where the maximum divide is between headers.  This method is
+     * Determines where the maximum divide is between headers. This method is
      * used by put and get operations to separate headers to a size that meets
      * the max packet size allowed.
-     *
      * @param headerArray the headers to separate
-     *
      * @param start the starting index to search
-     *
      * @param maxSize the maximum size of a packet
-     *
      * @return the index of the end of the header block to send or -1 if the
-     * header could not be divided because the header is too large
+     *         header could not be divided because the header is too large
      */
     public static int findHeaderEnd(byte[] headerArray, int start, int maxSize) {
 
@@ -757,9 +752,7 @@
 
     /**
      * Converts the byte array to a long.
-     *
      * @param b the byte array to convert to a long
-     *
      * @return the byte array as a long
      */
     public static long convertToLong(byte[] b) {
@@ -781,10 +774,8 @@
     }
 
     /**
-     * Converts the long to a 4 byte array.  The long must be non negative.
-     *
+     * Converts the long to a 4 byte array. The long must be non negative.
      * @param l the long to convert
-     *
      * @return a byte array that is the same as the long
      */
     public static byte[] convertToByteArray(long l) {
@@ -799,11 +790,9 @@
     }
 
     /**
-     * Converts the String to a UNICODE byte array.  It will also add the ending
+     * Converts the String to a UNICODE byte array. It will also add the ending
      * null characters to the end of the string.
-     *
      * @param s the string to convert
-     *
      * @return the unicode byte array of the string
      */
     public static byte[] convertToUnicodeByteArray(String s) {
@@ -826,13 +815,10 @@
     }
 
     /**
-     * Retrieves the value from the byte array for the tag value specified.  The
+     * Retrieves the value from the byte array for the tag value specified. The
      * array should be of the form Tag - Length - Value triplet.
-     *
      * @param tag the tag to retrieve from the byte array
-     *
      * @param triplet the byte sequence containing the tag length value form
-     *
      * @return the value of the specified tag
      */
     public static byte[] getTagValue(byte tag, byte[] triplet) {
@@ -854,11 +840,8 @@
 
     /**
      * Finds the index that starts the tag value pair in the byte array provide.
-     *
      * @param tag the tag to look for
-     *
      * @param value the byte array to search
-     *
      * @return the starting index of the tag or -1 if the tag could not be found
      */
     public static int findTag(byte tag, byte[] value) {
@@ -884,19 +867,15 @@
 
     /**
      * Converts the byte array provided to a unicode string.
-     *
      * @param b the byte array to convert to a string
-     *
      * @param includesNull determine if the byte string provided contains the
-     * UNICODE null character at the end or not;  if it does, it will be
-     * removed
-     *
+     *        UNICODE null character at the end or not; if it does, it will be
+     *        removed
      * @return a Unicode string
-     *
-     * @param IllegalArgumentException if the byte array has an odd length
+     * @throws IllegalArgumentException if the byte array has an odd length
      */
     public static String convertToUnicode(byte[] b, boolean includesNull) {
-        if (b == null) {
+        if (b == null || b.length == 0) {
             return null;
         }
         int arrayLength = b.length;
@@ -926,9 +905,8 @@
     }
 
     /**
-     * Compute the MD5 hash of the byte array provided.
-     * Does not accumulate input.
-     *
+     * Compute the MD5 hash of the byte array provided. Does not accumulate
+     * input.
      * @param in the byte array to hash
      * @return the MD5 hash of the byte array
      */
@@ -939,23 +917,16 @@
 
     /**
      * Computes an authentication challenge header.
-     *
-     *
-     * @param nonce the challenge that will be provided to the peer;  the
-     * challenge must be 16 bytes long
-     *
+     * @param nonce the challenge that will be provided to the peer; the
+     *        challenge must be 16 bytes long
      * @param realm a short description that describes what password to use
-     *
      * @param access if <code>true</code> then full access will be granted if
-     * successful; if <code>false</code> then read only access will be granted
-     * if successful
-     *
+     *        successful; if <code>false</code> then read only access will be
+     *        granted if successful
      * @param userID if <code>true</code>, a user ID is required in the reply;
-     * if <code>false</code>, no user ID is required
-     *
-     * @throws IllegalArgumentException if the challenge is not 16 bytes
-     * long; if the realm can not be encoded in less then 255 bytes
-     *
+     *        if <code>false</code>, no user ID is required
+     * @throws IllegalArgumentException if the challenge is not 16 bytes long;
+     *         if the realm can not be encoded in less then 255 bytes
      * @throws IOException if the encoding scheme ISO 8859-1 is not supported
      */
     public static byte[] computeAuthenticationChallenge(byte[] nonce, String realm, boolean access,
diff --git a/obex/javax/obex/ObexSession.java b/obex/javax/obex/ObexSession.java
index 97d65e0..a7daeb5 100644
--- a/obex/javax/obex/ObexSession.java
+++ b/obex/javax/obex/ObexSession.java
@@ -41,10 +41,8 @@
  * of the same connection, which is established by server's accepting of a
  * client issued "CONNECT".
  * <P>
- * 
  * This interface serves as the common super class for
  * <CODE>ClientSession</CODE> and <CODE>ServerSession</CODE>.
- * 
  * @hide
  */
 public class ObexSession {
@@ -56,10 +54,7 @@
     /**
      * Called when the server received an authentication challenge header. This
      * will cause the authenticator to handle the authentication challenge.
-     *
-     * @param header
-     *            the header with the authentication challenge
-     *
+     * @param header the header with the authentication challenge
      * @return <code>true</code> if the last request should be resent;
      *         <code>false</code> if the last request should not be resent
      * @throws IOException
@@ -188,10 +183,7 @@
     /**
      * Called when the server received an authentication response header. This
      * will cause the authenticator to handle the authentication response.
-     *
-     * @param authResp
-     *            the authentication response
-     *
+     * @param authResp the authentication response
      * @return <code>true</code> if the response passed; <code>false</code> if
      *         the response failed
      */
diff --git a/obex/javax/obex/ObexTransport.java b/obex/javax/obex/ObexTransport.java
index d0ba0c9..445e267 100644
--- a/obex/javax/obex/ObexTransport.java
+++ b/obex/javax/obex/ObexTransport.java
@@ -51,7 +51,6 @@
  * Different kind of medium may have different construction - for example, the
  * RFCOMM device file medium may be constructed from a file descriptor or simply
  * a string while the TCP medium usually from a socket.
- * 
  * @hide
  */
 public interface ObexTransport {
diff --git a/obex/javax/obex/Operation.java b/obex/javax/obex/Operation.java
index f265f53..20653f2 100644
--- a/obex/javax/obex/Operation.java
+++ b/obex/javax/obex/Operation.java
@@ -40,44 +40,39 @@
 
 /**
  * The <code>Operation</code> interface provides ways to manipulate a single
- * OBEX PUT or GET operation.  The implementation of this interface sends
- * OBEX packets as they are built.  If during the operation the peer in the
- * operation ends the operation, an <code>IOException</code> is thrown on
- * the next read from the input stream, write to the output stream, or call to
+ * OBEX PUT or GET operation. The implementation of this interface sends OBEX
+ * packets as they are built. If during the operation the peer in the operation
+ * ends the operation, an <code>IOException</code> is thrown on the next read
+ * from the input stream, write to the output stream, or call to
  * <code>sendHeaders()</code>.
  * <P>
- * <STRONG>Definition of methods inherited from <code>ContentConnection</code></STRONG>
+ * <STRONG>Definition of methods inherited from <code>ContentConnection</code>
+ * </STRONG>
  * <P>
- * <code>getEncoding()</code> will always return <code>null</code>.
- * <BR><code>getLength()</code> will return the length specified by the OBEX Length
- * header or -1 if the OBEX Length header was not included.
- * <BR><code>getType()</code> will return the value specified in the OBEX Type
+ * <code>getEncoding()</code> will always return <code>null</code>. <BR>
+ * <code>getLength()</code> will return the length specified by the OBEX Length
+ * header or -1 if the OBEX Length header was not included. <BR>
+ * <code>getType()</code> will return the value specified in the OBEX Type
  * header or <code>null</code> if the OBEX Type header was not included.<BR>
  * <P>
  * <STRONG>How Headers are Handled</STRONG>
  * <P>
  * As headers are received, they may be retrieved through the
- * <code>getReceivedHeaders()</code> method.  If new headers are set during the
+ * <code>getReceivedHeaders()</code> method. If new headers are set during the
  * operation, the new headers will be sent during the next packet exchange.
  * <P>
  * <STRONG>PUT example</STRONG>
  * <P>
  * <PRE>
- * void putObjectViaOBEX(ClientSession conn, HeaderSet head, byte[] obj)
- *     throws IOException {
- *
+ * void putObjectViaOBEX(ClientSession conn, HeaderSet head, byte[] obj) throws IOException {
  *     // Include the length header
  *     head.setHeader(head.LENGTH, new Long(obj.length));
- *
  *     // Initiate the PUT request
  *     Operation op = conn.put(head);
- *
  *     // Open the output stream to put the object to it
  *     DataOutputStream out = op.openDataOutputStream();
- *
  *     // Send the object to the server
  *     out.write(obj);
- *
  *     // End the transaction
  *     out.close();
  *     op.close();
@@ -88,64 +83,55 @@
  * <P>
  * <PRE>
  * byte[] getObjectViaOBEX(ClientSession conn, HeaderSet head) throws IOException {
- *
  *     // Send the initial GET request to the server
  *     Operation op = conn.get(head);
- *
  *     // Retrieve the length of the object being sent back
  *     int length = op.getLength();
- *
- *      // Create space for the object
- *      byte[] obj = new byte[length];
- *
+ *     // Create space for the object
+ *     byte[] obj = new byte[length];
  *     // Get the object from the input stream
  *     DataInputStream in = trans.openDataInputStream();
  *     in.read(obj);
- *
  *     // End the transaction
  *     in.close();
  *     op.close();
- *
  *     return obj;
  * }
  * </PRE>
- * <H3>Client PUT Operation Flow</H3>
- * For PUT operations, a call to <code>close()</code> the <code>OutputStream</code>
- * returned from <code>openOutputStream()</code> or <code>openDataOutputStream()</code>
- * will signal that the request is done.  (In OBEX terms, the End-Of-Body header should
- * be sent and the final bit in the request will be set.)  At this point, the
- * reply from the server may begin to be processed.  A call to
+ *
+ * <H3>Client PUT Operation Flow</H3> For PUT operations, a call to
+ * <code>close()</code> the <code>OutputStream</code> returned from
+ * <code>openOutputStream()</code> or <code>openDataOutputStream()</code> will
+ * signal that the request is done. (In OBEX terms, the End-Of-Body header
+ * should be sent and the final bit in the request will be set.) At this point,
+ * the reply from the server may begin to be processed. A call to
  * <code>getResponseCode()</code> will do an implicit close on the
  * <code>OutputStream</code> and therefore signal that the request is done.
- * <H3>Client GET Operation Flow</H3>
- * For GET operation, a call to <code>openInputStream()</code> or
- * <code>openDataInputStream()</code> will signal that the request is done.  (In OBEX
- * terms, the final bit in the request will be set.)  A call to
- * <code>getResponseCode()</code> will cause an implicit close on the
- * <code>InputStream</code>.  No further data may be read at this point.
- *
+ * <H3>Client GET Operation Flow</H3> For GET operation, a call to
+ * <code>openInputStream()</code> or <code>openDataInputStream()</code> will
+ * signal that the request is done. (In OBEX terms, the final bit in the request
+ * will be set.) A call to <code>getResponseCode()</code> will cause an implicit
+ * close on the <code>InputStream</code>. No further data may be read at this
+ * point.
  * @hide
  */
 public interface Operation {
 
     /**
-     * Sends an ABORT message to the server.  By calling this method, the
+     * Sends an ABORT message to the server. By calling this method, the
      * corresponding input and output streams will be closed along with this
-     * object.  No headers are sent in the abort request.  This will end the
+     * object. No headers are sent in the abort request. This will end the
      * operation since <code>close()</code> will be called by this method.
-     *
-     * @throws IOException if the transaction has already ended or if an
-     * OBEX server calls this method
+     * @throws IOException if the transaction has already ended or if an OBEX
+     *         server calls this method
      */
     void abort() throws IOException;
 
     /**
      * Returns the headers that have been received during the operation.
-     * Modifying the object returned has no effect on the headers that are
-     * sent or retrieved.
-     *
+     * Modifying the object returned has no effect on the headers that are sent
+     * or retrieved.
      * @return the headers received during this <code>Operation</code>
-     *
      * @throws IOException if this <code>Operation</code> has been closed
      */
     HeaderSet getReceivedHeader() throws IOException;
@@ -153,30 +139,23 @@
     /**
      * Specifies the headers that should be sent in the next OBEX message that
      * is sent.
-     *
      * @param headers the headers to send in the next message
-     *
-     * @throws IOException  if this <code>Operation</code> has been closed
-     * or the transaction has ended and no further messages will be exchanged
-     *
+     * @throws IOException if this <code>Operation</code> has been closed or the
+     *         transaction has ended and no further messages will be exchanged
      * @throws IllegalArgumentException if <code>headers</code> was not created
-     * by a call to <code>ServerRequestHandler.createHeaderSet()</code> or
-     * <code>ClientSession.createHeaderSet()</code>
-     *
+     *         by a call to <code>ServerRequestHandler.createHeaderSet()</code>
+     *         or <code>ClientSession.createHeaderSet()</code>
      * @throws NullPointerException if <code>headers</code> if <code>null</code>
      */
     void sendHeaders(HeaderSet headers) throws IOException;
 
     /**
-     * Returns the response code received from the server.  Response codes
-     * are defined in the <code>ResponseCodes</code> class.
-     *
+     * Returns the response code received from the server. Response codes are
+     * defined in the <code>ResponseCodes</code> class.
      * @see ResponseCodes
-     *
      * @return the response code retrieved from the server
-     *
      * @throws IOException if an error occurred in the transport layer during
-     * the transaction; if this object was created by an OBEX server
+     *         the transaction; if this object was created by an OBEX server
      */
     int getResponseCode() throws IOException;
 
diff --git a/obex/javax/obex/PasswordAuthentication.java b/obex/javax/obex/PasswordAuthentication.java
index e81a861..326b1ff 100644
--- a/obex/javax/obex/PasswordAuthentication.java
+++ b/obex/javax/obex/PasswordAuthentication.java
@@ -34,7 +34,6 @@
 
 /**
  * This class holds user name and password combinations.
- *
  * @hide
  */
 public final class PasswordAuthentication {
@@ -44,15 +43,12 @@
     private final byte[] mPassword;
 
     /**
-     * Creates a new <code>PasswordAuthentication</code> with the user name
-     * and password provided.
-     *
+     * Creates a new <code>PasswordAuthentication</code> with the user name and
+     * password provided.
      * @param userName the user name to include; this may be <code>null</code>
-     *
      * @param password the password to include in the response
-     *
      * @throws NullPointerException if <code>password</code> is
-     * <code>null</code>
+     *         <code>null</code>
      */
     public PasswordAuthentication(final byte[] userName, final byte[] password) {
         if (userName != null) {
@@ -65,9 +61,8 @@
     }
 
     /**
-     * Retrieves the user name that was specified in the constructor.
-     * The user name may be <code>null</code>.
-     *
+     * Retrieves the user name that was specified in the constructor. The user
+     * name may be <code>null</code>.
      * @return the user name
      */
     public byte[] getUserName() {
@@ -76,7 +71,6 @@
 
     /**
      * Retrieves the password.
-     *
      * @return the password
      */
     public byte[] getPassword() {
diff --git a/obex/javax/obex/PrivateInputStream.java b/obex/javax/obex/PrivateInputStream.java
index 2dc02da..5daee72 100644
--- a/obex/javax/obex/PrivateInputStream.java
+++ b/obex/javax/obex/PrivateInputStream.java
@@ -38,7 +38,6 @@
 /**
  * This object provides an input stream to the Operation objects used in this
  * package.
- *
  * @hide
  */
 public final class PrivateInputStream extends InputStream {
@@ -53,7 +52,6 @@
 
     /**
      * Creates an input stream for the <code>Operation</code> to read from
-     *
      * @param p the connection this input stream is for
      */
     public PrivateInputStream(BaseStream p) {
@@ -68,10 +66,8 @@
      * input stream without blocking by the next caller of a method for this
      * input stream. The next caller might be the same thread or or another
      * thread.
-     *
      * @return the number of bytes that can be read from this input stream
-     * without blocking
-     *
+     *         without blocking
      * @throws IOException if an I/O error occurs
      */
     @Override
@@ -82,14 +78,12 @@
 
     /**
      * Reads the next byte of data from the input stream. The value byte is
-     * returned as an int in the range 0 to 255. If no byte is available
-     * because the end of the stream has been reached, the value -1 is
-     * returned. This method blocks until input data is available, the end of
-     * the stream is detected, or an exception is thrown.
-     *
-     * @return the byte read from the input stream or -1 if it reaches the end
-     * of stream
-     *
+     * returned as an int in the range 0 to 255. If no byte is available because
+     * the end of the stream has been reached, the value -1 is returned. This
+     * method blocks until input data is available, the end of the stream is
+     * detected, or an exception is thrown.
+     * @return the byte read from the input stream or -1 if it reaches the end of
+     *         stream
      * @throws IOException if an I/O error occurs
      */
     @Override
@@ -147,9 +141,7 @@
     /**
      * Allows the <code>OperationImpl</code> thread to add body data to the
      * input stream.
-     *
      * @param body the data to add to the stream
-     *
      * @param start the start of the body to array to copy
      */
     public synchronized void writeBytes(byte[] body, int start) {
@@ -167,7 +159,6 @@
 
     /**
      * Verifies that this stream is open
-     *
      * @throws IOException if the stream is not open
      */
     private void ensureOpen() throws IOException {
@@ -178,9 +169,8 @@
     }
 
     /**
-     * Closes the input stream.  If the input stream is already closed, do
+     * Closes the input stream. If the input stream is already closed, do
      * nothing.
-     *
      * @throws IOException this will never happen
      */
     @Override
diff --git a/obex/javax/obex/PrivateOutputStream.java b/obex/javax/obex/PrivateOutputStream.java
index d972f78..ca420af 100644
--- a/obex/javax/obex/PrivateOutputStream.java
+++ b/obex/javax/obex/PrivateOutputStream.java
@@ -39,7 +39,6 @@
 /**
  * This object provides an output stream to the Operation objects used in this
  * package.
- *
  * @hide
  */
 public final class PrivateOutputStream extends OutputStream {
@@ -54,18 +53,17 @@
 
     /**
      * Creates an empty <code>PrivateOutputStream</code> to write to.
-     *
      * @param p the connection that this stream runs over
      */
     public PrivateOutputStream(BaseStream p, int maxSize) {
         mParent = p;
         mArray = new ByteArrayOutputStream();
         mMaxPacketSize = maxSize;
+        mOpen = true;
     }
 
     /**
      * Determines how many bytes have been written to the output stream.
-     *
      * @return the number of bytes written to the output stream
      */
     public int size() {
@@ -73,13 +71,11 @@
     }
 
     /**
-     * Writes the specified byte to this output stream. The general contract
-     * for write is that one byte is written to the output stream. The byte to
-     * be written is the eight low-order bits of the argument b. The 24
-     * high-order bits of b are ignored.
-     *
+     * Writes the specified byte to this output stream. The general contract for
+     * write is that one byte is written to the output stream. The byte to be
+     * written is the eight low-order bits of the argument b. The 24 high-order
+     * bits of b are ignored.
      * @param b the byte to write
-     *
      * @throws IOException if an I/O error occurs
      */
     @Override
@@ -128,9 +124,7 @@
 
     /**
      * Reads the bytes that have been written to this stream.
-     *
      * @param size the size of the array to return
-     *
      * @return the byte array that is written
      */
     public synchronized byte[] readBytes(int size) {
@@ -150,7 +144,6 @@
 
     /**
      * Verifies that this stream is open
-     *
      * @throws IOException if the stream is not open
      */
     private void ensureOpen() throws IOException {
@@ -161,9 +154,8 @@
     }
 
     /**
-     * Closes the output stream.  If the input stream is already closed, do
+     * Closes the output stream. If the input stream is already closed, do
      * nothing.
-     *
      * @throws IOException this will never happen
      */
     @Override
@@ -174,9 +166,8 @@
 
     /**
      * Determines if the connection is closed
-     *
-     * @return <code>true</code> if the connection is closed;
-     * <code>false</code> if the connection is open
+     * @return <code>true</code> if the connection is closed; <code>false</code>
+     *         if the connection is open
      */
     public boolean isClosed() {
         return !mOpen;
diff --git a/obex/javax/obex/ResponseCodes.java b/obex/javax/obex/ResponseCodes.java
index f6cc9c1..a2b9a37 100644
--- a/obex/javax/obex/ResponseCodes.java
+++ b/obex/javax/obex/ResponseCodes.java
@@ -33,8 +33,8 @@
 package javax.obex;
 
 /**
- * The <code>ResponseCodes</code> class contains the list of valid
- * response codes a server may send to a client.
+ * The <code>ResponseCodes</code> class contains the list of valid response
+ * codes a server may send to a client.
  * <P>
  * <STRONG>IMPORTANT NOTE</STRONG>
  * <P>
@@ -42,13 +42,12 @@
  * specification, which is different with the HTTP specification.
  * <P>
  * <code>OBEX_DATABASE_FULL</code> and <code>OBEX_DATABASE_LOCKED</code> require
- * further description since they are not defined in HTTP.  The server will send
+ * further description since they are not defined in HTTP. The server will send
  * an <code>OBEX_DATABASE_FULL</code> message when the client requests that
  * something be placed into a database but the database is full (cannot take
- * more data).   <code>OBEX_DATABASE_LOCKED</code> will be returned when the
+ * more data). <code>OBEX_DATABASE_LOCKED</code> will be returned when the
  * client wishes to access a database, database table, or database record that
  * has been locked.
- *
  * @hide
  */
 public final class ResponseCodes {
diff --git a/obex/javax/obex/ServerOperation.java b/obex/javax/obex/ServerOperation.java
index 6c3d9ba..8710c64 100644
--- a/obex/javax/obex/ServerOperation.java
+++ b/obex/javax/obex/ServerOperation.java
@@ -42,18 +42,14 @@
 /**
  * This class implements the Operation interface for server side connections.
  * <P>
- * <STRONG>Request Codes</STRONG>
- * There are four different request codes that are in this class.  0x02 is a
- * PUT request that signals that the request is not complete and requires an
- * additional OBEX packet.  0x82 is a PUT request that says that request is
- * complete.  In this case, the server can begin sending the response.  The
- * 0x03 is a GET request that signals that the request is not finished.  When
- * the server receives a 0x83, the client is signaling the server that it is
- * done with its request.
- *
- * TODO: Extend the ClientOperation and reuse the methods defined
- * TODO: in that class.
- *
+ * <STRONG>Request Codes</STRONG> There are four different request codes that
+ * are in this class. 0x02 is a PUT request that signals that the request is not
+ * complete and requires an additional OBEX packet. 0x82 is a PUT request that
+ * says that request is complete. In this case, the server can begin sending the
+ * response. The 0x03 is a GET request that signals that the request is not
+ * finished. When the server receives a 0x83, the client is signaling the server
+ * that it is done with its request. TODO: Extend the ClientOperation and reuse
+ * the methods defined TODO: in that class.
  * @hide
  */
 public final class ServerOperation implements Operation, BaseStream {
@@ -94,19 +90,12 @@
 
     /**
      * Creates new ServerOperation
-     *
      * @param p the parent that created this object
-     *
      * @param in the input stream to read from
-     *
      * @param out the output stream to write to
-     *
      * @param request the initial request that was received from the client
-     *
      * @param maxSize the max packet size that the client will accept
-     *
      * @param listen the listener that is responding to the request
-     *
      * @throws IOException if an IO error occurs
      */
     public ServerOperation(ServerSession p, InputStream in, int request, int maxSize,
@@ -240,17 +229,16 @@
     }
 
     /**
-     * Determines if the operation should continue or should wait.  If it
-     * should continue, this method will continue the operation.
-     *
+     * Determines if the operation should continue or should wait. If it should
+     * continue, this method will continue the operation.
      * @param sendEmpty if <code>true</code> then this will continue the
-     * operation even if no headers will be sent; if <code>false</code> then
-     * this method will only continue the operation if there are headers to
-     * send
-     * @param isStream  if<code>true</code> the stream is input stream, otherwise
-     * output stream
+     *        operation even if no headers will be sent; if <code>false</code>
+     *        then this method will only continue the operation if there are
+     *        headers to send
+     * @param inStream if<code>true</code> the stream is input stream, otherwise
+     *        output stream
      * @return <code>true</code> if the operation was completed;
-     * <code>false</code> if no operation took place
+     *         <code>false</code> if no operation took place
      */
     public synchronized boolean continueOperation(boolean sendEmpty, boolean inStream)
             throws IOException {
@@ -277,15 +265,13 @@
     }
 
     /**
-     * Sends a reply to the client.  If the reply is a OBEX_HTTP_CONTINUE, it
+     * Sends a reply to the client. If the reply is a OBEX_HTTP_CONTINUE, it
      * will wait for a response from the client before ending.
-     *
      * @param type the response code to send back to the client
-     *
      * @return <code>true</code> if the final bit was not set on the reply;
-     * <code>false</code> if no reply was received because the operation ended,
-     * an abort was received, or the final bit was set in the reply
-     *
+     *         <code>false</code> if no reply was received because the operation
+     *         ended, an abort was received, or the final bit was set in the
+     *         reply
      * @throws IOException if an IO error occurs
      */
     public synchronized boolean sendReply(int type) throws IOException {
@@ -492,12 +478,11 @@
     }
 
     /**
-     * Sends an ABORT message to the server.  By calling this method, the
+     * Sends an ABORT message to the server. By calling this method, the
      * corresponding input and output streams will be closed along with this
      * object.
-     *
-     * @throws IOException if the transaction has already ended or if an
-     * OBEX server called this method
+     * @throws IOException if the transaction has already ended or if an OBEX
+     *         server called this method
      */
     public void abort() throws IOException {
         throw new IOException("Called from a server");
@@ -505,11 +490,9 @@
 
     /**
      * Returns the headers that have been received during the operation.
-     * Modifying the object returned has no effect on the headers that are
-     * sent or retrieved.
-     *
+     * Modifying the object returned has no effect on the headers that are sent
+     * or retrieved.
      * @return the headers received during this <code>Operation</code>
-     *
      * @throws IOException if this <code>Operation</code> has been closed
      */
     public HeaderSet getReceivedHeader() throws IOException {
@@ -520,14 +503,11 @@
     /**
      * Specifies the headers that should be sent in the next OBEX message that
      * is sent.
-     *
      * @param headers the headers to send in the next message
-     *
-     * @throws IOException  if this <code>Operation</code> has been closed
-     * or the transaction has ended and no further messages will be exchanged
-     *
+     * @throws IOException if this <code>Operation</code> has been closed or the
+     *         transaction has ended and no further messages will be exchanged
      * @throws IllegalArgumentException if <code>headers</code> was not created
-     * by a call to <code>ServerRequestHandler.createHeaderSet()</code>
+     *         by a call to <code>ServerRequestHandler.createHeaderSet()</code>
      */
     public void sendHeaders(HeaderSet headers) throws IOException {
         ensureOpen();
@@ -546,15 +526,14 @@
     }
 
     /**
-     * Retrieves the response code retrieved from the server.  Response codes
-     * are defined in the <code>ResponseCodes</code> interface.
-     *
+     * Retrieves the response code retrieved from the server. Response codes are
+     * defined in the <code>ResponseCodes</code> interface.
      * @return the response code retrieved from the server
-     *
      * @throws IOException if an error occurred in the transport layer during
-     * the transaction; if this method is called on a <code>HeaderSet</code>
-     * object created by calling <code>createHeaderSet</code> in a
-     * <code>ClientSession</code> object; if this is called from a server
+     *         the transaction; if this method is called on a
+     *         <code>HeaderSet</code> object created by calling
+     *         <code>createHeaderSet</code> in a <code>ClientSession</code>
+     *         object; if this is called from a server
      */
     public int getResponseCode() throws IOException {
         throw new IOException("Called from a server");
@@ -562,7 +541,6 @@
 
     /**
      * Always returns <code>null</code>
-     *
      * @return <code>null</code>
      */
     public String getEncoding() {
@@ -573,9 +551,8 @@
      * Returns the type of content that the resource connected to is providing.
      * E.g. if the connection is via HTTP, then the value of the content-type
      * header field is returned.
-     *
      * @return the content type of the resource that the URL references, or
-     * <code>null</code> if not known
+     *         <code>null</code> if not known
      */
     public String getType() {
         try {
@@ -587,11 +564,10 @@
 
     /**
      * Returns the length of the content which is being provided. E.g. if the
-     * connection is via HTTP, then the value of the content-length header
-     * field is returned.
-     *
+     * connection is via HTTP, then the value of the content-length header field
+     * is returned.
      * @return the content length of the resource that this connection's URL
-     * references, or -1 if the content length is not known
+     *         references, or -1 if the content length is not known
      */
     public long getLength() {
         try {
@@ -613,9 +589,7 @@
 
     /**
      * Open and return an input stream for a connection.
-     *
      * @return an input stream
-     *
      * @throws IOException if an I/O error occurs
      */
     public InputStream openInputStream() throws IOException {
@@ -625,9 +599,7 @@
 
     /**
      * Open and return a data input stream for a connection.
-     *
      * @return an input stream
-     *
      * @throws IOException if an I/O error occurs
      */
     public DataInputStream openDataInputStream() throws IOException {
@@ -636,9 +608,7 @@
 
     /**
      * Open and return an output stream for a connection.
-     *
      * @return an output stream
-     *
      * @throws IOException if an I/O error occurs
      */
     public OutputStream openOutputStream() throws IOException {
@@ -661,9 +631,7 @@
 
     /**
      * Open and return a data output stream for a connection.
-     *
      * @return an output stream
-     *
      * @throws IOException if an I/O error occurs
      */
     public DataOutputStream openDataOutputStream() throws IOException {
@@ -672,7 +640,6 @@
 
     /**
      * Closes the connection and ends the transaction
-     *
      * @throws IOException if the operation has already ended or is closed
      */
     public void close() throws IOException {
@@ -682,7 +649,6 @@
 
     /**
      * Verifies that the connection is open and no exceptions should be thrown.
-     *
      * @throws IOException if an exception needs to be thrown
      */
     public void ensureOpen() throws IOException {
@@ -695,26 +661,23 @@
     }
 
     /**
-     * Verifies that additional information may be sent.  In other words, the
+     * Verifies that additional information may be sent. In other words, the
      * operation is not done.
      * <P>
-     * Included to implement the BaseStream interface only.  It does not do
+     * Included to implement the BaseStream interface only. It does not do
      * anything on the server side since the operation of the Operation object
      * is not done until after the handler returns from its method.
-     *
      * @throws IOException if the operation is completed
      */
     public void ensureNotDone() throws IOException {
     }
 
     /**
-     * Called when the output or input stream is closed.  It does not do
-     * anything on the server side since the operation of the Operation object
-     * is not done until after the handler returns from its method.
-     *
+     * Called when the output or input stream is closed. It does not do anything
+     * on the server side since the operation of the Operation object is not
+     * done until after the handler returns from its method.
      * @param inStream <code>true</code> if the input stream is closed;
-     * <code>false</code> if the output stream is closed
-     *
+     *        <code>false</code> if the output stream is closed
      * @throws IOException if an IO error occurs
      */
     public void streamClosed(boolean inStream) throws IOException {
diff --git a/obex/javax/obex/ServerRequestHandler.java b/obex/javax/obex/ServerRequestHandler.java
index e468b83..d93e5b6 100644
--- a/obex/javax/obex/ServerRequestHandler.java
+++ b/obex/javax/obex/ServerRequestHandler.java
@@ -33,40 +33,38 @@
 package javax.obex;
 
 /**
- * The <code>ServerRequestHandler</code> class defines an event
- * listener that will respond to OBEX requests made to the server.
+ * The <code>ServerRequestHandler</code> class defines an event listener that
+ * will respond to OBEX requests made to the server.
  * <P>
- * The <code>onConnect()</code>, <code>onSetPath()</code>, <code>onDelete()</code>,
- * <code>onGet()</code>,
- * and <code>onPut()</code> methods may return any response code defined
- * in the <code>ResponseCodes</code> class except for
- * <code>OBEX_HTTP_CONTINUE</code>.  If <code>OBEX_HTTP_CONTINUE</code> or
- * a value not defined in the <code>ResponseCodes</code> class is returned,
- * the server implementation will send an <code>OBEX_HTTP_INTERNAL_ERROR</code>
- * response to the client.
+ * The <code>onConnect()</code>, <code>onSetPath()</code>,
+ * <code>onDelete()</code>, <code>onGet()</code>, and <code>onPut()</code>
+ * methods may return any response code defined in the
+ * <code>ResponseCodes</code> class except for <code>OBEX_HTTP_CONTINUE</code>.
+ * If <code>OBEX_HTTP_CONTINUE</code> or a value not defined in the
+ * <code>ResponseCodes</code> class is returned, the server implementation will
+ * send an <code>OBEX_HTTP_INTERNAL_ERROR</code> response to the client.
  * <P>
  * <STRONG>Connection ID and Target Headers</STRONG>
  * <P>
  * According to the IrOBEX specification, a packet may not contain a Connection
- * ID and Target header.  Since the Connection ID header is managed by the
+ * ID and Target header. Since the Connection ID header is managed by the
  * implementation, it will not send a Connection ID header, if a Connection ID
- * was specified, in a packet that has a Target header.  In other words, if an
- * application adds a Target header to a <code>HeaderSet</code> object used
- * in an OBEX operation and a Connection ID was specified, no Connection ID
- * will be sent in the packet containing the Target header.
+ * was specified, in a packet that has a Target header. In other words, if an
+ * application adds a Target header to a <code>HeaderSet</code> object used in
+ * an OBEX operation and a Connection ID was specified, no Connection ID will be
+ * sent in the packet containing the Target header.
  * <P>
  * <STRONG>CREATE-EMPTY Requests</STRONG>
  * <P>
  * A CREATE-EMPTY request allows clients to create empty objects on the server.
- * When a CREATE-EMPTY request is received, the <code>onPut()</code> method
- * will be called by the implementation.  To differentiate between a normal
- * PUT request and a CREATE-EMPTY request, an application must open the
- * <code>InputStream</code> from the <code>Operation</code> object passed
- * to the <code>onPut()</code> method.  For a PUT request, the application
- * will be able to read Body data from this <code>InputStream</code>.  For
- * a CREATE-EMPTY request, there will be no Body data to read.  Therefore,
- * a call to <code>InputStream.read()</code> will return -1.
- *
+ * When a CREATE-EMPTY request is received, the <code>onPut()</code> method will
+ * be called by the implementation. To differentiate between a normal PUT
+ * request and a CREATE-EMPTY request, an application must open the
+ * <code>InputStream</code> from the <code>Operation</code> object passed to the
+ * <code>onPut()</code> method. For a PUT request, the application will be able
+ * to read Body data from this <code>InputStream</code>. For a CREATE-EMPTY
+ * request, there will be no Body data to read. Therefore, a call to
+ * <code>InputStream.read()</code> will return -1.
  * @hide
  */
 public class ServerRequestHandler {
@@ -74,8 +72,8 @@
     private long mConnectionId;
 
     /**
-      * Creates a <code>ServerRequestHandler</code>.
-      */
+     * Creates a <code>ServerRequestHandler</code>.
+     */
     protected ServerRequestHandler() {
         /*
          * A connection ID of -1 implies there is no conenction ID
@@ -85,12 +83,10 @@
 
     /**
      * Sets the connection ID header to include in the reply packets.
-     *
-     * @param connectionId the connection ID to use; -1 if no connection ID should be
-     * sent
-     *
-     * @throws IllegalArgumentException if <code>id</code> is not in the
-     * range -1 to 2<sup>32</sup>-1
+     * @param connectionId the connection ID to use; -1 if no connection ID
+     *        should be sent
+     * @throws IllegalArgumentException if <code>id</code> is not in the range
+     *         -1 to 2<sup>32</sup>-1
      */
     public void setConnectionId(final long connectionId) {
         if ((connectionId < -1) || (connectionId > 0xFFFFFFFFL)) {
@@ -102,9 +98,8 @@
     /**
      * Retrieves the connection ID that is being used in the present connection.
      * This method will return -1 if no connection ID is being used.
-     *
      * @return the connection id being used or -1 if no connection ID is being
-     * used
+     *         used
      */
     public long getConnectionId() {
         return mConnectionId;
@@ -113,23 +108,21 @@
     /**
      * Called when a CONNECT request is received.
      * <P>
-     * If this method is not implemented by the class that extends this
-     * class, <code>onConnect()</code> will always return an
-     * <code>OBEX_HTTP_OK</code> response code.
+     * If this method is not implemented by the class that extends this class,
+     * <code>onConnect()</code> will always return an <code>OBEX_HTTP_OK</code>
+     * response code.
      * <P>
      * The headers received in the request can be retrieved from the
-     * <code>request</code> argument.  The headers that should be sent
-     * in the reply must be specified in the <code>reply</code> argument.
-     *
+     * <code>request</code> argument. The headers that should be sent in the
+     * reply must be specified in the <code>reply</code> argument.
      * @param request contains the headers sent by the client;
-     * <code>request</code> will never be <code>null</code>
-     *
+     *        <code>request</code> will never be <code>null</code>
      * @param reply the headers that should be sent in the reply;
-     * <code>reply</code> will never be <code>null</code>
-     *
-     * @return a response code defined in <code>ResponseCodes</code> that will be
-     * returned to the client; if an invalid response code is provided, the
-     * <code>OBEX_HTTP_INTERNAL_ERROR</code> response code will be used
+     *        <code>reply</code> will never be <code>null</code>
+     * @return a response code defined in <code>ResponseCodes</code> that will
+     *         be returned to the client; if an invalid response code is
+     *         provided, the <code>OBEX_HTTP_INTERNAL_ERROR</code> response code
+     *         will be used
      */
     public int onConnect(HeaderSet request, HeaderSet reply) {
         return ResponseCodes.OBEX_HTTP_OK;
@@ -139,14 +132,12 @@
      * Called when a DISCONNECT request is received.
      * <P>
      * The headers received in the request can be retrieved from the
-     * <code>request</code> argument.  The headers that should be sent
-     * in the reply must be specified in the <code>reply</code> argument.
-     *
+     * <code>request</code> argument. The headers that should be sent in the
+     * reply must be specified in the <code>reply</code> argument.
      * @param request contains the headers sent by the client;
-     * <code>request</code> will never be <code>null</code>
-     *
+     *        <code>request</code> will never be <code>null</code>
      * @param reply the headers that should be sent in the reply;
-     * <code>reply</code> will never be <code>null</code>
+     *        <code>reply</code> will never be <code>null</code>
      */
     public void onDisconnect(HeaderSet request, HeaderSet reply) {
     }
@@ -154,32 +145,28 @@
     /**
      * Called when a SETPATH request is received.
      * <P>
-     * If this method is not implemented by the class that extends this
-     * class, <code>onSetPath()</code> will always return an
+     * If this method is not implemented by the class that extends this class,
+     * <code>onSetPath()</code> will always return an
      * <code>OBEX_HTTP_NOT_IMPLEMENTED</code> response code.
      * <P>
      * The headers received in the request can be retrieved from the
-     * <code>request</code> argument.  The headers that should be sent
-     * in the reply must be specified in the <code>reply</code> argument.
-     *
+     * <code>request</code> argument. The headers that should be sent in the
+     * reply must be specified in the <code>reply</code> argument.
      * @param request contains the headers sent by the client;
-     * <code>request</code> will never be <code>null</code>
-     *
+     *        <code>request</code> will never be <code>null</code>
      * @param reply the headers that should be sent in the reply;
-     * <code>reply</code> will never be <code>null</code>
-     *
+     *        <code>reply</code> will never be <code>null</code>
      * @param backup <code>true</code> if the client requests that the server
-     * back up one directory before changing to the path described by
-     * <code>name</code>; <code>false</code> to apply the request to the present
-     * path
-     *
+     *        back up one directory before changing to the path described by
+     *        <code>name</code>; <code>false</code> to apply the request to the
+     *        present path
      * @param create <code>true</code> if the path should be created if it does
-     * not already exist; <code>false</code> if the path should not be created
-     * if it does not exist and an error code should be returned
-     *
-     * @return a response code defined in <code>ResponseCodes</code> that will be
-     * returned to the client; if an invalid response code is provided, the
-     * <code>OBEX_HTTP_INTERNAL_ERROR</code> response code will be used
+     *        not already exist; <code>false</code> if the path should not be
+     *        created if it does not exist and an error code should be returned
+     * @return a response code defined in <code>ResponseCodes</code> that will
+     *         be returned to the client; if an invalid response code is
+     *         provided, the <code>OBEX_HTTP_INTERNAL_ERROR</code> response code
+     *         will be used
      */
     public int onSetPath(HeaderSet request, HeaderSet reply, boolean backup, boolean create) {
 
@@ -189,23 +176,21 @@
     /**
      * Called when a DELETE request is received.
      * <P>
-     * If this method is not implemented by the class that extends this
-     * class, <code>onDelete()</code> will always return an
+     * If this method is not implemented by the class that extends this class,
+     * <code>onDelete()</code> will always return an
      * <code>OBEX_HTTP_NOT_IMPLEMENTED</code> response code.
      * <P>
      * The headers received in the request can be retrieved from the
-     * <code>request</code> argument.  The headers that should be sent
-     * in the reply must be specified in the <code>reply</code> argument.
-     *
+     * <code>request</code> argument. The headers that should be sent in the
+     * reply must be specified in the <code>reply</code> argument.
      * @param request contains the headers sent by the client;
-     * <code>request</code> will never be <code>null</code>
-     *
+     *        <code>request</code> will never be <code>null</code>
      * @param reply the headers that should be sent in the reply;
-     * <code>reply</code> will never be <code>null</code>
-     *
-     * @return a response code defined in <code>ResponseCodes</code> that will be
-     * returned to the client; if an invalid response code is provided, the
-     * <code>OBEX_HTTP_INTERNAL_ERROR</code> response code will be used
+     *        <code>reply</code> will never be <code>null</code>
+     * @return a response code defined in <code>ResponseCodes</code> that will
+     *         be returned to the client; if an invalid response code is
+     *         provided, the <code>OBEX_HTTP_INTERNAL_ERROR</code> response code
+     *         will be used
      */
     public int onDelete(HeaderSet request, HeaderSet reply) {
         return ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED;
@@ -214,20 +199,19 @@
     /**
      * Called when a PUT request is received.
      * <P>
-     * If this method is not implemented by the class that extends this
-     * class, <code>onPut()</code> will always return an
+     * If this method is not implemented by the class that extends this class,
+     * <code>onPut()</code> will always return an
      * <code>OBEX_HTTP_NOT_IMPLEMENTED</code> response code.
      * <P>
      * If an ABORT request is received during the processing of a PUT request,
      * <code>op</code> will be closed by the implementation.
-     *
      * @param operation contains the headers sent by the client and allows new
-     * headers to be sent in the reply; <code>op</code> will never be
-     * <code>null</code>
-     *
-     * @return a response code defined in <code>ResponseCodes</code> that will be
-     * returned to the client; if an invalid response code is provided, the
-     * <code>OBEX_HTTP_INTERNAL_ERROR</code> response code will be used
+     *        headers to be sent in the reply; <code>op</code> will never be
+     *        <code>null</code>
+     * @return a response code defined in <code>ResponseCodes</code> that will
+     *         be returned to the client; if an invalid response code is
+     *         provided, the <code>OBEX_HTTP_INTERNAL_ERROR</code> response code
+     *         will be used
      */
     public int onPut(Operation operation) {
         return ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED;
@@ -236,20 +220,19 @@
     /**
      * Called when a GET request is received.
      * <P>
-     * If this method is not implemented by the class that extends this
-     * class, <code>onGet()</code> will always return an
+     * If this method is not implemented by the class that extends this class,
+     * <code>onGet()</code> will always return an
      * <code>OBEX_HTTP_NOT_IMPLEMENTED</code> response code.
      * <P>
      * If an ABORT request is received during the processing of a GET request,
      * <code>op</code> will be closed by the implementation.
-     *
      * @param operation contains the headers sent by the client and allows new
-     * headers to be sent in the reply; <code>op</code> will never be
-     * <code>null</code>
-     *
-     * @return a response code defined in <code>ResponseCodes</code> that will be
-     * returned to the client; if an invalid response code is provided, the
-     * <code>OBEX_HTTP_INTERNAL_ERROR</code> response code will be used
+     *        headers to be sent in the reply; <code>op</code> will never be
+     *        <code>null</code>
+     * @return a response code defined in <code>ResponseCodes</code> that will
+     *         be returned to the client; if an invalid response code is
+     *         provided, the <code>OBEX_HTTP_INTERNAL_ERROR</code> response code
+     *         will be used
      */
     public int onGet(Operation operation) {
         return ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED;
@@ -262,9 +245,8 @@
      * <P>
      * If this method is not implemented by the class that extends this class,
      * this method will do nothing.
-     *
      * @param userName the user name returned in the authentication response;
-     * <code>null</code> if no user name was provided in the response
+     *        <code>null</code> if no user name was provided in the response
      */
     public void onAuthenticationFailure(byte[] userName) {
     }
@@ -274,7 +256,6 @@
      * <P>
      * If this method is not implemented by the class that extends this class,
      * this method will do nothing.
-     *
      */
     public void updateStatus(String message) {
     }
@@ -284,7 +265,6 @@
      * <P>
      * If this method is not implemented by the class that extends this class,
      * this method will do nothing.
-     *
      */
     public void onClose() {
     }
diff --git a/obex/javax/obex/ServerSession.java b/obex/javax/obex/ServerSession.java
index 3a0e8150..423d5a7 100644
--- a/obex/javax/obex/ServerSession.java
+++ b/obex/javax/obex/ServerSession.java
@@ -40,7 +40,6 @@
 
 /**
  * This class in an implementation of the OBEX ServerSession.
- * 
  * @hide
  */
 public final class ServerSession extends ObexSession implements Runnable {
@@ -63,19 +62,11 @@
 
     /**
      * Creates new ServerSession.
-     *
-     * @param trans
-     *            the connection to the client
-     *
-     * @param handler
-     *            the event listener that will process requests
-     *
-     * @param auth
-     *            the authenticator to use with this connection
-     *
-     * @throws IOException
-     *                if an error occurred while opening the input and output
-     *                streams
+     * @param trans the connection to the client
+     * @param handler the event listener that will process requests
+     * @param auth the authenticator to use with this connection
+     * @throws IOException if an error occurred while opening the input and
+     *         output streams
      */
     public ServerSession(ObexTransport trans, ServerRequestHandler handler, Authenticator auth)
             throws IOException {
@@ -163,12 +154,8 @@
      * <code>ServerOperation</code> object will always reply with a
      * OBEX_HTTP_CONTINUE reply. It will only reply if further information is
      * needed.
-     *
-     * @param type
-     *            the type of request received; either 0x02 or 0x82
-     *
-     * @throws IOException
-     *                if an error occurred at the transport layer
+     * @param type the type of request received; either 0x02 or 0x82
+     * @throws IOException if an error occurred at the transport layer
      */
     private void handlePutRequest(int type) throws IOException {
         ServerOperation op = new ServerOperation(this, mInput, type, mMaxPacketLength, mListener);
@@ -191,7 +178,14 @@
                 op.sendReply(response);
             }
         } catch (Exception e) {
-            sendResponse(ResponseCodes.OBEX_HTTP_INTERNAL_ERROR, null);
+            /*To fix bugs in aborted cases,
+             *(client abort file transfer prior to the last packet which has the end of body header,
+             *internal error should not be sent because server has already replied with
+             *OK response in "sendReply")
+             */
+            if (!op.isAborted) {
+                sendResponse(ResponseCodes.OBEX_HTTP_INTERNAL_ERROR, null);
+            }
         }
     }
 
@@ -205,12 +199,8 @@
      * <code>ServerOperation</code> object will always reply with a
      * OBEX_HTTP_CONTINUE reply. It will only reply if further information is
      * needed.
-     *
-     * @param type
-     *            the type of request received; either 0x03 or 0x83
-     *
-     * @throws IOException
-     *                if an error occurred at the transport layer
+     * @param type the type of request received; either 0x03 or 0x83
+     * @throws IOException if an error occurred at the transport layer
      */
     private void handleGetRequest(int type) throws IOException {
         ServerOperation op = new ServerOperation(this, mInput, type, mMaxPacketLength, mListener);
@@ -227,15 +217,9 @@
 
     /**
      * Send standard response.
-     *
-     * @param code
-     *            the response code to send
-     *
-     * @param header
-     *            the headers to include in the response
-     *
-     * @throws IOException
-     *                if an IO error occurs
+     * @param code the response code to send
+     * @param header the headers to include in the response
+     * @throws IOException if an IO error occurs
      */
     public void sendResponse(int code, byte[] header) throws IOException {
         int totalLength = 3;
@@ -265,9 +249,7 @@
      * <code>ServerRequestHandler</code> object. After the handler processes the
      * request, this method will create a reply message to send to the server
      * with the response code provided.
-     *
-     * @throws IOException
-     *                if an error occurred at the transport layer
+     * @throws IOException if an error occurred at the transport layer
      */
     private void handleSetPathRequest() throws IOException {
         int length;
@@ -393,9 +375,7 @@
      * will create a <code>HeaderSet</code> object to pass to the
      * <code>ServerRequestHandler</code> object. After the handler processes the
      * request, this method will create a reply message to send to the server.
-     *
-     * @throws IOException
-     *                if an error occurred at the transport layer
+     * @throws IOException if an error occurred at the transport layer
      */
     private void handleDisconnectRequest() throws IOException {
         int length;
@@ -500,9 +480,7 @@
      * <code>ServerRequestHandler</code> object. After the handler processes the
      * request, this method will create a reply message to send to the server
      * with the response code provided.
-     *
-     * @throws IOException
-     *                if an error occurred at the transport layer
+     * @throws IOException if an error occurred at the transport layer
      */
     private void handleConnectRequest() throws IOException {
         int packetLength;
@@ -660,10 +638,7 @@
     /**
      * Verifies that the response code is valid. If it is not valid, it will
      * return the <code>OBEX_HTTP_INTERNAL_ERROR</code> response code.
-     *
-     * @param code
-     *            the response code to check
-     *
+     * @param code the response code to check
      * @return the valid response code or <code>OBEX_HTTP_INTERNAL_ERROR</code>
      *         if <code>code</code> is not valid
      */
diff --git a/obex/javax/obex/SessionNotifier.java b/obex/javax/obex/SessionNotifier.java
index 36e0ebf..9836dd6 100644
--- a/obex/javax/obex/SessionNotifier.java
+++ b/obex/javax/obex/SessionNotifier.java
@@ -36,73 +36,53 @@
 
 /**
  * The <code>SessionNotifier</code> interface defines a connection notifier for
- * server-side OBEX connections.  When a <code>SessionNotifier</code> is
- * created and calls  <code>acceptAndOpen()</code>, it will begin listening for
- * clients to create a connection at the transport layer.  When the transport
- * layer connection is received, the <code>acceptAndOpen()</code> method will
- * return a  <code>javax.microedition.io.Connection</code> that is the
- * connection to the client.  The <code>acceptAndOpen()</code> method also takes a
+ * server-side OBEX connections. When a <code>SessionNotifier</code> is created
+ * and calls <code>acceptAndOpen()</code>, it will begin listening for clients
+ * to create a connection at the transport layer. When the transport layer
+ * connection is received, the <code>acceptAndOpen()</code> method will return a
+ * <code>javax.microedition.io.Connection</code> that is the connection to the
+ * client. The <code>acceptAndOpen()</code> method also takes a
  * <code>ServerRequestHandler</code> argument that will process the requests
  * from the client that connects to the server.
- *
  * @hide
  */
 public interface SessionNotifier {
 
     /**
      * Waits for a transport layer connection to be established and specifies
-     * the handler to handle the requests from the client.  No authenticator
-     * is associated with this connection, therefore, it is implementation
+     * the handler to handle the requests from the client. No authenticator is
+     * associated with this connection, therefore, it is implementation
      * dependent as to how an authentication challenge and authentication
      * response header will be received and processed.
      * <P>
-     * <H4>Additional Note for OBEX over Bluetooth</H4>
-     * If this method is called on a <code>SessionNotifier</code> object that
-     * does not have a <code>ServiceRecord</code> in the SDDB, the
-     * <code>ServiceRecord</code> for this object will be added to the SDDB.
-     * This method requests the BCC to put the
-     * local device in connectible mode so that it will respond to
+     * <H4>Additional Note for OBEX over Bluetooth</H4> If this method is called
+     * on a <code>SessionNotifier</code> object that does not have a
+     * <code>ServiceRecord</code> in the SDDB, the <code>ServiceRecord</code>
+     * for this object will be added to the SDDB. This method requests the BCC
+     * to put the local device in connectable mode so that it will respond to
      * connection attempts by clients.
      * <P>
-     * The following checks are done to verify that the service record
-     * provided is valid. If any of these checks fail, then a
+     * The following checks are done to verify that the service record provided
+     * is valid. If any of these checks fail, then a
      * <code>ServiceRegistrationException</code> is thrown.
      * <UL>
-     * <LI>ServiceClassIDList and ProtocolDescriptorList, the mandatory
-     * service attributes for a <code>btgoep</code> service record, must be
-     * present in the <code>ServiceRecord</code> associated with this notifier.
+     * <LI>ServiceClassIDList and ProtocolDescriptorList, the mandatory service
+     * attributes for a <code>btgoep</code> service record, must be present in
+     * the <code>ServiceRecord</code> associated with this notifier.
      * <LI>L2CAP, RFCOMM and OBEX must all be in the ProtocolDescriptorList
-     * <LI>The <code>ServiceRecord</code> associated with this notifier must
-     *  not have changed the RFCOMM server channel number
+     * <LI>The <code>ServiceRecord</code> associated with this notifier must not
+     * have changed the RFCOMM server channel number
      * </UL>
      * <P>
      * This method will not ensure that <code>ServiceRecord</code> associated
-     * with this notifier is a completely
-     * valid service record. It is the responsibility of the application to
-     * ensure that the service record follows all of the applicable
-     * syntactic and semantic rules for service record correctness.
-     *
+     * with this notifier is a completely valid service record. It is the
+     * responsibility of the application to ensure that the service record
+     * follows all of the applicable syntactic and semantic rules for service
+     * record correctness.
      * @param handler the request handler that will respond to OBEX requests
-     *
      * @return the connection to the client
-     *
      * @throws IOException if an error occurs in the transport layer
-     *
-     * @throws NullPointerException if <code>handler</code> is
-     * <code>null</code>
-     *
-     * @throws ServiceRegistrationException if the structure of the
-     * associated service record is invalid or if the service record
-     * could not be added successfully to the local SDDB.  The
-     * structure of service record is invalid if the service
-     * record is missing any mandatory service attributes, or has
-     * changed any of the values described above which are fixed and
-     * cannot be changed. Failures to add the record to the SDDB could
-     * be due to insufficient disk space, database locks, etc.
-     *
-     * @throws BluetoothStateException if the server device could
-     * not be placed in connectible mode because the device user has
-     * configured the device to be non-connectible
+     * @throws NullPointerException if <code>handler</code> is <code>null</code>
      */
     ObexSession acceptAndOpen(ServerRequestHandler handler) throws IOException;
 
@@ -112,56 +92,37 @@
      * <code>Authenticator</code> to use to respond to authentication challenge
      * and authentication response headers.
      * <P>
-     * <H4>Additional Note for OBEX over Bluetooth</H4>
-     * If this method is called on a <code>SessionNotifier</code> object that
-     * does not have a <code>ServiceRecord</code> in the SDDB, the
-     * <code>ServiceRecord</code> for this object will be added to the SDDB.
-     * This method requests the BCC to put the
-     * local device in connectible mode so that it will respond to
+     * <H4>Additional Note for OBEX over Bluetooth</H4> If this method is called
+     * on a <code>SessionNotifier</code> object that does not have a
+     * <code>ServiceRecord</code> in the SDDB, the <code>ServiceRecord</code>
+     * for this object will be added to the SDDB. This method requests the BCC
+     * to put the local device in connectable mode so that it will respond to
      * connection attempts by clients.
      * <P>
-     * The following checks are done to verify that the service record
-     * provided is valid. If any of these checks fail, then a
+     * The following checks are done to verify that the service record provided
+     * is valid. If any of these checks fail, then a
      * <code>ServiceRegistrationException</code> is thrown.
      * <UL>
-     * <LI>ServiceClassIDList and ProtocolDescriptorList, the mandatory
-     * service attributes for a <code>btgoep</code> service record, must be
-     * present in the <code>ServiceRecord</code> associated with this notifier.
+     * <LI>ServiceClassIDList and ProtocolDescriptorList, the mandatory service
+     * attributes for a <code>btgoep</code> service record, must be present in
+     * the <code>ServiceRecord</code> associated with this notifier.
      * <LI>L2CAP, RFCOMM and OBEX must all be in the ProtocolDescriptorList
-     * <LI>The <code>ServiceRecord</code> associated with this notifier must
-     *  not have changed the RFCOMM server channel number
+     * <LI>The <code>ServiceRecord</code> associated with this notifier must not
+     * have changed the RFCOMM server channel number
      * </UL>
      * <P>
      * This method will not ensure that <code>ServiceRecord</code> associated
-     * with this notifier is a completely
-     * valid service record. It is the responsibility of the application to
-     * ensure that the service record follows all of the applicable
-     * syntactic and semantic rules for service record correctness.
-     *
+     * with this notifier is a completely valid service record. It is the
+     * responsibility of the application to ensure that the service record
+     * follows all of the applicable syntactic and semantic rules for service
+     * record correctness.
      * @param handler the request handler that will respond to OBEX requests
-     *
      * @param auth the <code>Authenticator</code> to use with this connection;
-     * if <code>null</code> then no <code>Authenticator</code> will be used
-     *
+     *        if <code>null</code> then no <code>Authenticator</code> will be
+     *        used
      * @return the connection to the client
-     *
      * @throws IOException if an error occurs in the transport layer
-     *
-     * @throws NullPointerException if <code>handler</code> is
-     * <code>null</code>
-     *
-     * @throws ServiceRegistrationException if the structure of the
-     * associated service record is invalid or if the service record
-     * could not be added successfully to the local SDDB.  The
-     * structure of service record is invalid if the service
-     * record is missing any mandatory service attributes, or has
-     * changed any of the values described above which are fixed and
-     * cannot be changed. Failures to add the record to the SDDB could
-     * be due to insufficient disk space, database locks, etc.
-     *
-     * @throws BluetoothStateException if the server device could
-     * not be placed in connectible mode because the device user has
-     * configured the device to be non-connectible
+     * @throws NullPointerException if <code>handler</code> is <code>null</code>
      */
     ObexSession acceptAndOpen(ServerRequestHandler handler, Authenticator auth) throws IOException;
 }
diff --git a/opengl/include/EGL/eglnatives.h b/opengl/include/EGL/eglnatives.h
deleted file mode 100644
index 21622dc..0000000
--- a/opengl/include/EGL/eglnatives.h
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_EGLNATIVES_H
-#define ANDROID_EGLNATIVES_H
-
-#include <sys/types.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*****************************************************************************/
-
-/* flags returned from swapBuffer */
-#define EGL_NATIVES_FLAG_SIZE_CHANGED       0x00000001
-
-/* surface flags */
-#define EGL_NATIVES_FLAG_DESTROY_BACKBUFFER 0x00000001
-
-enum native_pixel_format_t
-{
-    NATIVE_PIXEL_FORMAT_RGBA_8888   = 1,
-    NATIVE_PIXEL_FORMAT_RGB_565     = 4,
-    NATIVE_PIXEL_FORMAT_BGRA_8888   = 5,
-    NATIVE_PIXEL_FORMAT_RGBA_5551   = 6,
-    NATIVE_PIXEL_FORMAT_RGBA_4444   = 7,
-    NATIVE_PIXEL_FORMAT_YCbCr_422_SP= 0x10,
-    NATIVE_PIXEL_FORMAT_YCbCr_420_SP= 0x11,
-};
-
-enum native_memory_type_t
-{
-    NATIVE_MEMORY_TYPE_PMEM         = 0,
-    NATIVE_MEMORY_TYPE_GPU          = 1,
-    NATIVE_MEMORY_TYPE_FB           = 2,
-    NATIVE_MEMORY_TYPE_HEAP         = 128
-};
-
-
-struct egl_native_window_t
-{
-    /*
-     * magic must be set to 0x600913
-     */
-    uint32_t    magic;
-    
-    /*
-     * must be sizeof(egl_native_window_t)
-     */
-    uint32_t    version;
-
-    /*
-     * ident is reserved for the Android platform
-     */
-    uint32_t    ident;
-    
-    /*
-     * width, height and stride of the window in pixels
-     * Any of these value can be nul in which case GL commands are
-     * accepted and processed as usual, but not rendering occurs.
-     */
-    int         width;      // w=h=0 is legal
-    int         height;
-    int         stride;
-
-    /*
-     * format of the native window (see ui/PixelFormat.h)
-     */
-    int         format;
-    
-    /*
-     * Offset of the bits in the VRAM
-     */
-    intptr_t    offset;
-    
-    /*
-     * flags describing some attributes of this surface
-     * EGL_NATIVES_FLAG_DESTROY_BACKBUFFER: backbuffer not preserved after 
-     * eglSwapBuffers
-     */
-    uint32_t    flags;
-    
-    /*
-     * horizontal and vertical resolution in DPI
-     */
-    float       xdpi;
-    float       ydpi;
-    
-    /*
-     * refresh rate in frames per second (Hz)
-     */
-    float       fps;
-    
-    
-    /*
-     *  Base memory virtual address of the surface in the CPU side
-     */
-    intptr_t    base;
-    
-    /*
-     *  Heap the offset above is based from
-     */
-    int         fd;
-    
-    /*
-     *  Memory type the surface resides into
-     */
-    uint8_t     memory_type;
-    
-    /*
-     * Reserved for future use. MUST BE ZERO.
-     */
-    uint8_t     reserved_pad[3];
-    int         reserved[8];
-    
-    /*
-     * Vertical stride (only relevant with planar formats) 
-     */
-    
-    int         vstride;
-
-    /*
-     * Hook called by EGL to hold a reference on this structure
-     */
-    void        (*incRef)(struct egl_native_window_t* window);
-
-    /*
-     * Hook called by EGL to release a reference on this structure
-     */
-    void        (*decRef)(struct egl_native_window_t* window);
-
-    /*
-     * Hook called by EGL to perform a page flip. This function
-     * may update the size attributes above, in which case it returns
-     * the EGL_NATIVES_FLAG_SIZE_CHANGED bit set.
-     */
-    uint32_t    (*swapBuffers)(struct egl_native_window_t* window);
-    
-    /*
-     * Reserved for future use. MUST BE ZERO.
-     */
-    void        (*reserved_proc_0)(void);
-
-    /*
-     * Reserved for future use. MUST BE ZERO.
-     */
-    void        (*reserved_proc_1)(void);
-    
-    /*
-     * Reserved for future use. MUST BE ZERO.
-     */
-    void        (*reserved_proc_2)(void);
-
-    
-    /*
-     * Hook called by EGL when the native surface is associated to EGL
-     * (eglCreateWindowSurface). Can be NULL.
-     */
-    void        (*connect)(struct egl_native_window_t* window);
-
-    /*
-     * Hook called by EGL when eglDestroySurface is called.  Can be NULL.
-     */
-    void        (*disconnect)(struct egl_native_window_t* window);
-    
-    /*
-     * Reserved for future use. MUST BE ZERO.
-     */
-    void        (*reserved_proc[11])(void);
-    
-    /*
-     *  Some storage reserved for the oem driver.
-     */
-    intptr_t    oem[4];
-};
-
-
-struct egl_native_pixmap_t
-{
-    int32_t     version;    /* must be 32 */
-    int32_t     width;
-    int32_t     height;
-    int32_t     stride;
-    uint8_t*    data;
-    uint8_t     format;
-    uint8_t     rfu[3];
-    union {
-        uint32_t    compressedFormat;
-        int32_t     vstride;
-    };
-    int32_t     reserved;
-};
-
-/*****************************************************************************/
-
-/* 
- * This a convenience function to create a NativeWindowType surface
- * that maps to the whole screen
- * This function is actually implemented in libui.so
- */
-
-struct egl_native_window_t* android_createDisplaySurface();
-
-/*****************************************************************************/
-
-
-/*
- * OEM's egl's library (libhgl.so) must imlement these hooks to allocate
- * the GPU memory they need  
- */
-
-
-typedef struct
-{
-    // for internal use
-    void*   user;
-    // virtual address of this area
-    void*   base;
-    // size of this area in bytes
-    size_t  size;
-    // physical address of this area
-    void*   phys;
-    // offset in this area available to the GPU
-    size_t  offset;
-    // fd of this area
-    int     fd;
-} gpu_area_t;
-
-typedef struct
-{
-    // area where GPU registers are mapped
-    gpu_area_t regs;
-    // number of extra areas (currently limited to 2)
-    int32_t count;
-    // extra GPU areas (currently limited to 2)
-    gpu_area_t gpu[2];
-} request_gpu_t;
-
-
-typedef request_gpu_t* (*OEM_EGL_acquire_gpu_t)(void* user);
-typedef int (*OEM_EGL_release_gpu_t)(void* user, request_gpu_t* handle);
-typedef void (*register_gpu_t)
-        (void* user, OEM_EGL_acquire_gpu_t, OEM_EGL_release_gpu_t);
-
-void oem_register_gpu(
-        void* user,
-        OEM_EGL_acquire_gpu_t acquire,
-        OEM_EGL_release_gpu_t release);
-
-
-/*****************************************************************************/
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* ANDROID_EGLNATIVES_H */
diff --git a/packages/TtsService/jni/android_tts_SynthProxy.cpp b/packages/TtsService/jni/android_tts_SynthProxy.cpp
index 4247483..64cdb5b 100644
--- a/packages/TtsService/jni/android_tts_SynthProxy.cpp
+++ b/packages/TtsService/jni/android_tts_SynthProxy.cpp
@@ -84,6 +84,7 @@
             mNbChannels = DEFAULT_TTS_NB_CHANNELS;
             mBufferSize = DEFAULT_TTS_BUFFERSIZE;
             mBuffer = new int8_t[mBufferSize];
+            memset(mBuffer, 0, mBufferSize);
         }
 
         ~SynthProxyJniStorage() {
@@ -194,6 +195,7 @@
             prepAudioTrack(pJniData, pForAfter->streamType, rate, format, channel);
             if (pJniData->mAudioOut) {
                 pJniData->mAudioOut->write(wav, bufferSize);
+                memset(wav, 0, bufferSize);
                 //LOGV("AudioTrack wrote: %d bytes", bufferSize);
             } else {
                 LOGE("Can't play, null audiotrack");
@@ -208,6 +210,7 @@
         }
         if (bufferSize > 0){
             fwrite(wav, 1, bufferSize, pForAfter->outputFile);
+            memset(wav, 0, bufferSize);
         }
     }
     // Future update:
@@ -473,6 +476,7 @@
 
     unsigned int unique_identifier;
 
+    memset(pSynthData->mBuffer, 0, pSynthData->mBufferSize);
     result = pSynthData->mNativeSynthInterface->synthesizeText(textNativeString,
             pSynthData->mBuffer, pSynthData->mBufferSize, (void *)pForAfter);
 
@@ -554,6 +558,7 @@
 
     if (pSynthData->mNativeSynthInterface) {
         const char *textNativeString = env->GetStringUTFChars(textJavaString, 0);
+        memset(pSynthData->mBuffer, 0, pSynthData->mBufferSize);
         result = pSynthData->mNativeSynthInterface->synthesizeText(textNativeString,
                 pSynthData->mBuffer, pSynthData->mBufferSize, (void *)pForAfter);
         env->ReleaseStringUTFChars(textJavaString, textNativeString);
@@ -575,12 +580,12 @@
 
     SynthProxyJniStorage* pSynthData = (SynthProxyJniStorage*)jniData;
 
-    if (pSynthData->mNativeSynthInterface) {
-        result = pSynthData->mNativeSynthInterface->stop();
-    }
     if (pSynthData->mAudioOut) {
         pSynthData->mAudioOut->stop();
     }
+    if (pSynthData->mNativeSynthInterface) {
+        result = pSynthData->mNativeSynthInterface->stop();
+    }
 
     return result;
 }
diff --git a/packages/TtsService/src/android/tts/TtsService.java b/packages/TtsService/src/android/tts/TtsService.java
index 4d25183..7c4996e 100755
--- a/packages/TtsService/src/android/tts/TtsService.java
+++ b/packages/TtsService/src/android/tts/TtsService.java
@@ -340,6 +340,8 @@
         Log.i("TTS service received", text);
         if (queueMode == TextToSpeech.TTS_QUEUE_FLUSH) {
             stop(callingApp);
+        } else if (queueMode == 2) {
+            stopAll(callingApp);
         }
         mSpeechQueue.add(new SpeechItem(callingApp, text, params, SpeechItem.TEXT));
         if (!mIsSpeaking) {
@@ -364,6 +366,8 @@
             ArrayList<String> params) {
         if (queueMode == TextToSpeech.TTS_QUEUE_FLUSH) {
             stop(callingApp);
+        } else if (queueMode == 2) {
+            stopAll(callingApp);
         }
         mSpeechQueue.add(new SpeechItem(callingApp, earcon, params, SpeechItem.EARCON));
         if (!mIsSpeaking) {
@@ -373,7 +377,7 @@
     }
 
     /**
-     * Stops all speech output and removes any utterances still in the queue.
+     * Stops all speech output and removes any utterances still in the queue for the calling app.
      */
     private int stop(String callingApp) {
         int result = TextToSpeech.TTS_ERROR;
@@ -389,15 +393,20 @@
                         mSpeechQueue.remove(i);
                     }
                 }
-
-                result = nativeSynth.stop();
-                mIsSpeaking = false;
-                if (mPlayer != null) {
-                    try {
-                        mPlayer.stop();
-                    } catch (IllegalStateException e) {
-                        // Do nothing, the player is already stopped.
+                if ((mCurrentSpeechItem != null) &&
+                     mCurrentSpeechItem.mCallingApp.equals(callingApp)) {
+                    result = nativeSynth.stop();
+                    if (mPlayer != null) {
+                        try {
+                            mPlayer.stop();
+                        } catch (IllegalStateException e) {
+                            // Do nothing, the player is already stopped.
+                        }
                     }
+                    mIsSpeaking = false;
+                    mCurrentSpeechItem = null;
+                } else {
+                    result = TextToSpeech.TTS_SUCCESS;
                 }
                 Log.i("TTS", "Stopped");
             }
@@ -407,7 +416,55 @@
         } finally {
             // This check is needed because finally will always run; even if the
             // method returns somewhere in the try block.
-            mCurrentSpeechItem = null;
+            if (speechQueueAvailable) {
+                speechQueueLock.unlock();
+            }
+            return result;
+        }
+    }
+
+
+
+    /**
+     * Stops all speech output and removes any utterances still in the queue globally.
+     */
+    private int stopAll(String callingApp) {
+        int result = TextToSpeech.TTS_ERROR;
+        boolean speechQueueAvailable = false;
+        try{
+            // If the queue is locked for more than 1 second,
+            // something has gone very wrong with processSpeechQueue.
+            speechQueueAvailable = speechQueueLock.tryLock(1000, TimeUnit.MILLISECONDS);
+            if (speechQueueAvailable) {
+                for (int i = mSpeechQueue.size() - 1; i > -1; i--){
+                    if (mSpeechQueue.get(i).mType != SpeechItem.TEXT_TO_FILE){
+                        mSpeechQueue.remove(i);
+                    }
+                }
+                if ((mCurrentSpeechItem != null) &&
+                    ((mCurrentSpeechItem.mType != SpeechItem.TEXT_TO_FILE) ||
+                      mCurrentSpeechItem.mCallingApp.equals(callingApp))) {
+                    result = nativeSynth.stop();
+                    if (mPlayer != null) {
+                        try {
+                            mPlayer.stop();
+                        } catch (IllegalStateException e) {
+                            // Do nothing, the player is already stopped.
+                        }
+                    }
+                    mIsSpeaking = false;
+                    mCurrentSpeechItem = null;
+                } else {
+                    result = TextToSpeech.TTS_SUCCESS;
+                }
+                Log.i("TTS", "Stopped all");
+            }
+        } catch (InterruptedException e) {
+          Log.e("TTS stopAll", "tryLock interrupted");
+          e.printStackTrace();
+        } finally {
+            // This check is needed because finally will always run; even if the
+            // method returns somewhere in the try block.
             if (speechQueueAvailable) {
                 speechQueueLock.unlock();
             }
@@ -430,7 +487,6 @@
         if (utteranceId.length() > 0){
             dispatchUtteranceCompletedCallback(utteranceId, callingApp);
         }
-        mCurrentSpeechItem = null;
         processSpeechQueue();
     }
 
@@ -466,7 +522,6 @@
                     if (utteranceId.length() > 0){
                         dispatchUtteranceCompletedCallback(utteranceId, speechItem.mCallingApp);
                     }
-                    mCurrentSpeechItem = null;
                     processSpeechQueue();
                 }
             }
@@ -531,13 +586,12 @@
                     // This check is needed because finally will always run;
                     // even if the
                     // method returns somewhere in the try block.
-                    if (synthAvailable) {
-                        synthesizerLock.unlock();
-                    }
                     if (utteranceId.length() > 0){
                         dispatchUtteranceCompletedCallback(utteranceId, speechItem.mCallingApp);
                     }
-                    mCurrentSpeechItem = null;
+                    if (synthAvailable) {
+                        synthesizerLock.unlock();
+                    }
                     processSpeechQueue();
                 }
             }
@@ -595,13 +649,12 @@
                     // This check is needed because finally will always run;
                     // even if the
                     // method returns somewhere in the try block.
-                    if (synthAvailable) {
-                        synthesizerLock.unlock();
-                    }
                     if (utteranceId.length() > 0){
                         dispatchUtteranceCompletedCallback(utteranceId, speechItem.mCallingApp);
                     }
-                    mCurrentSpeechItem = null;
+                    if (synthAvailable) {
+                        synthesizerLock.unlock();
+                    }
                     processSpeechQueue();
                 }
             }
diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java
index 131e156..78db6f9 100644
--- a/services/java/com/android/server/AppWidgetService.java
+++ b/services/java/com/android/server/AppWidgetService.java
@@ -68,6 +68,7 @@
 
     private static final String SETTINGS_FILENAME = "appwidgets.xml";
     private static final String SETTINGS_TMP_FILENAME = SETTINGS_FILENAME + ".tmp";
+    private static final int MIN_UPDATE_PERIOD = 30 * 60 * 1000; // 30 minutes
 
     /*
      * When identifying a Host or Provider based on the calling process, use the uid field.
@@ -629,9 +630,12 @@
                 Binder.restoreCallingIdentity(token);
             }
             if (!alreadyRegistered) {
+                long period = p.info.updatePeriodMillis;
+                if (period < MIN_UPDATE_PERIOD) {
+                    period = MIN_UPDATE_PERIOD;
+                }
                 mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
-                        SystemClock.elapsedRealtime() + p.info.updatePeriodMillis,
-                        p.info.updatePeriodMillis, p.broadcast);
+                        SystemClock.elapsedRealtime() + period, period, p.broadcast);
             }
         }
     }
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index 69371b3..c493a12 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -100,18 +100,18 @@
     private PowerManager mPowerManager;
     private AlarmManager mAlarmManager;
 
-    private boolean mEnabled;   // access to this is synchronized on 'this'
-    private boolean mProvisioned;
-    private PowerManager.WakeLock mWakelock;
-    private final BackupHandler mBackupHandler = new BackupHandler();
-    private PendingIntent mRunBackupIntent;
-    private BroadcastReceiver mRunBackupReceiver;
-    private IntentFilter mRunBackupFilter;
+    boolean mEnabled;   // access to this is synchronized on 'this'
+    boolean mProvisioned;
+    PowerManager.WakeLock mWakelock;
+    final BackupHandler mBackupHandler = new BackupHandler();
+    PendingIntent mRunBackupIntent;
+    BroadcastReceiver mRunBackupReceiver;
+    IntentFilter mRunBackupFilter;
     // map UIDs to the set of backup client services within that UID's app set
-    private final SparseArray<HashSet<ApplicationInfo>> mBackupParticipants
+    final SparseArray<HashSet<ApplicationInfo>> mBackupParticipants
         = new SparseArray<HashSet<ApplicationInfo>>();
     // set of backup services that have pending changes
-    private class BackupRequest {
+    class BackupRequest {
         public ApplicationInfo appInfo;
         public boolean fullBackup;
 
@@ -125,35 +125,35 @@
         }
     }
     // Backups that we haven't started yet.
-    private HashMap<ApplicationInfo,BackupRequest> mPendingBackups
+    HashMap<ApplicationInfo,BackupRequest> mPendingBackups
             = new HashMap<ApplicationInfo,BackupRequest>();
 
     // Pseudoname that we use for the Package Manager metadata "package"
-    private static final String PACKAGE_MANAGER_SENTINEL = "@pm@";
+    static final String PACKAGE_MANAGER_SENTINEL = "@pm@";
 
     // locking around the pending-backup management
-    private final Object mQueueLock = new Object();
+    final Object mQueueLock = new Object();
 
     // The thread performing the sequence of queued backups binds to each app's agent
     // in succession.  Bind notifications are asynchronously delivered through the
     // Activity Manager; use this lock object to signal when a requested binding has
     // completed.
-    private final Object mAgentConnectLock = new Object();
-    private IBackupAgent mConnectedAgent;
-    private volatile boolean mConnecting;
+    final Object mAgentConnectLock = new Object();
+    IBackupAgent mConnectedAgent;
+    volatile boolean mConnecting;
 
     // A similar synchronicity mechanism around clearing apps' data for restore
-    private final Object mClearDataLock = new Object();
-    private volatile boolean mClearingData;
+    final Object mClearDataLock = new Object();
+    volatile boolean mClearingData;
 
     // Transport bookkeeping
-    private final HashMap<String,IBackupTransport> mTransports
+    final HashMap<String,IBackupTransport> mTransports
             = new HashMap<String,IBackupTransport>();
-    private String mCurrentTransport;
-    private IBackupTransport mLocalTransport, mGoogleTransport;
-    private RestoreSession mActiveRestoreSession;
+    String mCurrentTransport;
+    IBackupTransport mLocalTransport, mGoogleTransport;
+    RestoreSession mActiveRestoreSession;
 
-    private class RestoreParams {
+    class RestoreParams {
         public IBackupTransport transport;
         public IRestoreObserver observer;
         public long token;
@@ -165,7 +165,7 @@
         }
     }
 
-    private class ClearParams {
+    class ClearParams {
         public IBackupTransport transport;
         public PackageInfo packageInfo;
 
@@ -176,11 +176,17 @@
     }
 
     // Where we keep our journal files and other bookkeeping
-    private File mBaseStateDir;
-    private File mDataDir;
-    private File mJournalDir;
-    private File mJournal;
-    private RandomAccessFile mJournalStream;
+    File mBaseStateDir;
+    File mDataDir;
+    File mJournalDir;
+    File mJournal;
+    RandomAccessFile mJournalStream;
+
+    // Keep a log of all the apps we've ever backed up
+    private File mEverStored;
+    private RandomAccessFile mEverStoredStream;
+    HashSet<String> mEverStoredApps = new HashSet<String>();
+
 
     public BackupManagerService(Context context) {
         mContext = context;
@@ -215,6 +221,9 @@
         mJournalDir.mkdirs();   // creates mBaseStateDir along the way
         makeJournalLocked();    // okay because no other threads are running yet
 
+        // Set up the various sorts of package tracking we do
+        initPackageTracking();
+
         // Build our mapping of uid to backup client services.  This implicitly
         // schedules a backup pass on the Package Manager metadata the first
         // time anything needs to be backed up.
@@ -249,14 +258,6 @@
         // leftover journal files into the pending backup set
         parseLeftoverJournals();
 
-        // Register for broadcasts about package install, etc., so we can
-        // update the provider list.
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(Intent.ACTION_PACKAGE_ADDED);
-        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
-        filter.addDataScheme("package");
-        mContext.registerReceiver(mBroadcastReceiver, filter);
-
         // Power management
         mWakelock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "backup");
 
@@ -281,6 +282,67 @@
         }
     }
 
+    private void initPackageTracking() {
+        if (DEBUG) Log.v(TAG, "Initializing package tracking");
+
+        // Keep a log of what apps we've ever backed up.  Because we might have
+        // rebooted in the middle of an operation that was removing something from
+        // this log, we sanity-check its contents here and reconstruct it.
+        mEverStored = new File(mBaseStateDir, "processed");
+        File tempProcessedFile = new File(mBaseStateDir, "processed.new");
+        try {
+            RandomAccessFile temp = new RandomAccessFile(tempProcessedFile, "rw");
+            mEverStoredStream = new RandomAccessFile(mEverStored, "r");
+
+            // parse its existing contents
+            mEverStoredStream.seek(0);
+            temp.seek(0);
+            try {
+                while (true) {
+                    PackageInfo info;
+                    String pkg = mEverStoredStream.readUTF();
+                    try {
+                        info = mPackageManager.getPackageInfo(pkg, 0);
+                        mEverStoredApps.add(pkg);
+                        temp.writeUTF(pkg);
+                        if (DEBUG) Log.v(TAG, "   + " + pkg);
+                    } catch (NameNotFoundException e) {
+                        // nope, this package was uninstalled; don't include it
+                        if (DEBUG) Log.v(TAG, "   - " + pkg);
+                    }
+                }
+            } catch (EOFException e) {
+                // now we're at EOF
+            }
+
+            // Once we've rewritten the backup history log, atomically replace the
+            // old one with the new one then reopen the file for continuing use.
+            temp.close();
+            mEverStoredStream.close();
+            tempProcessedFile.renameTo(mEverStored);
+            mEverStoredStream = new RandomAccessFile(mEverStored, "rwd");
+        } catch (IOException e) {
+            Log.e(TAG, "Unable to open known-stored file!");
+            mEverStoredStream = null;
+        }
+
+        // If we were in the middle of removing something from the ever-backed-up
+        // file, there might be a transient "processed.new" file still present.
+        // We've reconstructed a coherent state at this point though, so we can
+        // safely discard that file now.
+        if (tempProcessedFile.exists()) {
+            tempProcessedFile.delete();
+        }
+
+        // Register for broadcasts about package install, etc., so we can
+        // update the provider list.
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Intent.ACTION_PACKAGE_ADDED);
+        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+        filter.addDataScheme("package");
+        mContext.registerReceiver(mBroadcastReceiver, filter);
+    }
+
     private void makeJournalLocked() {
         try {
             mJournal = File.createTempFile("journal", null, mJournalDir);
@@ -485,6 +547,17 @@
                     mBackupParticipants.put(uid, set);
                 }
                 set.add(pkg.applicationInfo);
+
+                // If we've never seen this app before, schedule a backup for it
+                if (!mEverStoredApps.contains(pkg.packageName)) {
+                    if (DEBUG) Log.i(TAG, "New app " + pkg.packageName
+                            + " never backed up; scheduling");
+                    try {
+                        dataChanged(pkg.packageName);
+                    } catch (RemoteException e) {
+                        // can't happen; it's a local method call
+                    }
+                }
             }
         }
     }
@@ -528,6 +601,7 @@
                     for (ApplicationInfo entry: set) {
                         if (entry.packageName.equals(pkg.packageName)) {
                             set.remove(entry);
+                            removeEverBackedUp(pkg.packageName);
                             break;
                         }
                     }
@@ -540,7 +614,7 @@
     }
 
     // Returns the set of all applications that define an android:backupAgent attribute
-    private List<PackageInfo> allAgentPackages() {
+    List<PackageInfo> allAgentPackages() {
         // !!! TODO: cache this and regenerate only when necessary
         int flags = PackageManager.GET_SIGNATURES;
         List<PackageInfo> packages = mPackageManager.getInstalledPackages(flags);
@@ -570,6 +644,65 @@
         addPackageParticipantsLockedInner(packageName, allApps);
     }
 
+    // Called from the backup thread: record that the given app has been successfully
+    // backed up at least once
+    void logBackupComplete(String packageName) {
+        if (mEverStoredStream != null && !packageName.equals(PACKAGE_MANAGER_SENTINEL)) {
+            synchronized (mEverStoredApps) {
+                if (mEverStoredApps.add(packageName)) {
+                    try {
+                        mEverStoredStream.writeUTF(packageName);
+                    } catch (IOException e) {
+                        Log.e(TAG, "Unable to log backup of " + packageName + ", ceasing log");
+                        try {
+                            mEverStoredStream.close();
+                        } catch (IOException ioe) {
+                            // we're dropping it; no need to handle an exception on close here
+                        }
+                        mEverStoredStream = null;
+                    }
+                }
+            }
+        }
+    }
+
+    // Remove our awareness of having ever backed up the given package
+    void removeEverBackedUp(String packageName) {
+        if (DEBUG) Log.v(TAG, "Removing backed-up knowledge of " + packageName
+                + ", new set:");
+
+        if (mEverStoredStream != null) {
+            synchronized (mEverStoredApps) {
+                // Rewrite the file and rename to overwrite.  If we reboot in the middle,
+                // we'll recognize on initialization time that the package no longer
+                // exists and fix it up then.
+                File tempKnownFile = new File(mBaseStateDir, "processed.new");
+                try {
+                    mEverStoredStream.close();
+                    RandomAccessFile known = new RandomAccessFile(tempKnownFile, "rw");
+                    mEverStoredApps.remove(packageName);
+                    for (String s : mEverStoredApps) {
+                        known.writeUTF(s);
+                        if (DEBUG) Log.v(TAG, "    " + s);
+                    }
+                    known.close();
+                    tempKnownFile.renameTo(mEverStored);
+                    mEverStoredStream = new RandomAccessFile(mEverStored, "rwd");
+                } catch (IOException e) {
+                    // Bad: we couldn't create the new copy.  For safety's sake we
+                    // abandon the whole process and remove all what's-backed-up
+                    // state entirely, meaning we'll force a backup pass for every
+                    // participant on the next boot or [re]install.
+                    Log.w(TAG, "Error rewriting backed-up set; halting log");
+                    mEverStoredStream = null;
+                    mEverStoredApps.clear();
+                    tempKnownFile.delete();
+                    mEverStored.delete();
+                }
+            }
+        }
+    }
+
     // Return the given transport
     private IBackupTransport getTransport(String transportName) {
         synchronized (mTransports) {
@@ -799,6 +932,7 @@
                 boolean success = false;
                 try {
                     agent.doBackup(savedState, backupData, newState);
+                    logBackupComplete(packageName);
                     success = true;
                 } finally {
                     if (savedState != null) {
@@ -1235,7 +1369,8 @@
                 }
             }
         } else {
-            Log.w(TAG, "dataChanged but no participant pkg='" + packageName + "'");
+            Log.w(TAG, "dataChanged but no participant pkg='" + packageName + "'"
+                    + " uid=" + Binder.getCallingUid());
         }
     }
 
@@ -1548,8 +1683,6 @@
     @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         synchronized (mQueueLock) {
-            long oldId = Binder.clearCallingIdentity();
-
             pw.println("Backup Manager is " + (mEnabled ? "enabled" : "disabled")
                     + " / " + (!mProvisioned ? "not " : "") + "provisioned");
             pw.println("Available transports:");
@@ -1568,12 +1701,14 @@
                     pw.println("    " + app.toString());
                 }
             }
+            pw.println("Ever backed up: " + mEverStoredApps.size());
+            for (String pkg : mEverStoredApps) {
+                pw.println("    " + pkg);
+            }
             pw.println("Pending: " + mPendingBackups.size());
             for (BackupRequest req : mPendingBackups.values()) {
                 pw.println("    " + req);
             }
-
-            Binder.restoreCallingIdentity(oldId);
         }
     }
 }
diff --git a/services/java/com/android/server/InputDevice.java b/services/java/com/android/server/InputDevice.java
index 9c1f942..a71c39a 100644
--- a/services/java/com/android/server/InputDevice.java
+++ b/services/java/com/android/server/InputDevice.java
@@ -66,19 +66,56 @@
         MotionEvent generateMotion(InputDevice device, long curTime, long curTimeNano,
                 boolean isAbs, Display display, int orientation,
                 int metaState) {
-            if (!changed) {
-                return null;
-            }
-            
             float scaledX = x;
             float scaledY = y;
             float temp;
             float scaledPressure = 1.0f;
             float scaledSize = 0;
             int edgeFlags = 0;
+            
+            int action;
+            if (down != lastDown) {
+                if (isAbs) {
+                    final AbsoluteInfo absX = device.absX;
+                    final AbsoluteInfo absY = device.absY;
+                    if (down && absX != null && absY != null) {
+                        // We don't let downs start unless we are
+                        // inside of the screen.  There are two reasons for
+                        // this: to avoid spurious touches when holding
+                        // the edges of the device near the touchscreen,
+                        // and to avoid reporting events if there are virtual
+                        // keys on the touchscreen outside of the display
+                        // area.
+                        if (scaledX < absX.minValue || scaledX > absX.maxValue
+                                || scaledY < absY.minValue || scaledY > absY.maxValue) {
+                            if (false) Log.v("InputDevice", "Rejecting (" + scaledX + ","
+                                    + scaledY + "): outside of ("
+                                    + absX.minValue + "," + absY.minValue
+                                    + ")-(" + absX.maxValue + ","
+                                    + absY.maxValue + ")");
+                            return null;
+                        }
+                    }
+                } else {
+                    x = y = 0;
+                }
+                lastDown = down;
+                if (down) {
+                    action = MotionEvent.ACTION_DOWN;
+                    downTime = curTime;
+                } else {
+                    action = MotionEvent.ACTION_UP;
+                }
+                currentMove = null;
+            } else {
+                action = MotionEvent.ACTION_MOVE;
+            }
+            
             if (isAbs) {
-                int w = display.getWidth()-1;
-                int h = display.getHeight()-1;
+                final int dispW = display.getWidth()-1;
+                final int dispH = display.getHeight()-1;
+                int w = dispW;
+                int h = dispH;
                 if (orientation == Surface.ROTATION_90
                         || orientation == Surface.ROTATION_270) {
                     int tmp = w;
@@ -120,16 +157,17 @@
                         break;
                 }
 
-                if (scaledX == 0) {
-                    edgeFlags += MotionEvent.EDGE_LEFT;
-                } else if (scaledX == display.getWidth() - 1.0f) {
-                    edgeFlags += MotionEvent.EDGE_RIGHT;
-                }
-                
-                if (scaledY == 0) {
-                    edgeFlags += MotionEvent.EDGE_TOP;
-                } else if (scaledY == display.getHeight() - 1.0f) {
-                    edgeFlags += MotionEvent.EDGE_BOTTOM;
+                if (action != MotionEvent.ACTION_DOWN) {
+                    if (scaledX <= 0) {
+                        edgeFlags += MotionEvent.EDGE_LEFT;
+                    } else if (scaledX >= dispW) {
+                        edgeFlags += MotionEvent.EDGE_RIGHT;
+                    }
+                    if (scaledY <= 0) {
+                        edgeFlags += MotionEvent.EDGE_TOP;
+                    } else if (scaledY >= dispH) {
+                        edgeFlags += MotionEvent.EDGE_BOTTOM;
+                    }
                 }
                 
             } else {
@@ -153,41 +191,25 @@
                 }
             }
             
-            changed = false;
-            if (down != lastDown) {
-                int action;
-                lastDown = down;
-                if (down) {
-                    action = MotionEvent.ACTION_DOWN;
-                    downTime = curTime;
-                } else {
-                    action = MotionEvent.ACTION_UP;
+            if (currentMove != null) {
+                if (false) Log.i("InputDevice", "Adding batch x=" + scaledX
+                        + " y=" + scaledY + " to " + currentMove);
+                currentMove.addBatch(curTime, scaledX, scaledY,
+                        scaledPressure, scaledSize, metaState);
+                if (WindowManagerPolicy.WATCH_POINTER) {
+                    Log.i("KeyInputQueue", "Updating: " + currentMove);
                 }
-                currentMove = null;
-                if (!isAbs) {
-                    x = y = 0;
-                }
-                return MotionEvent.obtainNano(downTime, curTime, curTimeNano, action,
-                        scaledX, scaledY, scaledPressure, scaledSize, metaState,
-                        xPrecision, yPrecision, device.id, edgeFlags);
-            } else {
-                if (currentMove != null) {
-                    if (false) Log.i("InputDevice", "Adding batch x=" + scaledX
-                            + " y=" + scaledY + " to " + currentMove);
-                    currentMove.addBatch(curTime, scaledX, scaledY,
-                            scaledPressure, scaledSize, metaState);
-                    if (WindowManagerPolicy.WATCH_POINTER) {
-                        Log.i("KeyInputQueue", "Updating: " + currentMove);
-                    }
-                    return null;
-                }
-                MotionEvent me = MotionEvent.obtainNano(downTime, curTime, curTimeNano,
-                        MotionEvent.ACTION_MOVE, scaledX, scaledY,
-                        scaledPressure, scaledSize, metaState,
-                        xPrecision, yPrecision, device.id, edgeFlags);
-                currentMove = me;
-                return me;
+                return null;
             }
+            
+            MotionEvent me = MotionEvent.obtainNano(downTime, curTime,
+                    curTimeNano, action, scaledX, scaledY,
+                    scaledPressure, scaledSize, metaState,
+                    xPrecision, yPrecision, device.id, edgeFlags);
+            if (action == MotionEvent.ACTION_MOVE) {
+                currentMove = me;
+            }
+            return me;
         }
     }
     
diff --git a/services/java/com/android/server/KeyInputQueue.java b/services/java/com/android/server/KeyInputQueue.java
index 78cdf8b..fd6b813 100644
--- a/services/java/com/android/server/KeyInputQueue.java
+++ b/services/java/com/android/server/KeyInputQueue.java
@@ -30,10 +30,20 @@
 import android.view.Surface;
 import android.view.WindowManagerPolicy;
 
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+
 public abstract class KeyInputQueue {
     static final String TAG = "KeyInputQueue";
 
-    SparseArray<InputDevice> mDevices = new SparseArray<InputDevice>();
+    static final boolean DEBUG_VIRTUAL_KEYS = false;
+    
+    final SparseArray<InputDevice> mDevices = new SparseArray<InputDevice>();
+    final ArrayList<VirtualKey> mVirtualKeys = new ArrayList<VirtualKey>();
     
     int mGlobalMetaState = 0;
     boolean mHaveGlobalMetaState = false;
@@ -44,10 +54,14 @@
     int mCacheCount;
 
     Display mDisplay = null;
+    int mDisplayWidth;
+    int mDisplayHeight;
     
     int mOrientation = Surface.ROTATION_0;
     int[] mKeyRotationMap = null;
     
+    VirtualKey mPressedVirtualKey = null;
+    
     PowerManager.WakeLock mWakeLock;
 
     static final int[] KEY_90_MAP = new int[] {
@@ -110,11 +124,106 @@
         QueuedEvent next;
     }
 
+    /**
+     * A key that exists as a part of the touch-screen, outside of the normal
+     * display area of the screen.
+     */
+    static class VirtualKey {
+        int scancode;
+        int centerx;
+        int centery;
+        int width;
+        int height;
+        
+        int hitLeft;
+        int hitTop;
+        int hitRight;
+        int hitBottom;
+        
+        InputDevice lastDevice;
+        int lastKeycode;
+        
+        boolean checkHit(int x, int y) {
+            return (x >= hitLeft && x <= hitRight
+                    && y >= hitTop && y <= hitBottom);
+        }
+        
+        void computeHitRect(InputDevice dev, int dw, int dh) {
+            if (dev == lastDevice) {
+                return;
+            }
+            
+            if (DEBUG_VIRTUAL_KEYS) Log.v(TAG, "computeHitRect for " + scancode
+                    + ": dev=" + dev + " absX=" + dev.absX + " absY=" + dev.absY);
+            
+            lastDevice = dev;
+            
+            int minx = dev.absX.minValue;
+            int maxx = dev.absX.maxValue;
+            
+            int halfw = width/2;
+            int left = centerx - halfw;
+            int right = centerx + halfw;
+            hitLeft = minx + ((left*maxx-minx)/dw);
+            hitRight = minx + ((right*maxx-minx)/dw);
+            
+            int miny = dev.absY.minValue;
+            int maxy = dev.absY.maxValue;
+            
+            int halfh = height/2;
+            int top = centery - halfh;
+            int bottom = centery + halfh;
+            hitTop = miny + ((top*maxy-miny)/dh);
+            hitBottom = miny + ((bottom*maxy-miny)/dh);
+        }
+    }
+    
     KeyInputQueue(Context context) {
         if (MEASURE_LATENCY) {
             lt = new LatencyTimer(100, 1000);
         }
 
+        try {
+            FileInputStream fis = new FileInputStream(
+                    "/sys/board_properties/virtualkeys.synaptics-rmi-touchscreen");
+            InputStreamReader isr = new InputStreamReader(fis);
+            BufferedReader br = new BufferedReader(isr);
+            String str = br.readLine();
+            if (str != null) {
+                String[] it = str.split(":");
+                if (DEBUG_VIRTUAL_KEYS) Log.v(TAG, "***** VIRTUAL KEYS: " + it);
+                final int N = it.length-6;
+                for (int i=0; i<=N; i+=6) {
+                    if (!"0x01".equals(it[i])) {
+                        Log.w(TAG, "Unknown virtual key type at elem #" + i
+                                + ": " + it[i]);
+                        continue;
+                    }
+                    try {
+                        VirtualKey sb = new VirtualKey();
+                        sb.scancode = Integer.parseInt(it[i+1]);
+                        sb.centerx = Integer.parseInt(it[i+2]);
+                        sb.centery = Integer.parseInt(it[i+3]);
+                        sb.width = Integer.parseInt(it[i+4]);
+                        sb.height = Integer.parseInt(it[i+5]);
+                        if (DEBUG_VIRTUAL_KEYS) Log.v(TAG, "Virtual key "
+                                + sb.scancode + ": center=" + sb.centerx + ","
+                                + sb.centery + " size=" + sb.width + "x"
+                                + sb.height);
+                        mVirtualKeys.add(sb);
+                    } catch (NumberFormatException e) {
+                        Log.w(TAG, "Bad number at region " + i + " in: "
+                                + str, e);
+                    }
+                }
+            }
+            br.close();
+        } catch (FileNotFoundException e) {
+            Log.i(TAG, "No virtual keys found");
+        } catch (IOException e) {
+            Log.w(TAG, "Error reading virtual keys", e);
+        }
+        
         PowerManager pm = (PowerManager)context.getSystemService(
                                                         Context.POWER_SERVICE);
         mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
@@ -131,6 +240,12 @@
 
     public void setDisplay(Display display) {
         mDisplay = display;
+        
+        // We assume at this point that the display dimensions reflect the
+        // natural, unrotated display.  We will perform hit tests for soft
+        // buttons based on that display.
+        mDisplayWidth = display.getWidth();
+        mDisplayHeight = display.getHeight();
     }
     
     public void getInputConfiguration(Configuration config) {
@@ -173,6 +288,7 @@
     public static native int getScancodeState(int deviceId, int sw);
     public static native int getKeycodeState(int sw);
     public static native int getKeycodeState(int deviceId, int sw);
+    public static native int scancodeToKeycode(int deviceId, int scancode);
     public static native boolean hasKeys(int[] keycodes, boolean[] keyExists);
     
     public static KeyEvent newKeyEvent(InputDevice device, long downTime,
@@ -339,36 +455,127 @@
                                 }
                                 
                                 MotionEvent me;
-                                me = di.mAbs.generateMotion(di, curTime, curTimeNano, true,
-                                        mDisplay, mOrientation, mGlobalMetaState);
-                                if (false) Log.v(TAG, "Absolute: x=" + di.mAbs.x
-                                        + " y=" + di.mAbs.y + " ev=" + me);
-                                if (me != null) {
-                                    if (WindowManagerPolicy.WATCH_POINTER) {
-                                        Log.i(TAG, "Enqueueing: " + me);
+                                
+                                InputDevice.MotionState ms = di.mAbs;
+                                if (ms.changed) {
+                                    ms.changed = false;
+                                    
+                                    boolean doMotion = true;
+                                    
+                                    // Look for virtual buttons.
+                                    VirtualKey vk = mPressedVirtualKey;
+                                    if (vk != null) {
+                                        doMotion = false;
+                                        if (!ms.down) {
+                                            mPressedVirtualKey = null;
+                                            ms.lastDown = ms.down;
+                                            if (DEBUG_VIRTUAL_KEYS) Log.v(TAG,
+                                                    "Generate key up for: " + vk.scancode);
+                                            addLocked(di, curTimeNano, ev.flags,
+                                                    RawInputEvent.CLASS_KEYBOARD,
+                                                    newKeyEvent(di, di.mDownTime,
+                                                            curTime, false,
+                                                            vk.lastKeycode,
+                                                            0, vk.scancode, 0));
+                                        }
+                                    } else if (ms.down && !ms.lastDown) {
+                                        vk = findSoftButton(di);
+                                        if (vk != null) {
+                                            doMotion = false;
+                                            mPressedVirtualKey = vk;
+                                            vk.lastKeycode = scancodeToKeycode(
+                                                    di.id, vk.scancode);
+                                            ms.lastDown = ms.down;
+                                            di.mDownTime = curTime;
+                                            if (DEBUG_VIRTUAL_KEYS) Log.v(TAG,
+                                                    "Generate key down for: " + vk.scancode
+                                                    + " (keycode=" + vk.lastKeycode + ")");
+                                            addLocked(di, curTimeNano, ev.flags,
+                                                    RawInputEvent.CLASS_KEYBOARD,
+                                                    newKeyEvent(di, di.mDownTime,
+                                                            curTime, true,
+                                                            vk.lastKeycode, 0,
+                                                            vk.scancode, 0));
+                                        }
                                     }
-                                    addLocked(di, curTimeNano, ev.flags,
-                                            RawInputEvent.CLASS_TOUCHSCREEN, me);
+                                    
+                                    if (doMotion) {
+                                        me = ms.generateMotion(di, curTime,
+                                                curTimeNano, true, mDisplay,
+                                                mOrientation, mGlobalMetaState);
+                                        if (false) Log.v(TAG, "Absolute: x=" + di.mAbs.x
+                                                + " y=" + di.mAbs.y + " ev=" + me);
+                                        if (me != null) {
+                                            if (WindowManagerPolicy.WATCH_POINTER) {
+                                                Log.i(TAG, "Enqueueing: " + me);
+                                            }
+                                            addLocked(di, curTimeNano, ev.flags,
+                                                    RawInputEvent.CLASS_TOUCHSCREEN, me);
+                                        }
+                                    }
                                 }
-                                me = di.mRel.generateMotion(di, curTime, curTimeNano, false,
-                                        mDisplay, mOrientation, mGlobalMetaState);
-                                if (false) Log.v(TAG, "Relative: x=" + di.mRel.x
-                                        + " y=" + di.mRel.y + " ev=" + me);
-                                if (me != null) {
-                                    addLocked(di, curTimeNano, ev.flags,
-                                            RawInputEvent.CLASS_TRACKBALL, me);
+                                
+                                ms = di.mRel;
+                                if (ms.changed) {
+                                    ms.changed = false;
+                                    
+                                    me = ms.generateMotion(di, curTime,
+                                            curTimeNano, false, mDisplay,
+                                            mOrientation, mGlobalMetaState);
+                                    if (false) Log.v(TAG, "Relative: x=" + di.mRel.x
+                                            + " y=" + di.mRel.y + " ev=" + me);
+                                    if (me != null) {
+                                        addLocked(di, curTimeNano, ev.flags,
+                                                RawInputEvent.CLASS_TRACKBALL, me);
+                                    }
                                 }
                             }
                         }
                     }
                 }
-            }
-            catch (RuntimeException exc) {
+                
+            } catch (RuntimeException exc) {
                 Log.e(TAG, "InputReaderThread uncaught exception", exc);
             }
         }
     };
 
+    private VirtualKey findSoftButton(InputDevice dev) {
+        final int N = mVirtualKeys.size();
+        if (N <= 0) {
+            return null;
+        }
+        
+        final InputDevice.AbsoluteInfo absx = dev.absX;
+        final InputDevice.AbsoluteInfo absy = dev.absY;
+        final InputDevice.MotionState absm = dev.mAbs;
+        if (absx == null || absy == null || absm == null) {
+            return null;
+        }
+        
+        if (absm.x >= absx.minValue && absm.x <= absx.maxValue
+                && absm.y >= absy.minValue && absm.y <= absy.maxValue) {
+            if (DEBUG_VIRTUAL_KEYS) Log.v(TAG, "Input (" + absm.x
+                    + "," + absm.y + ") inside of display");
+            return null;
+        }
+        
+        for (int i=0; i<N; i++) {
+            VirtualKey sb = mVirtualKeys.get(i);
+            sb.computeHitRect(dev, mDisplayWidth, mDisplayHeight);
+            if (DEBUG_VIRTUAL_KEYS) Log.v(TAG, "Hit test (" + absm.x + ","
+                    + absm.y + ") in code " + sb.scancode + " - (" + sb.hitLeft
+                    + "," + sb.hitTop + ")-(" + sb.hitRight + ","
+                    + sb.hitBottom + ")");
+            if (sb.checkHit(absm.x, absm.y)) {
+                if (DEBUG_VIRTUAL_KEYS) Log.v(TAG, "Hit!");
+                return sb;
+            }
+        }
+        
+        return null;
+    }
+    
     /**
      * Returns a new meta state for the given keys and old state.
      */
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index a561d11..67e8cf3 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -171,6 +171,7 @@
     WifiService(Context context, WifiStateTracker tracker) {
         mContext = context;
         mWifiStateTracker = tracker;
+        mWifiStateTracker.enableRssiPolling(true);
         mBatteryStats = BatteryStatsService.getService();
         
         mScanResultCache = new LinkedHashMap<String, ScanResult>(
@@ -1367,9 +1368,11 @@
                 mAlarmManager.cancel(mIdleIntent);
                 mDeviceIdle = false;
                 mScreenOff = false;
+                mWifiStateTracker.enableRssiPolling(true);
             } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
                 Log.d(TAG, "ACTION_SCREEN_OFF");
                 mScreenOff = true;
+                mWifiStateTracker.enableRssiPolling(false);
                 /*
                  * Set a timer to put Wi-Fi to sleep, but only if the screen is off
                  * AND the "stay on while plugged in" setting doesn't match the
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 25aff5c..e41524e 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -24,6 +24,7 @@
 import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
 import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
 import static android.view.WindowManager.LayoutParams.FLAG_BLUR_BEHIND;
+import static android.view.WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW;
 import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND;
 import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
 import static android.view.WindowManager.LayoutParams.FLAG_SYSTEM_ERROR;
@@ -102,6 +103,7 @@
 import android.view.WindowManagerImpl;
 import android.view.WindowManagerPolicy;
 import android.view.WindowManager.LayoutParams;
+import android.view.animation.AccelerateInterpolator;
 import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
 import android.view.animation.Transformation;
@@ -175,6 +177,11 @@
      */
     static final int DEFAULT_DIM_DURATION = 200;
 
+    /** Amount of time (in milliseconds) to animate the fade-in-out transition for
+     * compatible windows.
+     */
+    static final int DEFAULT_FADE_IN_OUT_DURATION = 400;
+
     /** Adjustment to time to perform a dim, to make it more dramatic.
      */
     static final int DIM_DURATION_MULTIPLIER = 6;
@@ -328,12 +335,7 @@
     IInputMethodManager mInputMethodManager;
 
     SurfaceSession mFxSession;
-    Surface mDimSurface;
-    boolean mDimShown;
-    float mDimCurrentAlpha;
-    float mDimTargetAlpha;
-    float mDimDeltaPerMs;
-    long mLastDimAnimTime;
+    private DimAnimator mDimAnimator = null;
     Surface mBlurSurface;
     boolean mBlurShown;
 
@@ -1861,44 +1863,51 @@
         // artifacts when we unfreeze the display if some different animation
         // is running.
         if (!mDisplayFrozen) {
-            int animAttr = 0;
-            switch (transit) {
-                case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
-                    animAttr = enter
-                            ? com.android.internal.R.styleable.WindowAnimation_activityOpenEnterAnimation
-                            : com.android.internal.R.styleable.WindowAnimation_activityOpenExitAnimation;
-                    break;
-                case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
-                    animAttr = enter
-                            ? com.android.internal.R.styleable.WindowAnimation_activityCloseEnterAnimation
-                            : com.android.internal.R.styleable.WindowAnimation_activityCloseExitAnimation;
-                    break;
-                case WindowManagerPolicy.TRANSIT_TASK_OPEN:
-                    animAttr = enter
-                            ? com.android.internal.R.styleable.WindowAnimation_taskOpenEnterAnimation
-                            : com.android.internal.R.styleable.WindowAnimation_taskOpenExitAnimation;
-                    break;
-                case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
-                    animAttr = enter
-                            ? com.android.internal.R.styleable.WindowAnimation_taskCloseEnterAnimation
-                            : com.android.internal.R.styleable.WindowAnimation_taskCloseExitAnimation;
-                    break;
-                case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
-                    animAttr = enter
-                            ? com.android.internal.R.styleable.WindowAnimation_taskToFrontEnterAnimation
-                            : com.android.internal.R.styleable.WindowAnimation_taskToFrontExitAnimation;
-                    break;
-                case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
-                    animAttr = enter
-                            ? com.android.internal.R.styleable.WindowAnimation_taskToBackEnterAnimation
-                            : com.android.internal.R.styleable.WindowAnimation_taskToBackExitAnimation;
-                    break;
+            Animation a;
+            if ((lp.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
+                a = new FadeInOutAnimation(enter);
+                if (DEBUG_ANIM) Log.v(TAG,
+                        "applying FadeInOutAnimation for a window in compatibility mode");
+            } else {
+                int animAttr = 0;
+                switch (transit) {
+                    case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
+                        animAttr = enter
+                                ? com.android.internal.R.styleable.WindowAnimation_activityOpenEnterAnimation
+                                : com.android.internal.R.styleable.WindowAnimation_activityOpenExitAnimation;
+                        break;
+                    case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
+                        animAttr = enter
+                                ? com.android.internal.R.styleable.WindowAnimation_activityCloseEnterAnimation
+                                : com.android.internal.R.styleable.WindowAnimation_activityCloseExitAnimation;
+                        break;
+                    case WindowManagerPolicy.TRANSIT_TASK_OPEN:
+                        animAttr = enter
+                                ? com.android.internal.R.styleable.WindowAnimation_taskOpenEnterAnimation
+                                : com.android.internal.R.styleable.WindowAnimation_taskOpenExitAnimation;
+                        break;
+                    case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
+                        animAttr = enter
+                                ? com.android.internal.R.styleable.WindowAnimation_taskCloseEnterAnimation
+                                : com.android.internal.R.styleable.WindowAnimation_taskCloseExitAnimation;
+                        break;
+                    case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
+                        animAttr = enter
+                                ? com.android.internal.R.styleable.WindowAnimation_taskToFrontEnterAnimation
+                                : com.android.internal.R.styleable.WindowAnimation_taskToFrontExitAnimation;
+                        break;
+                    case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
+                        animAttr = enter
+                        ? com.android.internal.R.styleable.WindowAnimation_taskToBackEnterAnimation
+                                : com.android.internal.R.styleable.WindowAnimation_taskToBackExitAnimation;
+                        break;
+                }
+                a = loadAnimation(lp, animAttr);
+                if (DEBUG_ANIM) Log.v(TAG, "applyAnimation: wtoken=" + wtoken
+                        + " anim=" + a
+                        + " animAttr=0x" + Integer.toHexString(animAttr)
+                        + " transit=" + transit);
             }
-            Animation a = loadAnimation(lp, animAttr);
-            if (DEBUG_ANIM) Log.v(TAG, "applyAnimation: wtoken=" + wtoken
-                    + " anim=" + a
-                    + " animAttr=0x" + Integer.toHexString(animAttr)
-                    + " transit=" + transit);
             if (a != null) {
                 if (DEBUG_ANIM) {
                     RuntimeException e = new RuntimeException();
@@ -5909,7 +5918,7 @@
             final Rect display = mDisplayFrame;
             display.set(df);
 
-            if ((mAttrs.flags & WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW) != 0) {
+            if ((mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
                 container.intersect(mCompatibleScreenFrame);
                 display.intersect(mCompatibleScreenFrame);
             }
@@ -6647,10 +6656,16 @@
         boolean needsBackgroundFiller(int screenWidth, int screenHeight) {
             return
                  // only if the application is requesting compatible window
-                 (mAttrs.flags & mAttrs.FLAG_COMPATIBLE_WINDOW) != 0 &&
+                 (mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0 &&
+                 // only if it's visible
+                 mHasDrawn && mViewVisibility == View.VISIBLE &&
                  // and only if the application wanted to fill the screen
                  mAttrs.width == mAttrs.FILL_PARENT &&
                  mAttrs.height == mAttrs.FILL_PARENT &&
+                 // and only if the window is not hidden
+                 mFrame.left == mCompatibleScreenFrame.left &&
+                 // and starting window do not need background filler
+                 mAttrs.type != mAttrs.TYPE_APPLICATION_STARTING &&
                  // and only if the screen is bigger
                  ((mFrame.right - mFrame.right) < screenWidth ||
                          (mFrame.bottom - mFrame.top) < screenHeight);
@@ -8457,7 +8472,7 @@
                         obscured = true;
                     } else if (opaqueDrawn && w.needsBackgroundFiller(dw, dh)) {
                         if (SHOW_TRANSACTIONS) Log.d(TAG, "showing background filler");
-                                                // This window is in compatibility mode, and needs background filler. 
+                        // This window is in compatibility mode, and needs background filler.
                         obscured = true;
                         if (mBackgroundFillerSurface == null) {
                             try {
@@ -8491,56 +8506,12 @@
                             if (!dimming) {
                                 //Log.i(TAG, "DIM BEHIND: " + w);
                                 dimming = true;
-                                mDimShown = true;
-                                if (mDimSurface == null) {
-                                    if (SHOW_TRANSACTIONS) Log.i(TAG, "  DIM "
-                                            + mDimSurface + ": CREATE");
-                                    try {
-                                        mDimSurface = new Surface(mFxSession, 0,
-                                                -1, 16, 16,
-                                                PixelFormat.OPAQUE,
-                                                Surface.FX_SURFACE_DIM);
-                                    } catch (Exception e) {
-                                        Log.e(TAG, "Exception creating Dim surface", e);
-                                    }
+                                if (mDimAnimator == null) {
+                                    mDimAnimator = new DimAnimator(mFxSession);
                                 }
-                                if (SHOW_TRANSACTIONS) Log.i(TAG, "  DIM "
-                                        + mDimSurface + ": SHOW pos=(0,0) (" +
-                                        dw + "x" + dh + "), layer=" + (w.mAnimLayer-1));
-                                if (mDimSurface != null) {
-                                    try {
-                                        mDimSurface.setPosition(0, 0);
-                                        mDimSurface.setSize(dw, dh);
-                                        mDimSurface.show();
-                                    } catch (RuntimeException e) {
-                                        Log.w(TAG, "Failure showing dim surface", e);
-                                    }
-                                }
+                                mDimAnimator.show(dw, dh);
                             }
-                            mDimSurface.setLayer(w.mAnimLayer-1);
-                            final float target = w.mExiting ? 0 : attrs.dimAmount;
-                            if (mDimTargetAlpha != target) {
-                                // If the desired dim level has changed, then
-                                // start an animation to it.
-                                mLastDimAnimTime = currentTime;
-                                long duration = (w.mAnimating && w.mAnimation != null)
-                                        ? w.mAnimation.computeDurationHint()
-                                        : DEFAULT_DIM_DURATION;
-                                if (target > mDimTargetAlpha) {
-                                    // This is happening behind the activity UI,
-                                    // so we can make it run a little longer to
-                                    // give a stronger impression without disrupting
-                                    // the user.
-                                    duration *= DIM_DURATION_MULTIPLIER;
-                                }
-                                if (duration < 1) {
-                                    // Don't divide by zero
-                                    duration = 1;
-                                }
-                                mDimTargetAlpha = target;
-                                mDimDeltaPerMs = (mDimTargetAlpha-mDimCurrentAlpha)
-                                        / duration;
-                            }
+                            mDimAnimator.updateParameters(w, currentTime);
                         }
                         if ((attrFlags&FLAG_BLUR_BEHIND) != 0) {
                             if (!blurring) {
@@ -8588,58 +8559,8 @@
                 }
             }
 
-            if (!dimming && mDimShown) {
-                // Time to hide the dim surface...  start fading.
-                if (mDimTargetAlpha != 0) {
-                    mLastDimAnimTime = currentTime;
-                    mDimTargetAlpha = 0;
-                    mDimDeltaPerMs = (-mDimCurrentAlpha) / DEFAULT_DIM_DURATION;
-                }
-            }
-
-            if (mDimShown && mLastDimAnimTime != 0) {
-                mDimCurrentAlpha += mDimDeltaPerMs
-                        * (currentTime-mLastDimAnimTime);
-                boolean more = true;
-                if (mDisplayFrozen) {
-                    // If the display is frozen, there is no reason to animate.
-                    more = false;
-                } else if (mDimDeltaPerMs > 0) {
-                    if (mDimCurrentAlpha > mDimTargetAlpha) {
-                        more = false;
-                    }
-                } else if (mDimDeltaPerMs < 0) {
-                    if (mDimCurrentAlpha < mDimTargetAlpha) {
-                        more = false;
-                    }
-                } else {
-                    more = false;
-                }
-
-                // Do we need to continue animating?
-                if (more) {
-                    if (SHOW_TRANSACTIONS) Log.i(TAG, "  DIM "
-                            + mDimSurface + ": alpha=" + mDimCurrentAlpha);
-                    mLastDimAnimTime = currentTime;
-                    mDimSurface.setAlpha(mDimCurrentAlpha);
-                    animating = true;
-                } else {
-                    mDimCurrentAlpha = mDimTargetAlpha;
-                    mLastDimAnimTime = 0;
-                    if (SHOW_TRANSACTIONS) Log.i(TAG, "  DIM "
-                            + mDimSurface + ": final alpha=" + mDimCurrentAlpha);
-                    mDimSurface.setAlpha(mDimCurrentAlpha);
-                    if (!dimming) {
-                        if (SHOW_TRANSACTIONS) Log.i(TAG, "  DIM " + mDimSurface
-                                + ": HIDE");
-                        try {
-                            mDimSurface.hide();
-                        } catch (RuntimeException e) {
-                            Log.w(TAG, "Illegal argument exception hiding dim surface");
-                        }
-                        mDimShown = false;
-                    }
-                }
+            if (mDimAnimator != null && mDimAnimator.mDimShown) {
+                animating |= mDimAnimator.updateSurface(dimming, currentTime, mDisplayFrozen);
             }
 
             if (!blurring && mBlurShown) {
@@ -9182,11 +9103,11 @@
                     pw.print(" mDisplayEnabled="); pw.println(mDisplayEnabled);
             pw.print("  mLayoutNeeded="); pw.print(mLayoutNeeded);
                     pw.print(" mBlurShown="); pw.println(mBlurShown);
-            pw.print("  mDimShown="); pw.print(mDimShown);
-                    pw.print(" current="); pw.print(mDimCurrentAlpha);
-                    pw.print(" target="); pw.print(mDimTargetAlpha);
-                    pw.print(" delta="); pw.print(mDimDeltaPerMs);
-                    pw.print(" lastAnimTime="); pw.println(mLastDimAnimTime);
+            if (mDimAnimator != null) {
+                mDimAnimator.printTo(pw);
+            } else {
+                pw.print( "  no DimAnimator ");
+            }
             pw.print("  mInputMethodAnimLayerAdjustment=");
                     pw.println(mInputMethodAnimLayerAdjustment);
             pw.print("  mDisplayFrozen="); pw.print(mDisplayFrozen);
@@ -9227,4 +9148,194 @@
         synchronized (mKeyguardDisabled) { }
         synchronized (mKeyWaiter) { }
     }
+
+    /**
+     * DimAnimator class that controls the dim animation. This holds the surface and
+     * all state used for dim animation. 
+     */
+    private static class DimAnimator {
+        Surface mDimSurface;
+        boolean mDimShown = false;
+        float mDimCurrentAlpha;
+        float mDimTargetAlpha;
+        float mDimDeltaPerMs;
+        long mLastDimAnimTime;
+
+        DimAnimator (SurfaceSession session) {
+            if (mDimSurface == null) {
+                if (SHOW_TRANSACTIONS) Log.i(TAG, "  DIM "
+                        + mDimSurface + ": CREATE");
+                try {
+                    mDimSurface = new Surface(session, 0, -1, 16, 16, PixelFormat.OPAQUE,
+                            Surface.FX_SURFACE_DIM);
+                } catch (Exception e) {
+                    Log.e(TAG, "Exception creating Dim surface", e);
+                }
+            }
+        }
+
+        /**
+         * Show the dim surface.
+         */
+        void show(int dw, int dh) {
+            if (SHOW_TRANSACTIONS) Log.i(TAG, "  DIM " + mDimSurface + ": SHOW pos=(0,0) (" +
+                    dw + "x" + dh + ")");
+            mDimShown = true;
+            try {
+                mDimSurface.setPosition(0, 0);
+                mDimSurface.setSize(dw, dh);
+                mDimSurface.show();
+            } catch (RuntimeException e) {
+                Log.w(TAG, "Failure showing dim surface", e);
+            }
+        }
+
+        /**
+         * Set's the dim surface's layer and update dim parameters that will be used in
+         * {@link updateSurface} after all windows are examined.
+         */
+        void updateParameters(WindowState w, long currentTime) {
+            mDimSurface.setLayer(w.mAnimLayer-1);
+
+            final float target = w.mExiting ? 0 : w.mAttrs.dimAmount;
+            if (SHOW_TRANSACTIONS) Log.i(TAG, "layer=" + (w.mAnimLayer-1) + ", target=" + target);
+            if (mDimTargetAlpha != target) {
+                // If the desired dim level has changed, then
+                // start an animation to it.
+                mLastDimAnimTime = currentTime;
+                long duration = (w.mAnimating && w.mAnimation != null)
+                        ? w.mAnimation.computeDurationHint()
+                        : DEFAULT_DIM_DURATION;
+                if (target > mDimTargetAlpha) {
+                    // This is happening behind the activity UI,
+                    // so we can make it run a little longer to
+                    // give a stronger impression without disrupting
+                    // the user.
+                    duration *= DIM_DURATION_MULTIPLIER;
+                }
+                if (duration < 1) {
+                    // Don't divide by zero
+                    duration = 1;
+                }
+                mDimTargetAlpha = target;
+                mDimDeltaPerMs = (mDimTargetAlpha-mDimCurrentAlpha) / duration;
+            }
+        }
+            
+        /**
+         * Updating the surface's alpha. Returns true if the animation continues, or returns
+         * false when the animation is finished and the dim surface is hidden.
+         */
+        boolean updateSurface(boolean dimming, long currentTime, boolean displayFrozen) {
+            if (!dimming) {
+                if (mDimTargetAlpha != 0) {
+                    mLastDimAnimTime = currentTime;
+                    mDimTargetAlpha = 0;
+                    mDimDeltaPerMs = (-mDimCurrentAlpha) / DEFAULT_DIM_DURATION;
+                }
+            }
+            
+            boolean animating = false;
+            if (mLastDimAnimTime != 0) {
+                mDimCurrentAlpha += mDimDeltaPerMs
+                        * (currentTime-mLastDimAnimTime);
+                boolean more = true;
+                if (displayFrozen) {
+                    // If the display is frozen, there is no reason to animate.
+                    more = false;
+                } else if (mDimDeltaPerMs > 0) {
+                    if (mDimCurrentAlpha > mDimTargetAlpha) {
+                        more = false;
+                    }
+                } else if (mDimDeltaPerMs < 0) {
+                    if (mDimCurrentAlpha < mDimTargetAlpha) {
+                        more = false;
+                    }
+                } else {
+                    more = false;
+                }
+
+                // Do we need to continue animating?
+                if (more) {
+                    if (SHOW_TRANSACTIONS) Log.i(TAG, "  DIM "
+                            + mDimSurface + ": alpha=" + mDimCurrentAlpha);
+                    mLastDimAnimTime = currentTime;
+                    mDimSurface.setAlpha(mDimCurrentAlpha);
+                    animating = true;
+                } else {
+                    mDimCurrentAlpha = mDimTargetAlpha;
+                    mLastDimAnimTime = 0;
+                    if (SHOW_TRANSACTIONS) Log.i(TAG, "  DIM "
+                            + mDimSurface + ": final alpha=" + mDimCurrentAlpha);
+                    mDimSurface.setAlpha(mDimCurrentAlpha);
+                    if (!dimming) {
+                        if (SHOW_TRANSACTIONS) Log.i(TAG, "  DIM " + mDimSurface
+                                + ": HIDE");
+                        try {
+                            mDimSurface.hide();
+                        } catch (RuntimeException e) {
+                            Log.w(TAG, "Illegal argument exception hiding dim surface");
+                        }
+                        mDimShown = false;
+                    }
+                }
+            }
+            return animating;
+        }
+
+        public void printTo(PrintWriter pw) {
+            pw.print("  mDimShown="); pw.print(mDimShown);
+            pw.print(" current="); pw.print(mDimCurrentAlpha);
+            pw.print(" target="); pw.print(mDimTargetAlpha);
+            pw.print(" delta="); pw.print(mDimDeltaPerMs);
+            pw.print(" lastAnimTime="); pw.println(mLastDimAnimTime);
+        }
+    }
+
+    /**
+     * Animation that fade in after 0.5 interpolate time, or fade out in reverse order.
+     * This is used for opening/closing transition for apps in compatible mode.
+     */
+    private static class FadeInOutAnimation extends Animation {
+        int mWidth;
+        boolean mFadeIn;
+
+        public FadeInOutAnimation(boolean fadeIn) {
+            setInterpolator(new AccelerateInterpolator());
+            setDuration(DEFAULT_FADE_IN_OUT_DURATION);
+            mFadeIn = fadeIn;
+        }
+
+        @Override
+        protected void applyTransformation(float interpolatedTime, Transformation t) {
+            float x = interpolatedTime;
+            if (!mFadeIn) {
+                x = 1.0f - x; // reverse the interpolation for fade out
+            }
+            if (x < 0.5) {
+                // move the window out of the screen.
+                t.getMatrix().setTranslate(mWidth, 0);
+            } else {
+                t.getMatrix().setTranslate(0, 0);// show
+                t.setAlpha((x - 0.5f) * 2);
+            }
+        }
+
+        @Override
+        public void initialize(int width, int height, int parentWidth, int parentHeight) {
+            // width is the screen width {@see AppWindowToken#stepAnimatinoLocked}
+            mWidth = width;
+        }
+        
+        @Override
+        public boolean willChangeTransformationMatrix() {
+            return true;
+        }
+
+        @Override
+        public boolean willChangeBounds() {
+            return true;
+        }
+    }
 }
+
diff --git a/services/jni/com_android_server_KeyInputQueue.cpp b/services/jni/com_android_server_KeyInputQueue.cpp
index 63830d5..afca1f7 100644
--- a/services/jni/com_android_server_KeyInputQueue.cpp
+++ b/services/jni/com_android_server_KeyInputQueue.cpp
@@ -205,6 +205,23 @@
     return st;
 }
 
+static jint
+android_server_KeyInputQueue_scancodeToKeycode(JNIEnv* env, jobject clazz,
+                                            jint deviceId, jint scancode)
+{
+    jint res = 0;
+    gLock.lock();
+    if (gHub != NULL) {
+        int32_t keycode;
+        uint32_t flags;
+        gHub->scancodeToKeycode(deviceId, scancode, &keycode, &flags);
+        res = keycode;
+    }
+    gLock.unlock();
+    
+    return res;
+}
+
 static jboolean
 android_server_KeyInputQueue_hasKeys(JNIEnv* env, jobject clazz,
                                      jintArray keyCodes, jbooleanArray outFlags)
@@ -254,6 +271,8 @@
         (void*) android_server_KeyInputQueue_getKeycodeStateDevice },
     { "hasKeys", "([I[Z)Z",
         (void*) android_server_KeyInputQueue_hasKeys },
+    { "scancodeToKeycode", "(II)I",
+        (void*) android_server_KeyInputQueue_scancodeToKeycode },
 };
 
 int register_android_server_KeyInputQueue(JNIEnv* env)
diff --git a/telephony/java/com/android/internal/telephony/Phone.java b/telephony/java/com/android/internal/telephony/Phone.java
index 7f2b849..0bb2df1 100644
--- a/telephony/java/com/android/internal/telephony/Phone.java
+++ b/telephony/java/com/android/internal/telephony/Phone.java
@@ -22,6 +22,7 @@
 import android.os.Message;
 import android.preference.PreferenceManager;
 import android.telephony.CellLocation;
+import android.telephony.PhoneStateListener;
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
 
@@ -260,8 +261,8 @@
 
     /**
      * Get current coarse-grained voice call state.
-     * Use {@link #registerForPhoneStateChanged(Handler, int, Object)
-     * registerForPhoneStateChanged()} for change notification. <p>
+     * Use {@link #registerForPreciseCallStateChanged(Handler, int, Object)
+     * registerForPreciseCallStateChanged()} for change notification. <p>
      * If the phone has an active call and call waiting occurs,
      * then the phone state is RINGING not OFFHOOK
      * <strong>Note:</strong>
@@ -315,18 +316,21 @@
     void unregisterForUnknownConnection(Handler h);
 
     /**
-     * Notifies when any aspect of the voice call state changes.
+     * Register for getting notifications for change in the Call State {@link Call.State}
+     * This is called PreciseCallState because the call state is more precise than the
+     * {@link Phone.State} which can be obtained using the {@link PhoneStateListener}
+     *
      * Resulting events will have an AsyncResult in <code>Message.obj</code>.
      * AsyncResult.userData will be set to the obj argument here.
      * The <em>h</em> parameter is held only by a weak reference.
      */
-    void registerForPhoneStateChanged(Handler h, int what, Object obj);
+    void registerForPreciseCallStateChanged(Handler h, int what, Object obj);
 
     /**
      * Unregisters for voice call state change notifications.
      * Extraneous calls are tolerated silently.
      */
-    void unregisterForPhoneStateChanged(Handler h);
+    void unregisterForPreciseCallStateChanged(Handler h);
 
 
     /**
@@ -556,8 +560,8 @@
     /**
      * Answers a ringing or waiting call. Active calls, if any, go on hold.
      * Answering occurs asynchronously, and final notification occurs via
-     * {@link #registerForPhoneStateChanged(android.os.Handler, int,
-     * java.lang.Object) registerForPhoneStateChanged()}.
+     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
+     * java.lang.Object) registerForPreciseCallStateChanged()}.
      *
      * @exception CallStateException when no call is ringing or waiting
      */
@@ -567,8 +571,8 @@
      * Reject (ignore) a ringing call. In GSM, this means UDUB
      * (User Determined User Busy). Reject occurs asynchronously,
      * and final notification occurs via
-     * {@link #registerForPhoneStateChanged(android.os.Handler, int,
-     * java.lang.Object) registerForPhoneStateChanged()}.
+     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
+     * java.lang.Object) registerForPreciseCallStateChanged()}.
      *
      * @exception CallStateException when no call is ringing or waiting
      */
@@ -578,8 +582,8 @@
      * Places any active calls on hold, and makes any held calls
      *  active. Switch occurs asynchronously and may fail.
      * Final notification occurs via
-     * {@link #registerForPhoneStateChanged(android.os.Handler, int,
-     * java.lang.Object) registerForPhoneStateChanged()}.
+     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
+     * java.lang.Object) registerForPreciseCallStateChanged()}.
      *
      * @exception CallStateException if a call is ringing, waiting, or
      * dialing/alerting. In these cases, this operation may not be performed.
@@ -596,8 +600,8 @@
     /**
      * Conferences holding and active. Conference occurs asynchronously
      * and may fail. Final notification occurs via
-     * {@link #registerForPhoneStateChanged(android.os.Handler, int,
-     * java.lang.Object) registerForPhoneStateChanged()}.
+     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
+     * java.lang.Object) registerForPreciseCallStateChanged()}.
      *
      * @exception CallStateException if canConference() would return false.
      * In these cases, this operation may not be performed.
@@ -631,8 +635,8 @@
      * Connects the two calls and disconnects the subscriber from both calls
      * Explicit Call Transfer occurs asynchronously
      * and may fail. Final notification occurs via
-     * {@link #registerForPhoneStateChanged(android.os.Handler, int,
-     * java.lang.Object) registerForPhoneStateChanged()}.
+     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
+     * java.lang.Object) registerForPreciseCallStateChanged()}.
      *
      * @exception CallStateException if canTransfer() would return false.
      * In these cases, this operation may not be performed.
@@ -659,8 +663,8 @@
      * IDLE, ACTIVE, DIALING, ALERTING, or DISCONNECTED.
      *
      * State change notification is available via
-     * {@link #registerForPhoneStateChanged(android.os.Handler, int,
-     * java.lang.Object) registerForPhoneStateChanged()}.
+     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
+     * java.lang.Object) registerForPreciseCallStateChanged()}.
      */
     Call getForegroundCall();
 
@@ -676,8 +680,8 @@
      * IDLE, HOLDING or DISCONNECTED.
      *
      * State change notification is available via
-     * {@link #registerForPhoneStateChanged(android.os.Handler, int,
-     * java.lang.Object) registerForPhoneStateChanged()}.
+     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
+     * java.lang.Object) registerForPreciseCallStateChanged()}.
      */
     Call getBackgroundCall();
 
@@ -693,8 +697,8 @@
      * IDLE, INCOMING, WAITING or DISCONNECTED.
      *
      * State change notification is available via
-     * {@link #registerForPhoneStateChanged(android.os.Handler, int,
-     * java.lang.Object) registerForPhoneStateChanged()}.
+     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
+     * java.lang.Object) registerForPreciseCallStateChanged()}.
      */
     Call getRingingCall();
 
@@ -1067,8 +1071,8 @@
 
     /**
      * Gets current mute status. Use
-     * {@link #registerForPhoneStateChanged(android.os.Handler, int,
-     * java.lang.Object) registerForPhoneStateChanged()}
+     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
+     * java.lang.Object) registerForPreciseCallStateChanged()}
      * as a change notifcation, although presently phone state changed is not
      * fired when setMute() is called.
      *
diff --git a/telephony/java/com/android/internal/telephony/PhoneBase.java b/telephony/java/com/android/internal/telephony/PhoneBase.java
index 1509a6b..fbda221 100644
--- a/telephony/java/com/android/internal/telephony/PhoneBase.java
+++ b/telephony/java/com/android/internal/telephony/PhoneBase.java
@@ -119,7 +119,7 @@
     }
 
 
-    protected final RegistrantList mPhoneStateRegistrants
+    protected final RegistrantList mPreciseCallStateRegistrants
             = new RegistrantList();
 
     protected final RegistrantList mNewRingingConnectionRegistrants
@@ -221,25 +221,24 @@
     }
 
     // Inherited documentation suffices.
-    public void registerForPhoneStateChanged(Handler h, int what, Object obj) {
+    public void registerForPreciseCallStateChanged(Handler h, int what, Object obj) {
         checkCorrectThread(h);
 
-        mPhoneStateRegistrants.addUnique(h, what, obj);
+        mPreciseCallStateRegistrants.addUnique(h, what, obj);
     }
 
     // Inherited documentation suffices.
-    public void unregisterForPhoneStateChanged(Handler h) {
-        mPhoneStateRegistrants.remove(h);
+    public void unregisterForPreciseCallStateChanged(Handler h) {
+        mPreciseCallStateRegistrants.remove(h);
     }
 
     /**
-     * Notify registrants of a PhoneStateChanged.
      * Subclasses of Phone probably want to replace this with a
      * version scoped to their packages
      */
-    protected void notifyCallStateChangedP() {
+    protected void notifyPreciseCallStateChangedP() {
         AsyncResult ar = new AsyncResult(null, this, null);
-        mPhoneStateRegistrants.notifyRegistrants(ar);
+        mPreciseCallStateRegistrants.notifyRegistrants(ar);
     }
 
     // Inherited documentation suffices.
diff --git a/telephony/java/com/android/internal/telephony/PhoneProxy.java b/telephony/java/com/android/internal/telephony/PhoneProxy.java
index da00268..979f0cd 100644
--- a/telephony/java/com/android/internal/telephony/PhoneProxy.java
+++ b/telephony/java/com/android/internal/telephony/PhoneProxy.java
@@ -25,6 +25,7 @@
 import android.os.Message;
 import android.preference.PreferenceManager;
 import android.telephony.CellLocation;
+import android.telephony.PhoneStateListener;
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
 import android.util.Log;
@@ -210,12 +211,12 @@
         mActivePhone.unregisterForUnknownConnection(h);
     }
 
-    public void registerForPhoneStateChanged(Handler h, int what, Object obj) {
-        mActivePhone.registerForPhoneStateChanged(h, what, obj);
+    public void registerForPreciseCallStateChanged(Handler h, int what, Object obj) {
+        mActivePhone.registerForPreciseCallStateChanged(h, what, obj);
     }
 
-    public void unregisterForPhoneStateChanged(Handler h) {
-        mActivePhone.unregisterForPhoneStateChanged(h);
+    public void unregisterForPreciseCallStateChanged(Handler h) {
+        mActivePhone.unregisterForPreciseCallStateChanged(h);
     }
 
     public void registerForNewRingingConnection(Handler h, int what, Object obj) {
diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
index 0918a8c..1cd6e58 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
@@ -36,6 +36,7 @@
 import android.text.TextUtils;
 import android.util.Log;
 
+import com.android.internal.telephony.Call;
 import com.android.internal.telephony.CallStateException;
 import com.android.internal.telephony.CommandException;
 import com.android.internal.telephony.CommandsInterface;
@@ -783,19 +784,19 @@
     }
 
    /**
-     * Notify any interested party of a Phone state change.
+     * Notify any interested party of a Phone state change  {@link Phone.State}
      */
     /*package*/ void notifyPhoneStateChanged() {
         mNotifier.notifyPhoneState(this);
     }
 
     /**
-     * Notifies registrants (ie, activities in the Phone app) about
-     * changes to call state (including Phone and Connection changes).
+     * Notify registrants of a change in the call state. This notifies changes in {@link Call.State}
+     * Use this when changes in the precise call state are needed, else use notifyPhoneStateChanged.
      */
-    /*package*/ void notifyCallStateChanged() {
+    /*package*/ void notifyPreciseCallStateChanged() {
         /* we'd love it if this was package-scoped*/
-        super.notifyCallStateChangedP();
+        super.notifyPreciseCallStateChangedP();
     }
 
      void notifyServiceStateChanged(ServiceState ss) {
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
index ed2ea90..a5f9c11 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
@@ -222,7 +222,7 @@
         }
 
         updatePhoneState();
-        phone.notifyCallStateChanged();
+        phone.notifyPreciseCallStateChanged();
 
         return pendingMO;
     }
@@ -305,7 +305,7 @@
         internalClearDisconnected();
 
         updatePhoneState();
-        phone.notifyCallStateChanged();
+        phone.notifyPreciseCallStateChanged();
     }
 
     boolean
@@ -644,7 +644,7 @@
         }
 
         if (hasNonHangupStateChanged || newRinging != null) {
-            phone.notifyCallStateChanged();
+            phone.notifyPreciseCallStateChanged();
         }
 
         //dumpState();
@@ -678,7 +678,7 @@
             // the hangup reason is user ignoring or timing out. So conn.onDisconnect()
             // is not called here. Instead, conn.onLocalDisconnect() is called.
             conn.onLocalDisconnect();
-            phone.notifyCallStateChanged();
+            phone.notifyPreciseCallStateChanged();
             return;
         } else {
             try {
@@ -821,7 +821,7 @@
         // the status of the call is after a call waiting is answered,
         // 3 way call merged or a switch between calls.
         foregroundCall.setGeneric(true);
-        phone.notifyCallStateChanged();
+        phone.notifyPreciseCallStateChanged();
     }
 
     private Phone.SuppService getFailedService(int what) {
@@ -926,7 +926,7 @@
 
                 updatePhoneState();
 
-                phone.notifyCallStateChanged();
+                phone.notifyPreciseCallStateChanged();
                 droppedDuringPoll.clear();
             break;
 
diff --git a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
index d1e4b4f..ebbf096 100755
--- a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
@@ -51,6 +51,7 @@
 import static com.android.internal.telephony.CommandsInterface.SERVICE_CLASS_VOICE;
 import static com.android.internal.telephony.TelephonyProperties.PROPERTY_BASEBAND_VERSION;
 
+import com.android.internal.telephony.Call;
 import com.android.internal.telephony.CallForwardInfo;
 import com.android.internal.telephony.CallStateException;
 import com.android.internal.telephony.CommandsInterface;
@@ -378,20 +379,19 @@
     }
 
     /**
-     * Notify any interested party of a Phone state change.
+     * Notify any interested party of a Phone state change {@link Phone.State}
      */
     /*package*/ void notifyPhoneStateChanged() {
         mNotifier.notifyPhoneState(this);
     }
 
     /**
-     * Notifies registrants (ie, activities in the Phone app) about
-     * changes to call state (including Phone and Connection changes).
+     * Notify registrants of a change in the call state. This notifies changes in {@link Call.State}
+     * Use this when changes in the precise call state are needed, else use notifyPhoneStateChanged.
      */
-    /*package*/ void
-    notifyCallStateChanged() {
+    /*package*/ void notifyPreciseCallStateChanged() {
         /* we'd love it if this was package-scoped*/
-        super.notifyCallStateChangedP();
+        super.notifyPreciseCallStateChangedP();
     }
 
     /*package*/ void
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java
index 5c5090f..f3b7596 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java
@@ -212,7 +212,7 @@
         }
 
         updatePhoneState();
-        phone.notifyCallStateChanged();
+        phone.notifyPreciseCallStateChanged();
 
         return pendingMO;
     }
@@ -279,7 +279,7 @@
         internalClearDisconnected();
 
         updatePhoneState();
-        phone.notifyCallStateChanged();
+        phone.notifyPreciseCallStateChanged();
     }
 
     boolean
@@ -600,7 +600,7 @@
         }
 
         if (hasNonHangupStateChanged || newRinging != null) {
-            phone.notifyCallStateChanged();
+            phone.notifyPreciseCallStateChanged();
         }
 
         //dumpState();
@@ -883,7 +883,7 @@
 
                 updatePhoneState();
 
-                phone.notifyCallStateChanged();
+                phone.notifyPreciseCallStateChanged();
                 droppedDuringPoll.clear();
             break;
 
diff --git a/tests/AndroidTests/src/com/android/unit_tests/SearchablesTest.java b/tests/AndroidTests/src/com/android/unit_tests/SearchablesTest.java
index ecc8dfe..4e5f7a9 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/SearchablesTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/SearchablesTest.java
@@ -93,8 +93,8 @@
         Context appContext = si.getActivityContext(mContext);
         assertNotNull(appContext);
         MoreAsserts.assertNotEqual(appContext, mContext);
-        assertEquals("Android Search", appContext.getString(si.getHintId()));
-        assertEquals("Google", appContext.getString(si.getLabelId()));
+        assertEquals("Quick Search Box", appContext.getString(si.getHintId()));
+        assertEquals("Quick Search Box", appContext.getString(si.getLabelId()));
     }
     
     /**
diff --git a/tests/CoreTests/android/core/RequestAPITest.java b/tests/CoreTests/android/core/RequestAPITest.java
index d89f5ae..94eb23e 100644
--- a/tests/CoreTests/android/core/RequestAPITest.java
+++ b/tests/CoreTests/android/core/RequestAPITest.java
@@ -72,7 +72,7 @@
             RequestHandle handle =
                     mRequestQueue.queueRequest(
                             "http://localhost:8080/test1", "GET", headers, null,
-                            null, 0, false);
+                            null, 0);
 
             handle.waitUntilComplete();
             fail("expected exception not thrown");
@@ -121,7 +121,7 @@
         mTestWebServer.setKeepAlive(false);
         RequestHandle handle = mRequestQueue.queueRequest(
                 "http://localhost:8080/test1", "GET", headers, null,
-                null, 0, false);
+                null, 0);
         handle.waitUntilComplete();
     }
 
@@ -197,7 +197,7 @@
 
         RequestHandle handle = mRequestQueue.queueRequest(
                 "http://localhost:8080/test1", "GET", null, testEventHandler,
-                null, 0, false);
+                null, 0);
 
         Log.d(LOGTAG, "testGet - sent request. Waiting");
         handle.waitUntilComplete();
@@ -231,11 +231,11 @@
 
         RequestHandle handle0 = mRequestQueue.queueRequest(
                 "http://localhost:8080/test1", "GET", null, testEventHandler,
-                null, 0, false);
+                null, 0);
         handle0.waitUntilComplete();
         RequestHandle handle1 = mRequestQueue.queueRequest(
                 "http://localhost:8080/test1", "GET", null, testEventHandler2,
-                null, 0, false);
+                null, 0);
         handle1.waitUntilComplete();
 
         /* It's not correct to use same listener for multiple
@@ -270,7 +270,7 @@
 
         RequestHandle handle = mRequestQueue.queueRequest(
                 "http://localhost:8080/test1", "HEAD", null, testEventHandler,
-                null, 0, false);
+                null, 0);
 
         Log.d(LOGTAG, "testHead - sent request waiting");
         handle.waitUntilComplete();
@@ -297,7 +297,7 @@
 
         RequestHandle handle = mRequestQueue.queueRequest(
                 "http://localhost:8080/test1", "GET", null, testEventHandler,
-                null, 0, false);
+                null, 0);
 
         Log.d(LOGTAG, "testChunked - sent request waiting");
         handle.waitUntilComplete();
@@ -330,7 +330,7 @@
             Log.d(LOGTAG, testName + " start - rq = " + mRequestQueue);
 
             RequestHandle requestHandle = mRequestQueue.queueRequest(
-                    "http://localhost:8080/test1", "GET", null, testEventHandler, null, 0, false);
+                    "http://localhost:8080/test1", "GET", null, testEventHandler, null, 0);
             Log.d(LOGTAG, testName + " - sent request waiting");
 
             requestHandle.waitUntilComplete();
@@ -398,10 +398,10 @@
         leh2.expectHeaders();
 
         RequestHandle handle0 = mRequestQueue.queueRequest(
-                "http://localhost:8080/test1", "GET", null, testEventHandler, null, 0, false);
+                "http://localhost:8080/test1", "GET", null, testEventHandler, null, 0);
         handle0.waitUntilComplete();
         RequestHandle handle1 = mRequestQueue.queueRequest(
-                "http://localhost:8080/test1", "HEAD", null, testEventHandler, null, 0, false);
+                "http://localhost:8080/test1", "HEAD", null, testEventHandler, null, 0);
 
         Log.d(LOGTAG, "testGetAndHead - sent request. Waiting");
         handle1.waitUntilComplete();
@@ -432,7 +432,7 @@
         Log.d(LOGTAG, "testPost start - rq = " + mRequestQueue);
 
         RequestHandle handle = mRequestQueue.queueRequest(
-                "http://localhost:8080/test1", "POST", null, testEventHandler, null, 0, false);
+                "http://localhost:8080/test1", "POST", null, testEventHandler, null, 0);
 
         Log.d(LOGTAG, "testPost - sent request waiting");
         handle.waitUntilComplete();
@@ -470,7 +470,7 @@
         InputStream bodyProvider = new ByteArrayInputStream(mBody.getBytes());
 
         RequestHandle handle = mRequestQueue.queueRequest(
-                "http://localhost:8080/test1", "POST", null, testEventHandler, bodyProvider, bodyLength, false);
+                "http://localhost:8080/test1", "POST", null, testEventHandler, bodyProvider, bodyLength);
 
         Log.d(LOGTAG, "testPostWithData - sent request waiting");
         handle.waitUntilComplete();
diff --git a/tests/CoreTests/com/android/internal/telephony/gsm/GSMPhoneTest.java b/tests/CoreTests/com/android/internal/telephony/gsm/GSMPhoneTest.java
index 7107412..b96743a 100644
--- a/tests/CoreTests/com/android/internal/telephony/gsm/GSMPhoneTest.java
+++ b/tests/CoreTests/com/android/internal/telephony/gsm/GSMPhoneTest.java
@@ -81,7 +81,7 @@
         mRadioControl = mGSMTestHandler.getSimulatedCommands();
 
         mHandler = mGSMTestHandler.getHandler();
-        mGSMPhone.registerForPhoneStateChanged(mHandler, EVENT_PHONE_STATE_CHANGED, null);
+        mGSMPhone.registerForPreciseCallStateChanged(mHandler, EVENT_PHONE_STATE_CHANGED, null);
         mGSMPhone.registerForNewRingingConnection(mHandler, EVENT_RINGING, null);
         mGSMPhone.registerForDisconnect(mHandler, EVENT_DISCONNECT, null);
 
@@ -109,7 +109,7 @@
     protected void tearDown() throws Exception {
         mRadioControl.shutdown();
 
-        mGSMPhone.unregisterForPhoneStateChanged(mHandler);
+        mGSMPhone.unregisterForPreciseCallStateChanged(mHandler);
         mGSMPhone.unregisterForNewRingingConnection(mHandler);
         mGSMPhone.unregisterForDisconnect(mHandler);
         mGSMPhone.setOnPostDialCharacter(mHandler, 0, null);
diff --git a/wifi/java/android/net/wifi/WifiStateTracker.java b/wifi/java/android/net/wifi/WifiStateTracker.java
index a2cdcc1..12abce5 100644
--- a/wifi/java/android/net/wifi/WifiStateTracker.java
+++ b/wifi/java/android/net/wifi/WifiStateTracker.java
@@ -242,6 +242,7 @@
     private SettingsObserver mSettingsObserver;
     
     private boolean mIsScanModeActive;
+    private boolean mEnableRssiPolling;
 
     // Wi-Fi run states:
     private static final int RUN_STATE_STARTING = 1;
@@ -340,6 +341,7 @@
     private void setSupplicantState(SupplicantState state) {
         mWifiInfo.setSupplicantState(state);
         updateNetworkInfo();
+        checkPollTimer();
     }
 
     public SupplicantState getSupplicantState() {
@@ -354,6 +356,7 @@
     private void setSupplicantState(String stateName) {
         mWifiInfo.setSupplicantState(stateName);
         updateNetworkInfo();
+        checkPollTimer();
     }
 
     /**
@@ -550,8 +553,10 @@
      * Set the interval timer for polling connection information
      * that is not delivered asynchronously.
      */
-    private synchronized void setPollTimer () {
-        if (!hasMessages(EVENT_POLL_INTERVAL)) {
+    private synchronized void checkPollTimer() {
+        if (mEnableRssiPolling &&
+                mWifiInfo.getSupplicantState() == SupplicantState.COMPLETED &&
+                !hasMessages(EVENT_POLL_INTERVAL)) {
             sendEmptyMessageDelayed(EVENT_POLL_INTERVAL, POLL_STATUS_INTERVAL_MSECS);
         }
     }
@@ -651,6 +656,13 @@
         setBluetoothScanMode(isBluetoothPlaying);
     }
 
+    public void enableRssiPolling(boolean enable) {
+        if (mEnableRssiPolling != enable) {
+            mEnableRssiPolling = enable;
+            checkPollTimer();
+        }
+    }
+
     @Override
     public void releaseWakeLock() {
         if (mReleaseWakeLockCallback != null) {
@@ -1031,9 +1043,7 @@
             case EVENT_POLL_INTERVAL:
                 if (mWifiInfo.getSupplicantState() != SupplicantState.UNINITIALIZED) {
                     requestPolledInfo(mWifiInfo, true);
-                    if (mWifiInfo.getSupplicantState() == SupplicantState.COMPLETED) {
-                        setPollTimer();
-                    }
+                    checkPollTimer();
                 }
                 break;
             
@@ -1170,7 +1180,7 @@
     }
 
     private void configureInterface() {
-        setPollTimer();
+        checkPollTimer();
         mLastSignalLevel = -1;
         if (!mUseStaticIp) {
             if (!mHaveIpAddress && !mObtainingIpAddress) {