Merge "unhide public apis"
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index 1a5b7f3..dd1c275 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -793,7 +793,9 @@
             MEDIA_MIMETYPE_VIDEO_AVC, MEDIA_MIMETYPE_VIDEO_MPEG4,
             MEDIA_MIMETYPE_VIDEO_H263, MEDIA_MIMETYPE_AUDIO_AAC,
             MEDIA_MIMETYPE_AUDIO_AMR_NB, MEDIA_MIMETYPE_AUDIO_AMR_WB,
-            MEDIA_MIMETYPE_AUDIO_MPEG
+            MEDIA_MIMETYPE_AUDIO_MPEG, MEDIA_MIMETYPE_AUDIO_G711_MLAW,
+            MEDIA_MIMETYPE_AUDIO_G711_ALAW, MEDIA_MIMETYPE_AUDIO_VORBIS,
+            MEDIA_MIMETYPE_VIDEO_VPX
         };
 
         for (size_t k = 0; k < sizeof(kMimeTypes) / sizeof(kMimeTypes[0]);
diff --git a/cmds/system_server/system_main.cpp b/cmds/system_server/system_main.cpp
index 543f650..d67329d 100644
--- a/cmds/system_server/system_main.cpp
+++ b/cmds/system_server/system_main.cpp
@@ -52,10 +52,5 @@
     LOGW("*** Current priority: %d\n", getpriority(PRIO_PROCESS, 0));
     setpriority(PRIO_PROCESS, 0, -1);
 
-    #if HAVE_ANDROID_OS
-    //setgid(GID_SYSTEM);
-    //setuid(UID_SYSTEM);
-    #endif
-
     system_init();    
 }
diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index 8e4725f..32ca226 100755
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -181,7 +181,7 @@
          *
          * @hide
          * @deprecated No longer in use, the default engine is determined by
-         *         the sort order defined in {@link EngineInfoComparator}. Note that
+         *         the sort order defined in {@link TtsEngines}. Note that
          *         this doesn't "break" anything because there is no guarantee that
          *         the engine specified below is installed on a given build, let
          *         alone be the default.
@@ -504,36 +504,39 @@
     }
 
     private int initTts() {
-        String defaultEngine = getDefaultEngine();
-        String engine = defaultEngine;
-        if (mEnginesHelper.isEngineInstalled(mRequestedEngine)) {
-            engine = mRequestedEngine;
+        // Step 1: Try connecting to the engine that was requested.
+        if (mRequestedEngine != null && mEnginesHelper.isEngineInstalled(mRequestedEngine)) {
+            if (connectToEngine(mRequestedEngine)) {
+                mCurrentEngine = mRequestedEngine;
+                return SUCCESS;
+            }
         }
 
-        // Try requested engine
-        if (connectToEngine(engine)) {
-            mCurrentEngine = engine;
-            return SUCCESS;
-        }
-
-        // Fall back to user's default engine if different from the already tested one
-        if (!engine.equals(defaultEngine)) {
+        // Step 2: Try connecting to the user's default engine.
+        final String defaultEngine = getDefaultEngine();
+        if (defaultEngine != null && !defaultEngine.equals(mRequestedEngine)) {
             if (connectToEngine(defaultEngine)) {
-                mCurrentEngine = engine;
+                mCurrentEngine = defaultEngine;
                 return SUCCESS;
             }
         }
 
+        // Step 3: Try connecting to the highest ranked engine in the
+        // system.
         final String highestRanked = mEnginesHelper.getHighestRankedEngineName();
-        // Fall back to the hardcoded default if different from the two above
-        if (!defaultEngine.equals(highestRanked)
-                && !engine.equals(highestRanked)) {
+        if (highestRanked != null && !highestRanked.equals(mRequestedEngine) &&
+                !highestRanked.equals(defaultEngine)) {
             if (connectToEngine(highestRanked)) {
-                mCurrentEngine = engine;
+                mCurrentEngine = highestRanked;
                 return SUCCESS;
             }
         }
 
+        // NOTE: The API currently does not allow the caller to query whether
+        // they are actually connected to any engine. This might fail for various
+        // reasons like if the user disables all her TTS engines.
+
+        mCurrentEngine = null;
         dispatchOnInit(ERROR);
         return ERROR;
     }
@@ -963,7 +966,7 @@
     /**
      * Synthesizes the given text to a file using the specified parameters.
      *
-     * @param text Thetext that should be synthesized
+     * @param text The text that should be synthesized
      * @param params Parameters for the request. Can be null.
      *            Supported parameter names:
      *            {@link Engine#KEY_PARAM_UTTERANCE_ID}.
@@ -1073,7 +1076,9 @@
      *
      * @deprecated This doesn't inform callers when the TTS engine has been
      *        initialized. {@link #TextToSpeech(Context, OnInitListener, String)}
-     *        can be used with the appropriate engine name.
+     *        can be used with the appropriate engine name. Also, there is no
+     *        guarantee that the engine specified will be loaded. If it isn't
+     *        installed or disabled, the user / system wide defaults will apply.
      *
      * @param enginePackageName The package name for the synthesis engine (e.g. "com.svox.pico")
      *
diff --git a/core/java/android/webkit/CallbackProxy.java b/core/java/android/webkit/CallbackProxy.java
index 0294e3f..88583df 100644
--- a/core/java/android/webkit/CallbackProxy.java
+++ b/core/java/android/webkit/CallbackProxy.java
@@ -120,6 +120,7 @@
     private static final int AUTO_LOGIN                          = 140;
     private static final int CLIENT_CERT_REQUEST                 = 141;
     private static final int SEARCHBOX_IS_SUPPORTED_CALLBACK     = 142;
+    private static final int SEARCHBOX_DISPATCH_COMPLETE_CALLBACK= 143;
 
     // Message triggered by the client to resume execution
     private static final int NOTIFY                              = 200;
@@ -821,6 +822,13 @@
                 searchBox.handleIsSupportedCallback(supported);
                 break;
             }
+            case SEARCHBOX_DISPATCH_COMPLETE_CALLBACK: {
+                SearchBoxImpl searchBox = (SearchBoxImpl) mWebView.getSearchBox();
+                Boolean success = (Boolean) msg.obj;
+                searchBox.handleDispatchCompleteCallback(msg.getData().getString("function"),
+                        msg.getData().getInt("id"), success);
+                break;
+            }
         }
     }
 
@@ -1641,4 +1649,13 @@
         msg.obj = new Boolean(isSupported);
         sendMessage(msg);
     }
+
+    void onSearchboxDispatchCompleteCallback(String function, int id, boolean success) {
+        Message msg = obtainMessage(SEARCHBOX_DISPATCH_COMPLETE_CALLBACK);
+        msg.obj = Boolean.valueOf(success);
+        msg.getData().putString("function", function);
+        msg.getData().putInt("id", id);
+
+        sendMessage(msg);
+    }
 }
diff --git a/core/java/android/webkit/SearchBox.java b/core/java/android/webkit/SearchBox.java
index 5075302..6512c4b 100644
--- a/core/java/android/webkit/SearchBox.java
+++ b/core/java/android/webkit/SearchBox.java
@@ -68,11 +68,15 @@
      * Notify the search page of any changes to the searchbox. Such as
      * a change in the typed query (onchange), the user commiting a given query
      * (onsubmit), or a change in size of a suggestions dropdown (onresize).
+     *
+     * @param listener an optional listener to notify of the success of the operation,
+     *      indicating if the javascript function existed and could be called or not.
+     *      It will be called on the UI thread.
      */
-    void onchange();
-    void onsubmit();
-    void onresize();
-    void oncancel();
+    void onchange(SearchBoxListener listener);
+    void onsubmit(SearchBoxListener listener);
+    void onresize(SearchBoxListener listener);
+    void oncancel(SearchBoxListener listener);
 
     /**
      * Add and remove listeners to the given Searchbox. Listeners are notified
@@ -91,8 +95,12 @@
      * Listeners (if any) will be called on the thread that created the
      * webview.
      */
-    interface SearchBoxListener {
-        void onSuggestionsReceived(String query, List<String> suggestions);
+    public abstract class SearchBoxListener {
+        public void onSuggestionsReceived(String query, List<String> suggestions) {}
+        public void onChangeComplete(boolean called) {}
+        public void onSubmitComplete(boolean called) {}
+        public void onResizeComplete(boolean called) {}
+        public void onCancelComplete(boolean called) {}
     }
 
     interface IsSupportedCallback {
diff --git a/core/java/android/webkit/SearchBoxImpl.java b/core/java/android/webkit/SearchBoxImpl.java
index 61fb2ce..9942d25 100644
--- a/core/java/android/webkit/SearchBoxImpl.java
+++ b/core/java/android/webkit/SearchBoxImpl.java
@@ -16,10 +16,12 @@
 
 package android.webkit;
 
+import android.text.TextUtils;
 import android.util.Log;
 import android.webkit.WebViewCore.EventHub;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 
 import org.json.JSONArray;
@@ -69,7 +71,7 @@
 
     private static final String SET_VERBATIM_SCRIPT
             =  "if (window.chrome && window.chrome.searchBox) {"
-            + "  window.chrome.searchBox.verbatim = %s;"
+            + "  window.chrome.searchBox.verbatim = %1$s;"
             + "}";
 
     private static final String SET_SELECTION_SCRIPT
@@ -89,13 +91,21 @@
             + "}";
 
     private static final String DISPATCH_EVENT_SCRIPT
-            = "if (window.chrome && window.chrome.searchBox &&"
-            + "  window.chrome.searchBox.on%1$s) { window.chrome.searchBox.on%1$s(); }";
+            = "if (window.chrome && window.chrome.searchBox && window.chrome.searchBox.on%1$s) {"
+            + "  window.chrome.searchBox.on%1$s();"
+            + "  window.searchBoxJavaBridge_.dispatchCompleteCallback('%1$s', %2$d, true);"
+            + "} else {"
+            + "  window.searchBoxJavaBridge_.dispatchCompleteCallback('%1$s', %2$d, false);"
+            + "}";
+
+    private static final String EVENT_CHANGE = "change";
+    private static final String EVENT_SUBMIT = "submit";
+    private static final String EVENT_RESIZE = "resize";
+    private static final String EVENT_CANCEL = "cancel";
 
     private static final String IS_SUPPORTED_SCRIPT
             = "if (window.searchBoxJavaBridge_) {"
-            + "  if (window.chrome && window.chrome.searchBox && "
-            + "  window.chrome.searchBox.onsubmit) {"
+            + "  if (window.chrome && window.chrome.sv) {"
             + "    window.searchBoxJavaBridge_.isSupportedCallback(true);"
             + "  } else {"
             + "    window.searchBoxJavaBridge_.isSupportedCallback(false);"
@@ -105,11 +115,14 @@
     private final WebViewCore mWebViewCore;
     private final CallbackProxy mCallbackProxy;
     private IsSupportedCallback mSupportedCallback;
+    private int mNextEventId = 1;
+    private final HashMap<Integer, SearchBoxListener> mEventCallbacks;
 
     SearchBoxImpl(WebViewCore webViewCore, CallbackProxy callbackProxy) {
         mListeners = new ArrayList<SearchBoxListener>();
         mWebViewCore = webViewCore;
         mCallbackProxy = callbackProxy;
+        mEventCallbacks = new HashMap<Integer, SearchBoxListener>();
     }
 
     @Override
@@ -141,27 +154,36 @@
     }
 
     @Override
-    public void onchange() {
-        dispatchEvent("change");
+    public void onchange(SearchBoxListener callback) {
+        dispatchEvent(EVENT_CHANGE, callback);
     }
 
     @Override
-    public void onsubmit() {
-        dispatchEvent("submit");
+    public void onsubmit(SearchBoxListener callback) {
+        dispatchEvent(EVENT_SUBMIT, callback);
     }
 
     @Override
-    public void onresize() {
-        dispatchEvent("resize");
+    public void onresize(SearchBoxListener callback) {
+        dispatchEvent(EVENT_RESIZE, callback);
     }
 
     @Override
-    public void oncancel() {
-        dispatchEvent("cancel");
+    public void oncancel(SearchBoxListener callback) {
+        dispatchEvent(EVENT_CANCEL, callback);
     }
 
-    private void dispatchEvent(String eventName) {
-        final String js = String.format(DISPATCH_EVENT_SCRIPT, eventName);
+    private void dispatchEvent(String eventName, SearchBoxListener callback) {
+        int eventId;
+        if (callback != null) {
+            synchronized(this) {
+                eventId = mNextEventId++;
+                mEventCallbacks.put(eventId, callback);
+            }
+        } else {
+            eventId = 0;
+        }
+        final String js = String.format(DISPATCH_EVENT_SCRIPT, eventName, eventId);
         dispatchJs(js);
     }
 
@@ -202,9 +224,35 @@
         }
     }
 
+    // Called by Javascript through the Java bridge.
+    public void dispatchCompleteCallback(String function, int id, boolean successful) {
+        mCallbackProxy.onSearchboxDispatchCompleteCallback(function, id, successful);
+    }
+
+    public void handleDispatchCompleteCallback(String function, int id, boolean successful) {
+        if (id != 0) {
+            SearchBoxListener listener;
+            synchronized(this) {
+                listener = mEventCallbacks.get(id);
+                mEventCallbacks.remove(id);
+            }
+            if (listener != null) {
+                if (TextUtils.equals(EVENT_CHANGE, function)) {
+                    listener.onChangeComplete(successful);
+                } else if (TextUtils.equals(EVENT_SUBMIT, function)) {
+                    listener.onSubmitComplete(successful);
+                } else if (TextUtils.equals(EVENT_RESIZE, function)) {
+                    listener.onResizeComplete(successful);
+                } else if (TextUtils.equals(EVENT_CANCEL, function)) {
+                    listener.onCancelComplete(successful);
+                }
+            }
+        }
+    }
+
     // This is used as a hackish alternative to javascript escaping.
     // There appears to be no such functionality in the core framework.
-    private String jsonSerialize(String query) {
+    private static String jsonSerialize(String query) {
         JSONStringer stringer = new JSONStringer();
         try {
             stringer.array().value(query).endArray();
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index c652e55..5414b79 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -248,7 +248,7 @@
 
     /* Get the BrowserFrame component. This is used for subwindow creation and
      * is called only from BrowserFrame in the WebCore thread. */
-    /* package */ BrowserFrame getBrowserFrame() {
+    /* package */ synchronized BrowserFrame getBrowserFrame() {
         return mBrowserFrame;
     }
 
diff --git a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
index 9c06d69..80f68ac 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
@@ -544,6 +544,17 @@
             }
 
             setCallback(mPopupPresenterCallback);
+
+            boolean preserveIconSpacing = false;
+            final int count = subMenu.size();
+            for (int i = 0; i < count; i++) {
+                MenuItem childItem = subMenu.getItem(i);
+                if (childItem.isVisible() && childItem.getIcon() != null) {
+                    preserveIconSpacing = true;
+                    break;
+                }
+            }
+            setForceShowIcon(preserveIconSpacing);
         }
 
         @Override
diff --git a/core/java/com/android/internal/view/menu/IconMenuPresenter.java b/core/java/com/android/internal/view/menu/IconMenuPresenter.java
index 56128d4..d1b1dae 100644
--- a/core/java/com/android/internal/view/menu/IconMenuPresenter.java
+++ b/core/java/com/android/internal/view/menu/IconMenuPresenter.java
@@ -179,8 +179,10 @@
         @Override
         public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
             mOpenSubMenuId = 0;
-            mOpenSubMenu.dismiss();
-            mOpenSubMenu = null;
+            if (mOpenSubMenu != null) {
+                mOpenSubMenu.dismiss();
+                mOpenSubMenu = null;
+            }
         }
 
         @Override
diff --git a/core/java/com/android/internal/view/menu/ListMenuItemView.java b/core/java/com/android/internal/view/menu/ListMenuItemView.java
index 0c3c605..a1e16d4 100644
--- a/core/java/com/android/internal/view/menu/ListMenuItemView.java
+++ b/core/java/com/android/internal/view/menu/ListMenuItemView.java
@@ -22,6 +22,7 @@
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
 import android.view.View;
+import android.view.ViewGroup;
 import android.widget.CheckBox;
 import android.widget.CompoundButton;
 import android.widget.ImageView;
@@ -50,6 +51,8 @@
     
     private LayoutInflater mInflater;
 
+    private boolean mForceShowIcon;
+
     public ListMenuItemView(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs);
     
@@ -99,6 +102,10 @@
         setEnabled(itemData.isEnabled());
     }
 
+    public void setForceShowIcon(boolean forceShow) {
+        mPreserveIconSpacing = mForceShowIcon = forceShow;
+    }
+
     public void setTitle(CharSequence title) {
         if (title != null) {
             mTitleView.setText(title);
@@ -189,12 +196,12 @@
     }
     
     public void setIcon(Drawable icon) {
-        final boolean showIcon = mItemData.shouldShowIcon();
+        final boolean showIcon = mItemData.shouldShowIcon() || mForceShowIcon;
         if (!showIcon && !mPreserveIconSpacing) {
             return;
         }
         
-        if (mIconView == null && icon == null) {
+        if (mIconView == null && icon == null && !mPreserveIconSpacing) {
             return;
         }
         
@@ -213,6 +220,19 @@
         }
     }
     
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        if (mIconView != null && mPreserveIconSpacing) {
+            // Enforce minimum icon spacing
+            ViewGroup.LayoutParams lp = getLayoutParams();
+            LayoutParams iconLp = (LayoutParams) mIconView.getLayoutParams();
+            if (lp.height > 0 && iconLp.width <= 0) {
+                iconLp.width = lp.height;
+            }
+        }
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+    }
+
     private void insertIconView() {
         LayoutInflater inflater = getInflater();
         mIconView = (ImageView) inflater.inflate(com.android.internal.R.layout.list_menu_item_icon,
@@ -241,7 +261,7 @@
     }
 
     public boolean showsIcon() {
-        return false;
+        return mForceShowIcon;
     }
     
     private LayoutInflater getInflater() {
diff --git a/core/java/com/android/internal/view/menu/MenuPopupHelper.java b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
index 4ecc828..6265618 100644
--- a/core/java/com/android/internal/view/menu/MenuPopupHelper.java
+++ b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
@@ -19,15 +19,16 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.os.Parcelable;
-import android.util.DisplayMetrics;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
+import android.view.MenuItem;
 import android.view.View;
 import android.view.View.MeasureSpec;
 import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
 import android.widget.AdapterView;
 import android.widget.BaseAdapter;
+import android.widget.FrameLayout;
 import android.widget.ListAdapter;
 import android.widget.ListPopupWindow;
 import android.widget.PopupWindow;
@@ -58,6 +59,10 @@
 
     private Callback mPresenterCallback;
 
+    boolean mForceShowIcon;
+
+    private ViewGroup mMeasureParent;
+
     public MenuPopupHelper(Context context, MenuBuilder menu) {
         this(context, menu, null, false);
     }
@@ -86,6 +91,10 @@
         mAnchorView = anchor;
     }
 
+    public void setForceShowIcon(boolean forceShow) {
+        mForceShowIcon = forceShow;
+    }
+
     public void show() {
         if (!tryShow()) {
             throw new IllegalStateException("MenuPopupHelper cannot be used without an anchor");
@@ -170,7 +179,10 @@
                 itemType = positionType;
                 itemView = null;
             }
-            itemView = adapter.getView(i, itemView, null);
+            if (mMeasureParent == null) {
+                mMeasureParent = new FrameLayout(mContext);
+            }
+            itemView = adapter.getView(i, itemView, mMeasureParent);
             itemView.measure(widthMeasureSpec, heightMeasureSpec);
             width = Math.max(width, itemView.getMeasuredWidth());
         }
@@ -228,6 +240,18 @@
         if (subMenu.hasVisibleItems()) {
             MenuPopupHelper subPopup = new MenuPopupHelper(mContext, subMenu, mAnchorView, false);
             subPopup.setCallback(mPresenterCallback);
+
+            boolean preserveIconSpacing = false;
+            final int count = subMenu.size();
+            for (int i = 0; i < count; i++) {
+                MenuItem childItem = subMenu.getItem(i);
+                if (childItem.isVisible() && childItem.getIcon() != null) {
+                    preserveIconSpacing = true;
+                    break;
+                }
+            }
+            subPopup.setForceShowIcon(preserveIconSpacing);
+
             if (subPopup.tryShow()) {
                 if (mPresenterCallback != null) {
                     mPresenterCallback.onOpenSubMenu(subMenu);
@@ -293,6 +317,9 @@
             }
 
             MenuView.ItemView itemView = (MenuView.ItemView) convertView;
+            if (mForceShowIcon) {
+                ((ListMenuItemView) convertView).setForceShowIcon(true);
+            }
             itemView.initialize(getItem(position), 0);
             return convertView;
         }
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index a61217a..23c6da7 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -623,16 +623,9 @@
     }
 
     /* enable debugging; set suspend=y to pause during VM init */
-#ifdef HAVE_ANDROID_OS
     /* use android ADB transport */
     opt.optionString =
         "-agentlib:jdwp=transport=dt_android_adb,suspend=n,server=y";
-#else
-    /* use TCP socket; address=0 means start at port 8000 and probe up */
-    LOGI("Using TCP socket for JDWP\n");
-    opt.optionString =
-        "-agentlib:jdwp=transport=dt_socket,suspend=n,server=y,address=0";
-#endif
     mOptions.add(opt);
 
     char enableDPBuf[sizeof("-Xdeadlockpredict:") + PROPERTY_VALUE_MAX];
diff --git a/core/jni/android_net_TrafficStats.cpp b/core/jni/android_net_TrafficStats.cpp
index d54981e..c22b071 100644
--- a/core/jni/android_net_TrafficStats.cpp
+++ b/core/jni/android_net_TrafficStats.cpp
@@ -44,7 +44,6 @@
 
 // Returns an ASCII decimal number read from the specified file, -1 on error.
 static jlong readNumber(char const* filename) {
-#ifdef HAVE_ANDROID_OS
     char buf[80];
     int fd = open(filename, O_RDONLY);
     if (fd < 0) {
@@ -62,9 +61,6 @@
     close(fd);
     buf[len] = '\0';
     return atoll(buf);
-#else  // Simulator
-    return -1;
-#endif
 }
 
 static const char* mobile_iface_list[] = {
@@ -101,7 +97,6 @@
 // Returns the sum of numbers from the specified path under /sys/class/net/*,
 // -1 if no such file exists.
 static jlong readTotal(char const* suffix) {
-#ifdef HAVE_ANDROID_OS
     char filename[PATH_MAX] = "/sys/class/net/";
     DIR *dir = opendir(filename);
     if (dir == NULL) {
@@ -123,9 +118,6 @@
 
     closedir(dir);
     return total;
-#else  // Simulator
-    return -1;
-#endif
 }
 
 // Mobile stats get accessed a lot more often than total stats.
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index 2297834..a4432c3 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -278,7 +278,6 @@
 jint android_os_Debug_getDeathObjectCount(JNIEnv* env, jobject clazz);
 
 
-#ifdef HAVE_ANDROID_OS
 /* pulled out of bionic */
 extern "C" void get_malloc_leak_info(uint8_t** info, size_t* overallSize,
     size_t* infoSize, size_t* totalMemory, size_t* backtraceSize);
@@ -414,7 +413,6 @@
 
     fprintf(fp, "END\n");
 }
-#endif /*HAVE_ANDROID_OS*/
 
 /*
  * Dump the native heap, writing human-readable output to the specified
@@ -449,13 +447,9 @@
         return;
     }
 
-#ifdef HAVE_ANDROID_OS
     LOGD("Native heap dump starting...\n");
     dumpNativeHeap(fp);
     LOGD("Native heap dump complete.\n");
-#else
-    fprintf(fp, "Native heap dump not available on this platform\n");
-#endif
 
     fclose(fp);
 }
diff --git a/core/jni/android_os_FileUtils.cpp b/core/jni/android_os_FileUtils.cpp
index 89dce89..8d65cbc 100644
--- a/core/jni/android_os_FileUtils.cpp
+++ b/core/jni/android_os_FileUtils.cpp
@@ -28,11 +28,8 @@
 #include <sys/types.h>
 #include <fcntl.h>
 #include <signal.h>
-
-#if HAVE_ANDROID_OS
 #include <sys/ioctl.h>
 #include <linux/msdos_fs.h>
-#endif
 
 namespace android {
 
@@ -53,7 +50,6 @@
                                          jstring file, jint mode,
                                          jint uid, jint gid)
 {
-    #if HAVE_ANDROID_OS
     const jchar* str = env->GetStringCritical(file, 0);
     String8 file8;
     if (str) {
@@ -70,15 +66,11 @@
         }
     }
     return chmod(file8.string(), mode) == 0 ? 0 : errno;
-    #else
-    return ENOSYS;
-    #endif
 }
 
 jint android_os_FileUtils_getPermissions(JNIEnv* env, jobject clazz,
                                          jstring file, jintArray outArray)
 {
-    #if HAVE_ANDROID_OS
     const jchar* str = env->GetStringCritical(file, 0);
     String8 file8;
     if (str) {
@@ -107,9 +99,6 @@
     }
     env->ReleasePrimitiveArrayCritical(outArray, array, 0);
     return 0;
-    #else
-    return ENOSYS;
-    #endif
 }
 
 jint android_os_FileUtils_setUMask(JNIEnv* env, jobject clazz, jint mask)
@@ -119,7 +108,6 @@
 
 jint android_os_FileUtils_getFatVolumeId(JNIEnv* env, jobject clazz, jstring path)
 {
-    #if HAVE_ANDROID_OS
     if (path == NULL) {
         jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
         return -1;
@@ -137,9 +125,6 @@
 
     env->ReleaseStringUTFChars(path, pathStr);
     return result;
-    #else
-    return -1;
-    #endif
 }
 
 jboolean android_os_FileUtils_getFileStatus(JNIEnv* env, jobject clazz, jstring path, jobject fileStatus) {
diff --git a/core/jni/android_os_Power.cpp b/core/jni/android_os_Power.cpp
index 9ae4a63..dc16990 100644
--- a/core/jni/android_os_Power.cpp
+++ b/core/jni/android_os_Power.cpp
@@ -70,16 +70,11 @@
 
 static void android_os_Power_shutdown(JNIEnv *env, jobject clazz)
 {
-#ifdef HAVE_ANDROID_OS
     android_reboot(ANDROID_RB_POWEROFF, 0, 0);
-#else
-    sync();
-#endif
 }
 
 static void android_os_Power_reboot(JNIEnv *env, jobject clazz, jstring reason)
 {
-#ifdef HAVE_ANDROID_OS
     if (reason == NULL) {
         android_reboot(ANDROID_RB_RESTART, 0, 0);
     } else {
@@ -88,9 +83,6 @@
         env->ReleaseStringUTFChars(reason, chars);  // In case it fails.
     }
     jniThrowIOException(env, errno);
-#else
-    sync();
-#endif
 }
 
 static JNINativeMethod method_table[] = {
diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp
index 2b09442..8f84b81 100644
--- a/core/jni/android_server_BluetoothEventLoop.cpp
+++ b/core/jni/android_server_BluetoothEventLoop.cpp
@@ -1115,7 +1115,7 @@
         LOGV("... uuid = %s", uuid);
 
         dbus_message_ref(msg);  // increment refcount because we pass to java
-        env->CallBooleanMethod(nat->me, method_onAgentAuthorize,
+        env->CallVoidMethod(nat->me, method_onAgentAuthorize,
                 env->NewStringUTF(object_path), env->NewStringUTF(uuid),
                 int(msg));
 
diff --git a/core/jni/android_util_Log.cpp b/core/jni/android_util_Log.cpp
index 0fbe0e7..2c7bb84 100644
--- a/core/jni/android_util_Log.cpp
+++ b/core/jni/android_util_Log.cpp
@@ -58,9 +58,6 @@
 
 static jboolean android_util_Log_isLoggable(JNIEnv* env, jobject clazz, jstring tag, jint level)
 {
-#ifndef HAVE_ANDROID_OS
-    return false;
-#else /* HAVE_ANDROID_OS */
     int len;
     char key[PROPERTY_KEY_MAX];
     char buf[PROPERTY_VALUE_MAX];
@@ -93,7 +90,6 @@
     len = property_get(key, buf, "");
     int logLevel = toLevel(buf);
     return (logLevel >= 0 && level >= logLevel) ? true : false;
-#endif /* HAVE_ANDROID_OS */
 }
 
 /*
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index d1ba2d1..47d343a 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -352,20 +352,12 @@
 
 jint android_os_Process_setUid(JNIEnv* env, jobject clazz, jint uid)
 {
-    #if HAVE_ANDROID_OS
     return setuid(uid) == 0 ? 0 : errno;
-    #else
-    return ENOSYS;
-    #endif
 }
 
 jint android_os_Process_setGid(JNIEnv* env, jobject clazz, jint uid)
 {
-    #if HAVE_ANDROID_OS
     return setgid(uid) == 0 ? 0 : errno;
-    #else
-    return ENOSYS;
-    #endif
 }
 
 static int pid_compare(const void* v1, const void* v2)
diff --git a/core/jni/com_android_internal_os_ZygoteInit.cpp b/core/jni/com_android_internal_os_ZygoteInit.cpp
index 86fd9cb..7e5dede 100644
--- a/core/jni/com_android_internal_os_ZygoteInit.cpp
+++ b/core/jni/com_android_internal_os_ZygoteInit.cpp
@@ -27,13 +27,11 @@
 #include <JNIHelp.h>
 #include "android_runtime/AndroidRuntime.h"
 
-#ifdef HAVE_ANDROID_OS
 #include <linux/capability.h>
 #include <linux/prctl.h>
 #include <sys/prctl.h>
 extern "C" int capget(cap_user_header_t hdrp, cap_user_data_t datap);
 extern "C" int capset(cap_user_header_t hdrp, const cap_user_data_t datap);
-#endif
 
 
 namespace android {
@@ -168,7 +166,6 @@
 static void com_android_internal_os_ZygoteInit_setCapabilities (JNIEnv *env,
     jobject clazz, jlong permitted, jlong effective)
 {
-#ifdef HAVE_ANDROID_OS
     struct __user_cap_header_struct capheader;
     struct __user_cap_data_struct capdata;
     int err;
@@ -190,15 +187,11 @@
         jniThrowIOException(env, errno);
         return;
     }
-#endif /* HAVE_ANDROID_OS */
 }
 
 static jlong com_android_internal_os_ZygoteInit_capgetPermitted (JNIEnv *env,
     jobject clazz, jint pid)
 {
-#ifndef HAVE_ANDROID_OS
-    return (jlong)0;
-#else
     struct __user_cap_header_struct capheader;
     struct __user_cap_data_struct capdata;
     int err;
@@ -217,7 +210,6 @@
     }
 
     return (jlong) capdata.permitted;
-#endif /* HAVE_ANDROID_OS */
 }
 
 static jint com_android_internal_os_ZygoteInit_selectReadable (
diff --git a/core/res/res/layout/list_menu_item_icon.xml b/core/res/res/layout/list_menu_item_icon.xml
index 6ff14dd..a885211 100644
--- a/core/res/res/layout/list_menu_item_icon.xml
+++ b/core/res/res/layout/list_menu_item_icon.xml
@@ -19,6 +19,8 @@
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:layout_gravity="center_vertical"
-    android:layout_marginRight="8dip"
+    android:layout_marginLeft="8dip"
+    android:layout_marginRight="-8dip"
+    android:scaleType="center"
     android:duplicateParentState="true" />
 
diff --git a/core/res/res/layout/popup_menu_item_layout.xml b/core/res/res/layout/popup_menu_item_layout.xml
index fef017d..1a12c01 100644
--- a/core/res/res/layout/popup_menu_item_layout.xml
+++ b/core/res/res/layout/popup_menu_item_layout.xml
@@ -18,7 +18,6 @@
     android:layout_width="match_parent"
     android:layout_height="?android:attr/dropdownListPreferredItemHeight"
     android:minWidth="196dip"
-    android:paddingLeft="16dip"
     android:paddingRight="16dip">
     
     <!-- Icon will be inserted here. -->
@@ -29,6 +28,7 @@
         android:layout_weight="1"
         android:layout_height="wrap_content"
         android:layout_gravity="center_vertical"
+        android:layout_marginLeft="16dip"
         android:duplicateParentState="true">
         
         <TextView 
diff --git a/include/media/stagefright/ShoutcastSource.h b/include/media/stagefright/ShoutcastSource.h
deleted file mode 100644
index bc67156..0000000
--- a/include/media/stagefright/ShoutcastSource.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2009 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 SHOUTCAST_SOURCE_H_
-
-#define SHOUTCAST_SOURCE_H_
-
-#include <sys/types.h>
-
-#include <media/stagefright/MediaSource.h>
-
-namespace android {
-
-class HTTPStream;
-class MediaBufferGroup;
-
-class ShoutcastSource : public MediaSource {
-public:
-    // Assumes ownership of "http".
-    ShoutcastSource(HTTPStream *http);
-
-    virtual status_t start(MetaData *params = NULL);
-    virtual status_t stop();
-
-    virtual sp<MetaData> getFormat();
-
-    virtual status_t read(
-            MediaBuffer **buffer, const ReadOptions *options = NULL);
-
-protected:
-    virtual ~ShoutcastSource();
-
-private:
-    HTTPStream *mHttp;
-    size_t mMetaDataOffset;
-    size_t mBytesUntilMetaData;
-
-    MediaBufferGroup *mGroup;
-    bool mStarted;
-
-    ShoutcastSource(const ShoutcastSource &);
-    ShoutcastSource &operator= (const ShoutcastSource &);
-};
-
-}  // namespace android
-
-#endif  // SHOUTCAST_SOURCE_H_
-
diff --git a/include/private/binder/binder_module.h b/include/private/binder/binder_module.h
index fdf327e..a8dd64f 100644
--- a/include/private/binder/binder_module.h
+++ b/include/private/binder/binder_module.h
@@ -21,126 +21,11 @@
 namespace android {
 #endif
 
-#if defined(HAVE_ANDROID_OS)
-
 /* obtain structures and constants from the kernel header */
 
 #include <sys/ioctl.h>
 #include <linux/binder.h>
 
-#else
-
-/* Some parts of the simulator need fake versions of this 
- * stuff in order to compile.  Really this should go away
- * entirely...
- */
-
-#define BINDER_CURRENT_PROTOCOL_VERSION 7
-
-#define BINDER_TYPE_BINDER 1
-#define BINDER_TYPE_WEAK_BINDER 2
-#define BINDER_TYPE_HANDLE 3
-#define BINDER_TYPE_WEAK_HANDLE 4
-#define BINDER_TYPE_FD 5
-
-struct flat_binder_object {
-    unsigned long type;
-    unsigned long flags;
-    union {
-        void *binder;
-        signed long handle;
-    };
-    void *cookie;
-};
-
-struct binder_write_read {
-    signed long write_size;
-    signed long write_consumed;
-    unsigned long write_buffer;
-    signed long read_size;
-    signed long read_consumed;
-    unsigned long read_buffer;
-};
-
-struct binder_transaction_data {
-    union {
-        size_t handle;
-        void *ptr;
-    } target;
-    void *cookie;
-    unsigned int code;
-    
-    unsigned int flags;
-    pid_t sender_pid;
-    uid_t sender_euid;
-    size_t data_size;
-    size_t offsets_size;
-    
-    union {
-        struct {
-            const void *buffer;
-            const void *offsets;
-        } ptr;
-        uint8_t buf[8];
-    } data;
-};
-
-enum transaction_flags {
-    TF_ONE_WAY = 0x01,
-    TF_ROOT_OBJECT = 0x04,
-    TF_STATUS_CODE = 0x08,
-    TF_ACCEPT_FDS = 0x10,
-};
-
-
-enum {
-    FLAT_BINDER_FLAG_PRIORITY_MASK = 0xff,
-    FLAT_BINDER_FLAG_ACCEPTS_FDS = 0x100,
-};
-
-enum BinderDriverReturnProtocol {
-    BR_ERROR,
-    BR_OK,
-    BR_TRANSACTION,
-    BR_REPLY,
-    BR_ACQUIRE_RESULT,
-    BR_DEAD_REPLY,
-    BR_TRANSACTION_COMPLETE,
-    BR_INCREFS,
-    BR_ACQUIRE,
-    BR_RELEASE,
-    BR_DECREFS,
-    BR_ATTEMPT_ACQUIRE,
-    BR_NOOP,
-    BR_SPAWN_LOOPER,
-    BR_FINISHED,
-    BR_DEAD_BINDER,
-    BR_CLEAR_DEATH_NOTIFICATION_DONE,
-    BR_FAILED_REPLY,
-};
-
-enum BinderDriverCommandProtocol {
-    BC_TRANSACTION,
-    BC_REPLY,
-    BC_ACQUIRE_RESULT,
-    BC_FREE_BUFFER,
-    BC_INCREFS,
-    BC_ACQUIRE,
-    BC_RELEASE,
-    BC_DECREFS,
-    BC_INCREFS_DONE,
-    BC_ACQUIRE_DONE,
-    BC_ATTEMPT_ACQUIRE,
-    BC_REGISTER_LOOPER,
-    BC_ENTER_LOOPER,
-    BC_EXIT_LOOPER,
-    BC_REQUEST_DEATH_NOTIFICATION,
-    BC_CLEAR_DEATH_NOTIFICATION,
-    BC_DEAD_BINDER_DONE,
-};
-
-#endif
-
 #ifdef __cplusplus
 }   // namespace android
 #endif
diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp
index 7264ac4..f5288c8 100644
--- a/libs/binder/ProcessState.cpp
+++ b/libs/binder/ProcessState.cpp
@@ -154,11 +154,7 @@
         mBinderContextUserData = userData;
 
         int dummy = 0;
-#if defined(HAVE_ANDROID_OS)
         status_t result = ioctl(mDriverFD, BINDER_SET_CONTEXT_MGR, &dummy);
-#else
-        status_t result = INVALID_OPERATION;
-#endif
         if (result == 0) {
             mManagesContexts = true;
         } else if (result == -1) {
@@ -304,12 +300,7 @@
     if (fd >= 0) {
         fcntl(fd, F_SETFD, FD_CLOEXEC);
         int vers;
-#if defined(HAVE_ANDROID_OS)
         status_t result = ioctl(fd, BINDER_VERSION, &vers);
-#else
-        status_t result = -1;
-        errno = EPERM;
-#endif
         if (result == -1) {
             LOGE("Binder ioctl to obtain version failed: %s", strerror(errno));
             close(fd);
@@ -320,14 +311,11 @@
             close(fd);
             fd = -1;
         }
-#if defined(HAVE_ANDROID_OS)
         size_t maxThreads = 15;
         result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
         if (result == -1) {
             LOGE("Binder ioctl to set max threads failed: %s", strerror(errno));
         }
-#endif
-        
     } else {
         LOGW("Opening '/dev/binder' failed: %s\n", strerror(errno));
     }
diff --git a/libs/ui/InputTransport.cpp b/libs/ui/InputTransport.cpp
index c46d6f4..1e602e9 100644
--- a/libs/ui/InputTransport.cpp
+++ b/libs/ui/InputTransport.cpp
@@ -83,7 +83,9 @@
         sp<InputChannel>& outServerChannel, sp<InputChannel>& outClientChannel) {
     status_t result;
 
-    int serverAshmemFd = ashmem_create_region(name.string(), DEFAULT_MESSAGE_BUFFER_SIZE);
+    String8 ashmemName("InputChannel ");
+    ashmemName.append(name);
+    int serverAshmemFd = ashmem_create_region(ashmemName.string(), DEFAULT_MESSAGE_BUFFER_SIZE);
     if (serverAshmemFd < 0) {
         result = -errno;
         LOGE("channel '%s' ~ Could not create shared memory region. errno=%d",
diff --git a/media/jni/android_mtp_MtpDatabase.cpp b/media/jni/android_mtp_MtpDatabase.cpp
index 0f3c063..4dbcb90 100644
--- a/media/jni/android_mtp_MtpDatabase.cpp
+++ b/media/jni/android_mtp_MtpDatabase.cpp
@@ -79,7 +79,6 @@
     return (MtpDatabase *)env->GetIntField(database, field_context);
 }
 
-#ifdef HAVE_ANDROID_OS
 // ----------------------------------------------------------------------------
 
 class MyMtpDatabase : public MtpDatabase {
@@ -1066,42 +1065,32 @@
     checkAndClearExceptionFromCallback(env, __FUNCTION__);
 }
 
-#endif // HAVE_ANDROID_OS
-
 // ----------------------------------------------------------------------------
 
 static void
 android_mtp_MtpDatabase_setup(JNIEnv *env, jobject thiz)
 {
-#ifdef HAVE_ANDROID_OS
     MyMtpDatabase* database = new MyMtpDatabase(env, thiz);
     env->SetIntField(thiz, field_context, (int)database);
     checkAndClearExceptionFromCallback(env, __FUNCTION__);
-#endif
 }
 
 static void
 android_mtp_MtpDatabase_finalize(JNIEnv *env, jobject thiz)
 {
-#ifdef HAVE_ANDROID_OS
     MyMtpDatabase* database = (MyMtpDatabase *)env->GetIntField(thiz, field_context);
     database->cleanup(env);
     delete database;
     env->SetIntField(thiz, field_context, 0);
     checkAndClearExceptionFromCallback(env, __FUNCTION__);
-#endif
 }
 
 static jstring
 android_mtp_MtpPropertyGroup_format_date_time(JNIEnv *env, jobject thiz, jlong seconds)
 {
-#ifdef HAVE_ANDROID_OS
     char    date[20];
     formatDateTime(seconds, date, sizeof(date));
     return env->NewStringUTF(date);
-#else
-    return NULL;
-#endif
 }
 
 // ----------------------------------------------------------------------------
diff --git a/media/jni/android_mtp_MtpDevice.cpp b/media/jni/android_mtp_MtpDevice.cpp
index 40bbaa3..6b73f6c 100644
--- a/media/jni/android_mtp_MtpDevice.cpp
+++ b/media/jni/android_mtp_MtpDevice.cpp
@@ -85,8 +85,6 @@
 static jfieldID field_objectInfo_dateModified;
 static jfieldID field_objectInfo_keywords;
 
-#ifdef HAVE_ANDROID_OS
-
 MtpDevice* get_device_from_object(JNIEnv* env, jobject javaDevice)
 {
     return (MtpDevice*)env->GetIntField(javaDevice, field_context);
@@ -100,15 +98,11 @@
     }
 }
 
-#endif // HAVE_ANDROID_OS
-
 // ----------------------------------------------------------------------------
 
 static jboolean
 android_mtp_MtpDevice_open(JNIEnv *env, jobject thiz, jstring deviceName, jint fd)
 {
-#ifdef HAVE_ANDROID_OS
-    LOGD("open\n");
     const char *deviceNameStr = env->GetStringUTFChars(deviceName, NULL);
     if (deviceNameStr == NULL) {
         return false;
@@ -120,27 +114,22 @@
     if (device)
         env->SetIntField(thiz, field_context, (int)device);
     return (device != NULL);
-#endif
 }
 
 static void
 android_mtp_MtpDevice_close(JNIEnv *env, jobject thiz)
 {
-#ifdef HAVE_ANDROID_OS
-    LOGD("close\n");
     MtpDevice* device = get_device_from_object(env, thiz);
     if (device) {
         device->close();
         delete device;
         env->SetIntField(thiz, field_context, 0);
     }
-#endif
 }
 
 static jobject
 android_mtp_MtpDevice_get_device_info(JNIEnv *env, jobject thiz)
 {
-#ifdef HAVE_ANDROID_OS
     MtpDevice* device = get_device_from_object(env, thiz);
     if (!device) {
         LOGD("android_mtp_MtpDevice_get_device_info device is null");
@@ -173,15 +162,11 @@
 
     delete deviceInfo;
     return info;
-#else
-    return NULL;
-#endif
 }
 
 static jintArray
 android_mtp_MtpDevice_get_storage_ids(JNIEnv *env, jobject thiz)
 {
-#ifdef HAVE_ANDROID_OS
     MtpDevice* device = get_device_from_object(env, thiz);
     if (!device)
         return NULL;
@@ -196,15 +181,11 @@
 
     delete storageIDs;
     return array;
-#else
-    return NULL;
-#endif
 }
 
 static jobject
 android_mtp_MtpDevice_get_storage_info(JNIEnv *env, jobject thiz, jint storageID)
 {
-#ifdef HAVE_ANDROID_OS
     MtpDevice* device = get_device_from_object(env, thiz);
     if (!device)
         return NULL;
@@ -234,16 +215,12 @@
 
     delete storageInfo;
     return info;
-#else
-    return NULL;
-#endif
 }
 
 static jintArray
 android_mtp_MtpDevice_get_object_handles(JNIEnv *env, jobject thiz,
         jint storageID, jint format, jint objectID)
 {
-#ifdef HAVE_ANDROID_OS
     MtpDevice* device = get_device_from_object(env, thiz);
     if (!device)
         return NULL;
@@ -258,15 +235,11 @@
 
     delete handles;
     return array;
-#else
-    return NULL;
-#endif
 }
 
 static jobject
 android_mtp_MtpDevice_get_object_info(JNIEnv *env, jobject thiz, jint objectID)
 {
-#ifdef HAVE_ANDROID_OS
     MtpDevice* device = get_device_from_object(env, thiz);
     if (!device)
         return NULL;
@@ -324,9 +297,6 @@
 
     delete objectInfo;
     return info;
-#else
-    return NULL;
-#endif
 }
 
 struct get_object_callback_data {
@@ -344,7 +314,6 @@
 static jbyteArray
 android_mtp_MtpDevice_get_object(JNIEnv *env, jobject thiz, jint objectID, jint objectSize)
 {
-#ifdef HAVE_ANDROID_OS
     MtpDevice* device = get_device_from_object(env, thiz);
     if (!device)
         return NULL;
@@ -361,14 +330,12 @@
 
     if (device->readObject(objectID, get_object_callback, objectSize, &data))
         return array;
-#endif
     return NULL;
 }
 
 static jbyteArray
 android_mtp_MtpDevice_get_thumbnail(JNIEnv *env, jobject thiz, jint objectID)
 {
-#ifdef HAVE_ANDROID_OS
     MtpDevice* device = get_device_from_object(env, thiz);
     if (!device)
         return NULL;
@@ -382,51 +349,41 @@
 
     free(thumbnail);
     return array;
-#else
-    return NULL;
-#endif
 }
 
 static jboolean
 android_mtp_MtpDevice_delete_object(JNIEnv *env, jobject thiz, jint object_id)
 {
-#ifdef HAVE_ANDROID_OS
     MtpDevice* device = get_device_from_object(env, thiz);
     if (device)
         return device->deleteObject(object_id);
     else
- #endif
         return NULL;
 }
 
 static jlong
 android_mtp_MtpDevice_get_parent(JNIEnv *env, jobject thiz, jint object_id)
 {
-#ifdef HAVE_ANDROID_OS
     MtpDevice* device = get_device_from_object(env, thiz);
     if (device)
         return device->getParent(object_id);
     else
-#endif
         return -1;
 }
 
 static jlong
 android_mtp_MtpDevice_get_storage_id(JNIEnv *env, jobject thiz, jint object_id)
 {
- #ifdef HAVE_ANDROID_OS
     MtpDevice* device = get_device_from_object(env, thiz);
     if (device)
         return device->getStorageID(object_id);
     else
-#endif
         return -1;
 }
 
 static jboolean
 android_mtp_MtpDevice_import_file(JNIEnv *env, jobject thiz, jint object_id, jstring dest_path)
 {
-#ifdef HAVE_ANDROID_OS
     MtpDevice* device = get_device_from_object(env, thiz);
     if (device) {
         const char *destPathStr = env->GetStringUTFChars(dest_path, NULL);
@@ -438,7 +395,7 @@
         env->ReleaseStringUTFChars(dest_path, destPathStr);
         return result;
     }
-#endif
+
     return false;
 }
 
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 0b998b9..e17e1e8 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -22,7 +22,6 @@
         FileSource.cpp                    \
         FLACExtractor.cpp                 \
         HTTPBase.cpp                      \
-        HTTPStream.cpp                    \
         JPEGSource.cpp                    \
         MP3Extractor.cpp                  \
         MPEG2TSWriter.cpp                 \
@@ -36,13 +35,11 @@
         MediaSourceSplitter.cpp           \
         MetaData.cpp                      \
         NuCachedSource2.cpp               \
-        NuHTTPDataSource.cpp              \
         OMXClient.cpp                     \
         OMXCodec.cpp                      \
         OggExtractor.cpp                  \
         SampleIterator.cpp                \
         SampleTable.cpp                   \
-        ShoutcastSource.cpp               \
         StagefrightMediaScanner.cpp       \
         StagefrightMetadataRetriever.cpp  \
         ThrottledSource.cpp               \
diff --git a/media/libstagefright/HTTPBase.cpp b/media/libstagefright/HTTPBase.cpp
index 0d24551..f9d8501 100644
--- a/media/libstagefright/HTTPBase.cpp
+++ b/media/libstagefright/HTTPBase.cpp
@@ -24,10 +24,11 @@
 #include "include/ChromiumHTTPDataSource.h"
 #endif
 
-#include "include/NuHTTPDataSource.h"
-
+#include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/ALooper.h>
+
 #include <cutils/properties.h>
+#include <cutils/qtaguid.h>
 
 namespace android {
 
@@ -44,14 +45,12 @@
 // static
 sp<HTTPBase> HTTPBase::Create(uint32_t flags) {
 #if CHROMIUM_AVAILABLE
-    char value[PROPERTY_VALUE_MAX];
-    if (!property_get("media.stagefright.use-chromium", value, NULL)
-            || (strcasecmp("false", value) && strcmp("0", value))) {
         return new ChromiumHTTPDataSource(flags);
-    } else
 #endif
     {
-        return new NuHTTPDataSource(flags);
+        TRESPASS();
+
+        return NULL;
     }
 }
 
@@ -135,4 +134,10 @@
     return true;
 }
 
+// static
+void HTTPBase::RegisterSocketUser(int s, uid_t uid) {
+    static const uint32_t kTag = 0xdeadbeef;
+    set_qtaguid(s, kTag, uid);
+}
+
 }  // namespace android
diff --git a/media/libstagefright/HTTPStream.cpp b/media/libstagefright/HTTPStream.cpp
deleted file mode 100644
index d526ebd..0000000
--- a/media/libstagefright/HTTPStream.cpp
+++ /dev/null
@@ -1,623 +0,0 @@
-/*
- * Copyright (C) 2009 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.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "HTTPStream"
-#include <utils/Log.h>
-
-#include "include/HTTPStream.h"
-
-#include <sys/socket.h>
-
-#include <arpa/inet.h>
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <media/stagefright/foundation/ADebug.h>
-
-#include <openssl/ssl.h>
-
-namespace android {
-
-// static
-const char *HTTPStream::kStatusKey = ":status:";  // MUST be lowercase.
-
-HTTPStream::HTTPStream()
-    : mState(READY),
-      mUIDValid(false),
-      mSocket(-1),
-      mSSLContext(NULL),
-      mSSL(NULL) {
-}
-
-HTTPStream::~HTTPStream() {
-    disconnect();
-
-    if (mSSLContext != NULL) {
-        SSL_CTX_free((SSL_CTX *)mSSLContext);
-        mSSLContext = NULL;
-    }
-}
-
-void HTTPStream::setUID(uid_t uid) {
-    mUIDValid = true;
-    mUID = uid;
-}
-
-static bool MakeSocketBlocking(int s, bool blocking) {
-    // Make socket non-blocking.
-    int flags = fcntl(s, F_GETFL, 0);
-    if (flags == -1) {
-        return false;
-    }
-
-    if (blocking) {
-        flags &= ~O_NONBLOCK;
-    } else {
-        flags |= O_NONBLOCK;
-    }
-
-    return fcntl(s, F_SETFL, flags) != -1;
-}
-
-static status_t MyConnect(
-        int s, const struct sockaddr *addr, socklen_t addrlen) {
-    status_t result = UNKNOWN_ERROR;
-
-    MakeSocketBlocking(s, false);
-
-    if (connect(s, addr, addrlen) == 0) {
-        result = OK;
-    } else if (errno != EINPROGRESS) {
-        result = -errno;
-    } else {
-        for (;;) {
-            fd_set rs, ws;
-            FD_ZERO(&rs);
-            FD_ZERO(&ws);
-            FD_SET(s, &rs);
-            FD_SET(s, &ws);
-
-            struct timeval tv;
-            tv.tv_sec = 0;
-            tv.tv_usec = 100000ll;
-
-            int nfds = ::select(s + 1, &rs, &ws, NULL, &tv);
-
-            if (nfds < 0) {
-                if (errno == EINTR) {
-                    continue;
-                }
-
-                result = -errno;
-                break;
-            }
-
-            if (FD_ISSET(s, &ws) && !FD_ISSET(s, &rs)) {
-                result = OK;
-                break;
-            }
-
-            if (FD_ISSET(s, &rs) || FD_ISSET(s, &ws)) {
-                // Get the pending error.
-                int error = 0;
-                socklen_t errorLen = sizeof(error);
-                if (getsockopt(s, SOL_SOCKET, SO_ERROR, &error, &errorLen) == -1) {
-                    // Couldn't get the real error, so report why not.
-                    result = -errno;
-                } else {
-                    result = -error;
-                }
-                break;
-            }
-
-            // Timeout expired. Try again.
-        }
-    }
-
-    MakeSocketBlocking(s, true);
-
-    return result;
-}
-
-// Apparently under out linux closing a socket descriptor from one thread
-// will not unblock a pending send/recv on that socket on another thread.
-static ssize_t MySendReceive(
-        int s, void *data, size_t size, int flags, bool sendData) {
-    ssize_t result = 0;
-
-    if (s < 0) {
-        return -1;
-    }
-    while (size > 0) {
-        fd_set rs, ws, es;
-        FD_ZERO(&rs);
-        FD_ZERO(&ws);
-        FD_ZERO(&es);
-        FD_SET(s, sendData ? &ws : &rs);
-        FD_SET(s, &es);
-
-        struct timeval tv;
-        tv.tv_sec = 0;
-        tv.tv_usec = 100000ll;
-
-        int nfds = ::select(
-                s + 1,
-                sendData ? NULL : &rs,
-                sendData ? &ws : NULL,
-                &es,
-                &tv);
-
-        if (nfds < 0) {
-            if (errno == EINTR) {
-                continue;
-            }
-
-            result = -errno;
-            break;
-        } else if (nfds == 0) {
-            // timeout
-
-            continue;
-        }
-
-        CHECK_EQ(nfds, 1);
-
-        ssize_t nbytes =
-            sendData ? send(s, data, size, flags) : recv(s, data, size, flags);
-
-        if (nbytes < 0) {
-            if (errno == EINTR) {
-                continue;
-            }
-
-            result = -errno;
-            break;
-        } else if (nbytes == 0) {
-            result = 0;
-            break;
-        }
-
-        data = (uint8_t *)data + nbytes;
-        size -= nbytes;
-
-        result = nbytes;
-        break;
-    }
-
-    return result;
-}
-
-static ssize_t MySend(int s, const void *data, size_t size, int flags) {
-    return MySendReceive(
-            s, const_cast<void *>(data), size, flags, true /* sendData */);
-}
-
-static ssize_t MyReceive(int s, void *data, size_t size, int flags) {
-    return MySendReceive(s, data, size, flags, false /* sendData */);
-}
-
-status_t HTTPStream::connect(const char *server, int port, bool https) {
-    if (port < 0) {
-        port = https ? 443 : 80;
-    }
-
-    Mutex::Autolock autoLock(mLock);
-
-    status_t err = OK;
-
-    if (mState == CONNECTED) {
-        return ERROR_ALREADY_CONNECTED;
-    }
-
-    if (port < 0 || port > (int) USHRT_MAX) {
-        return UNKNOWN_ERROR;
-    }
-
-    char service[sizeof("65536")];
-    sprintf(service, "%d", port);
-    struct addrinfo hints, *ai;
-    memset(&hints, 0, sizeof(hints));
-    hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICSERV;
-    hints.ai_socktype = SOCK_STREAM;
-
-    int ret = getaddrinfo(server, service, &hints, &ai);
-    if (ret) {
-        return ERROR_UNKNOWN_HOST;
-    }
-
-    CHECK_EQ(mSocket, -1);
-
-    mState = CONNECTING;
-    status_t res = -1;
-    struct addrinfo *tmp;
-    for (tmp = ai; tmp; tmp = tmp->ai_next) {
-        mSocket = socket(tmp->ai_family, tmp->ai_socktype, tmp->ai_protocol);
-        if (mSocket < 0) {
-            continue;
-        }
-
-        if (mUIDValid) {
-            RegisterSocketUser(mSocket, mUID);
-        }
-
-        setReceiveTimeout(30);  // Time out reads after 30 secs by default.
-
-        int s = mSocket;
-
-        mLock.unlock();
-
-        res = MyConnect(s, tmp->ai_addr, tmp->ai_addrlen);
-
-        mLock.lock();
-
-        if (mState != CONNECTING) {
-            close(s);
-            freeaddrinfo(ai);
-            return UNKNOWN_ERROR;
-        }
-
-        if (res == OK) {
-            break;
-        }
-
-        close(s);
-    }
-
-    freeaddrinfo(ai);
-
-    if (res != OK) {
-        close(mSocket);
-        mSocket = -1;
-
-        mState = READY;
-        return res;
-    }
-
-    if (https) {
-        CHECK(mSSL == NULL);
-
-        if (mSSLContext == NULL) {
-            SSL_library_init();
-
-            mSSLContext = SSL_CTX_new(TLSv1_client_method());
-
-            if (mSSLContext == NULL) {
-                LOGE("failed to create SSL context");
-                mState = READY;
-                return ERROR_IO;
-            }
-        }
-
-        mSSL = SSL_new((SSL_CTX *)mSSLContext);
-
-        if (mSSL == NULL) {
-            LOGE("failed to create SSL session");
-
-            mState = READY;
-            return ERROR_IO;
-        }
-
-        int res = SSL_set_fd((SSL *)mSSL, mSocket);
-
-        if (res == 1) {
-            res = SSL_connect((SSL *)mSSL);
-        }
-
-        if (res != 1) {
-            SSL_free((SSL *)mSSL);
-            mSSL = NULL;
-
-            LOGE("failed to connect over SSL");
-            mState = READY;
-
-            return ERROR_IO;
-        }
-    }
-
-    mState = CONNECTED;
-
-    return OK;
-}
-
-status_t HTTPStream::disconnect() {
-    Mutex::Autolock autoLock(mLock);
-
-    if (mState != CONNECTED && mState != CONNECTING) {
-        return ERROR_NOT_CONNECTED;
-    }
-
-    if (mSSL != NULL) {
-        SSL_shutdown((SSL *)mSSL);
-
-        SSL_free((SSL *)mSSL);
-        mSSL = NULL;
-    }
-
-    CHECK(mSocket >= 0);
-    close(mSocket);
-    mSocket = -1;
-
-    mState = READY;
-
-    return OK;
-}
-
-status_t HTTPStream::send(const char *data, size_t size) {
-    if (mState != CONNECTED) {
-        return ERROR_NOT_CONNECTED;
-    }
-
-    while (size > 0) {
-        ssize_t n;
-        if (mSSL != NULL) {
-            n = SSL_write((SSL *)mSSL, data, size);
-
-            if (n < 0) {
-                n = -SSL_get_error((SSL *)mSSL, n);
-            }
-        } else {
-            n = MySend(mSocket, data, size, 0);
-        }
-
-        if (n < 0) {
-            disconnect();
-
-            return n;
-        } else if (n == 0) {
-            disconnect();
-
-            return ERROR_CONNECTION_LOST;
-        }
-
-        size -= (size_t)n;
-        data += (size_t)n;
-    }
-
-    return OK;
-}
-
-status_t HTTPStream::send(const char *data) {
-    return send(data, strlen(data));
-}
-
-// A certain application spawns a local webserver that sends invalid responses,
-// specifically it terminates header line with only a newline instead of the
-// CRLF (carriage-return followed by newline) required by the HTTP specs.
-// The workaround accepts both behaviours but could potentially break
-// legitimate responses that use a single newline to "fold" headers, which is
-// why it's not yet on by default.
-#define WORKAROUND_FOR_MISSING_CR       1
-
-status_t HTTPStream::receive_line(char *line, size_t size) {
-    if (mState != CONNECTED) {
-        return ERROR_NOT_CONNECTED;
-    }
-
-    bool saw_CR = false;
-    size_t length = 0;
-
-    for (;;) {
-        char c;
-        ssize_t n;
-        if (mSSL != NULL) {
-            n = SSL_read((SSL *)mSSL, &c, 1);
-
-            if (n < 0) {
-                n = -SSL_get_error((SSL *)mSSL, n);
-            }
-        } else {
-            n = MyReceive(mSocket, &c, 1, 0);
-        }
-
-        if (n < 0) {
-            disconnect();
-
-            return ERROR_IO;
-        } else if (n == 0) {
-            disconnect();
-
-            return ERROR_CONNECTION_LOST;
-        }
-
-#if WORKAROUND_FOR_MISSING_CR
-        if (c == '\n') {
-            // We have a complete line.
-
-            line[saw_CR ? length - 1 : length] = '\0';
-            return OK;
-        }
-#else
-        if (saw_CR &&  c == '\n') {
-            // We have a complete line.
-
-            line[length - 1] = '\0';
-            return OK;
-        }
-#endif
-
-        saw_CR = (c == '\r');
-
-        if (length + 1 >= size) {
-            return ERROR_MALFORMED;
-        }
-        line[length++] = c;
-    }
-}
-
-status_t HTTPStream::receive_header(int *http_status) {
-    *http_status = -1;
-    mHeaders.clear();
-
-    char line[2048];
-    status_t err = receive_line(line, sizeof(line));
-    if (err != OK) {
-        return err;
-    }
-
-    mHeaders.add(AString(kStatusKey), AString(line));
-
-    char *spacePos = strchr(line, ' ');
-    if (spacePos == NULL) {
-        // Malformed response?
-        return UNKNOWN_ERROR;
-    }
-
-    char *status_start = spacePos + 1;
-    char *status_end = status_start;
-    while (isdigit(*status_end)) {
-        ++status_end;
-    }
-
-    if (status_end == status_start) {
-        // Malformed response, status missing?
-        return UNKNOWN_ERROR;
-    }
-
-    memmove(line, status_start, status_end - status_start);
-    line[status_end - status_start] = '\0';
-
-    long tmp = strtol(line, NULL, 10);
-    if (tmp < 0 || tmp > 999) {
-        return UNKNOWN_ERROR;
-    }
-
-    *http_status = (int)tmp;
-
-    for (;;) {
-        err = receive_line(line, sizeof(line));
-        if (err != OK) {
-            return err;
-        }
-
-        if (*line == '\0') {
-            // Empty line signals the end of the header.
-            break;
-        }
-
-        // puts(line);
-
-        char *colonPos = strchr(line, ':');
-        if (colonPos == NULL) {
-            AString key = line;
-            key.tolower();
-
-            mHeaders.add(key, AString());
-        } else {
-            char *end_of_key = colonPos;
-            while (end_of_key > line && isspace(end_of_key[-1])) {
-                --end_of_key;
-            }
-
-            char *start_of_value = colonPos + 1;
-            while (isspace(*start_of_value)) {
-                ++start_of_value;
-            }
-
-            *end_of_key = '\0';
-
-            AString key = line;
-            key.tolower();
-
-            mHeaders.add(key, AString(start_of_value));
-        }
-    }
-
-    return OK;
-}
-
-ssize_t HTTPStream::receive(void *data, size_t size) {
-    size_t total = 0;
-    while (total < size) {
-        ssize_t n;
-        if (mSSL != NULL) {
-            n = SSL_read((SSL *)mSSL, (char *)data + total, size - total);
-
-            if (n < 0) {
-                n = -SSL_get_error((SSL *)mSSL, n);
-            }
-        } else {
-            n = MyReceive(mSocket, (char *)data + total, size - total, 0);
-        }
-
-        if (n < 0) {
-            LOGE("recv failed, errno = %d (%s)", (int)n, strerror(-n));
-
-            disconnect();
-            return (ssize_t)ERROR_IO;
-        } else if (n == 0) {
-            disconnect();
-
-            LOGE("recv failed, server is gone, total received: %d bytes",
-                 total);
-
-            return total == 0 ? (ssize_t)ERROR_CONNECTION_LOST : total;
-        }
-
-        total += (size_t)n;
-    }
-
-    return (ssize_t)total;
-}
-
-bool HTTPStream::find_header_value(const AString &key, AString *value) const {
-    AString key_lower = key;
-    key_lower.tolower();
-
-    ssize_t index = mHeaders.indexOfKey(key_lower);
-    if (index < 0) {
-        value->clear();
-        return false;
-    }
-
-    *value = mHeaders.valueAt(index);
-
-    return true;
-}
-
-void HTTPStream::setReceiveTimeout(int seconds) {
-    if (seconds < 0) {
-        // Disable the timeout.
-        seconds = 0;
-    }
-
-    struct timeval tv;
-    tv.tv_usec = 0;
-    tv.tv_sec = seconds;
-    CHECK_EQ(0, setsockopt(mSocket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)));
-}
-
-// static
-void HTTPStream::RegisterSocketUser(int s, uid_t uid) {
-    // Lower bits MUST be 0.
-    static const uint64_t kTag = 0xdeadbeef00000000ll;
-
-    AString line = StringPrintf("t %d %llu %d", s, kTag, uid);
-
-    int fd = open("/proc/net/xt_qtaguid/ctrl", O_WRONLY);
-    write(fd, line.c_str(), line.size());
-    close(fd);
-    fd = -1;
-}
-
-}  // namespace android
-
diff --git a/media/libstagefright/NuHTTPDataSource.cpp b/media/libstagefright/NuHTTPDataSource.cpp
deleted file mode 100644
index 2949767..0000000
--- a/media/libstagefright/NuHTTPDataSource.cpp
+++ /dev/null
@@ -1,560 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "NuHTTPDataSource"
-#include <utils/Log.h>
-
-#include "include/NuHTTPDataSource.h"
-
-#include <cutils/properties.h>
-#include <media/stagefright/foundation/ALooper.h>
-#include <media/stagefright/MediaDebug.h>
-#include <media/stagefright/MediaErrors.h>
-
-namespace android {
-
-static bool ParseSingleUnsignedLong(
-        const char *from, unsigned long *x) {
-    char *end;
-    *x = strtoul(from, &end, 10);
-
-    if (end == from || *end != '\0') {
-        return false;
-    }
-
-    return true;
-}
-
-static bool ParseURL(
-        const char *url, String8 *host, unsigned *port,
-        String8 *path, bool *https) {
-    host->setTo("");
-    *port = 0;
-    path->setTo("");
-
-    size_t hostStart;
-    if (!strncasecmp("http://", url, 7)) {
-        hostStart = 7;
-        *https = false;
-    } else if (!strncasecmp("https://", url, 8)) {
-        hostStart = 8;
-        *https = true;
-    } else {
-        return false;
-    }
-
-    const char *slashPos = strchr(&url[hostStart], '/');
-
-    if (slashPos == NULL) {
-        host->setTo(&url[hostStart]);
-        path->setTo("/");
-    } else {
-        host->setTo(&url[hostStart], slashPos - &url[hostStart]);
-        path->setTo(slashPos);
-    }
-
-    const char *colonPos = strchr(host->string(), ':');
-
-    if (colonPos != NULL) {
-        unsigned long x;
-        if (!ParseSingleUnsignedLong(colonPos + 1, &x) || x >= 65536) {
-            return false;
-        }
-
-        *port = x;
-
-        size_t colonOffset = colonPos - host->string();
-        String8 tmp(host->string(), colonOffset);
-        *host = tmp;
-    } else {
-        *port = (*https) ? 443 : 80;
-    }
-
-    return true;
-}
-
-NuHTTPDataSource::NuHTTPDataSource(uint32_t flags)
-    : mFlags(flags),
-      mState(DISCONNECTED),
-      mPort(0),
-      mHTTPS(false),
-      mOffset(0),
-      mContentLength(0),
-      mContentLengthValid(false),
-      mHasChunkedTransferEncoding(false),
-      mChunkDataBytesLeft(0),
-      mDecryptHandle(NULL),
-      mDrmManagerClient(NULL) {
-}
-
-NuHTTPDataSource::~NuHTTPDataSource() {
-    if (mDecryptHandle != NULL) {
-        // To release mDecryptHandle
-        CHECK(mDrmManagerClient);
-        mDrmManagerClient->closeDecryptSession(mDecryptHandle);
-        mDecryptHandle = NULL;
-    }
-
-    if (mDrmManagerClient != NULL) {
-        delete mDrmManagerClient;
-        mDrmManagerClient = NULL;
-    }
-}
-
-status_t NuHTTPDataSource::connect(
-        const char *uri,
-        const KeyedVector<String8, String8> *overrides,
-        off64_t offset) {
-    String8 headers;
-    MakeFullHeaders(overrides, &headers);
-
-    return connect(uri, headers, offset);
-}
-
-status_t NuHTTPDataSource::connect(
-        const char *uri,
-        const String8 &headers,
-        off64_t offset) {
-    String8 host, path;
-    unsigned port;
-
-    mUri = uri;
-    mContentType = String8("application/octet-stream");
-
-    bool https;
-    if (!ParseURL(uri, &host, &port, &path, &https)) {
-        return ERROR_MALFORMED;
-    }
-
-    uid_t uid;
-    if (getUID(&uid)) {
-        mHTTP.setUID(uid);
-    }
-
-    return connect(host, port, path, https, headers, offset);
-}
-
-static bool IsRedirectStatusCode(int httpStatus) {
-    return httpStatus == 301 || httpStatus == 302
-        || httpStatus == 303 || httpStatus == 307;
-}
-
-status_t NuHTTPDataSource::connect(
-        const char *host, unsigned port, const char *path,
-        bool https,
-        const String8 &headers,
-        off64_t offset) {
-    if (!(mFlags & kFlagIncognito)) {
-        LOGI("connect to %s:%u%s @%lld", host, port, path, offset);
-    } else {
-        LOGI("connect to <URL suppressed> @%lld", offset);
-    }
-
-    bool needsToReconnect = true;
-
-    if (mState == CONNECTED && host == mHost && port == mPort
-            && https == mHTTPS && offset == mOffset) {
-        if (mContentLengthValid && mOffset == mContentLength) {
-            LOGI("Didn't have to reconnect, old one's still good.");
-            needsToReconnect = false;
-        }
-    }
-
-    mHost = host;
-    mPort = port;
-    mPath = path;
-    mHTTPS = https;
-    mHeaders = headers;
-
-    status_t err = OK;
-
-    mState = CONNECTING;
-
-    if (needsToReconnect) {
-        mHTTP.disconnect();
-        err = mHTTP.connect(host, port, https);
-    }
-
-    if (err != OK) {
-        mState = DISCONNECTED;
-    } else if (mState != CONNECTING) {
-        err = UNKNOWN_ERROR;
-    } else {
-        mState = CONNECTED;
-
-        mOffset = offset;
-        mContentLength = 0;
-        mContentLengthValid = false;
-
-        String8 request("GET ");
-        request.append(mPath);
-        request.append(" HTTP/1.1\r\n");
-        request.append("Host: ");
-        request.append(mHost);
-        if (mPort != 80) {
-            request.append(StringPrintf(":%u", mPort).c_str());
-        }
-        request.append("\r\n");
-
-        if (offset != 0) {
-            char rangeHeader[128];
-            sprintf(rangeHeader, "Range: bytes=%lld-\r\n", offset);
-            request.append(rangeHeader);
-        }
-
-        request.append(mHeaders);
-        request.append("\r\n");
-
-        int httpStatus;
-        if ((err = mHTTP.send(request.string(), request.size())) != OK
-                || (err = mHTTP.receive_header(&httpStatus)) != OK) {
-            mHTTP.disconnect();
-            mState = DISCONNECTED;
-            return err;
-        }
-
-        if (IsRedirectStatusCode(httpStatus)) {
-            AString value;
-            CHECK(mHTTP.find_header_value("Location", &value));
-
-            mState = DISCONNECTED;
-
-            mHTTP.disconnect();
-
-            return connect(value.c_str(), headers, offset);
-        }
-
-        if (httpStatus < 200 || httpStatus >= 300) {
-            mState = DISCONNECTED;
-            mHTTP.disconnect();
-
-            return ERROR_IO;
-        }
-
-        mHasChunkedTransferEncoding = false;
-
-        {
-            AString value;
-            if (mHTTP.find_header_value("Transfer-Encoding", &value)) {
-                // We don't currently support any transfer encodings but
-                // chunked.
-
-                if (!strcasecmp(value.c_str(), "chunked")) {
-                    LOGI("Chunked transfer encoding applied.");
-                    mHasChunkedTransferEncoding = true;
-                    mChunkDataBytesLeft = 0;
-                } else {
-                    mState = DISCONNECTED;
-                    mHTTP.disconnect();
-
-                    LOGE("We don't support '%s' transfer encoding.", value.c_str());
-
-                    return ERROR_UNSUPPORTED;
-                }
-            }
-        }
-
-        {
-            AString value;
-            if (mHTTP.find_header_value("Content-Type", &value)) {
-                mContentType = String8(value.c_str());
-            } else {
-                mContentType = String8("application/octet-stream");
-            }
-        }
-
-        applyTimeoutResponse();
-
-        if (offset == 0) {
-            AString value;
-            unsigned long x;
-            if (mHTTP.find_header_value(AString("Content-Length"), &value)
-                    && ParseSingleUnsignedLong(value.c_str(), &x)) {
-                mContentLength = (off64_t)x;
-                mContentLengthValid = true;
-            } else {
-                LOGW("Server did not give us the content length!");
-            }
-        } else {
-            if (httpStatus != 206 /* Partial Content */) {
-                // We requested a range but the server didn't support that.
-                LOGE("We requested a range but the server didn't "
-                     "support that.");
-                return ERROR_UNSUPPORTED;
-            }
-
-            AString value;
-            unsigned long x;
-            if (mHTTP.find_header_value(AString("Content-Range"), &value)) {
-                const char *slashPos = strchr(value.c_str(), '/');
-                if (slashPos != NULL
-                        && ParseSingleUnsignedLong(slashPos + 1, &x)) {
-                    mContentLength = x;
-                    mContentLengthValid = true;
-                }
-            }
-        }
-    }
-
-    return err;
-}
-
-void NuHTTPDataSource::disconnect() {
-    if (mState == CONNECTING || mState == CONNECTED) {
-        mHTTP.disconnect();
-    }
-    mState = DISCONNECTED;
-}
-
-status_t NuHTTPDataSource::initCheck() const {
-    return mState == CONNECTED ? OK : NO_INIT;
-}
-
-ssize_t NuHTTPDataSource::internalRead(void *data, size_t size) {
-    if (!mHasChunkedTransferEncoding) {
-        return mHTTP.receive(data, size);
-    }
-
-    if (mChunkDataBytesLeft < 0) {
-        return 0;
-    } else if (mChunkDataBytesLeft == 0) {
-        char line[1024];
-        status_t err = mHTTP.receive_line(line, sizeof(line));
-
-        if (err != OK) {
-            return err;
-        }
-
-        LOGV("line = '%s'", line);
-
-        char *end;
-        unsigned long n = strtoul(line, &end, 16);
-
-        if (end == line || (*end != ';' && *end != '\0')) {
-            LOGE("malformed HTTP chunk '%s'", line);
-            return ERROR_MALFORMED;
-        }
-
-        mChunkDataBytesLeft = n;
-        LOGV("chunk data size = %lu", n);
-
-        if (mChunkDataBytesLeft == 0) {
-            mChunkDataBytesLeft = -1;
-            return 0;
-        }
-
-        // fall through
-    }
-
-    if (size > (size_t)mChunkDataBytesLeft) {
-        size = mChunkDataBytesLeft;
-    }
-
-    ssize_t n = mHTTP.receive(data, size);
-
-    if (n < 0) {
-        return n;
-    }
-
-    mChunkDataBytesLeft -= (size_t)n;
-
-    if (mChunkDataBytesLeft == 0) {
-        char line[1024];
-        status_t err = mHTTP.receive_line(line, sizeof(line));
-
-        if (err != OK) {
-            return err;
-        }
-
-        if (line[0] != '\0') {
-            LOGE("missing HTTP chunk terminator.");
-            return ERROR_MALFORMED;
-        }
-    }
-
-    return n;
-}
-
-ssize_t NuHTTPDataSource::readAt(off64_t offset, void *data, size_t size) {
-    LOGV("readAt offset %ld, size %d", offset, size);
-
-    Mutex::Autolock autoLock(mLock);
-
-    if (offset != mOffset) {
-        String8 host = mHost;
-        String8 path = mPath;
-        String8 headers = mHeaders;
-        status_t err = connect(host, mPort, path, mHTTPS, headers, offset);
-
-        if (err != OK) {
-            return err;
-        }
-    }
-
-    if (mContentLengthValid) {
-        size_t avail =
-            (offset >= mContentLength) ? 0 : mContentLength - offset;
-
-        if (size > avail) {
-            size = avail;
-        }
-    }
-
-    size_t numBytesRead = 0;
-    while (numBytesRead < size) {
-        int64_t startTimeUs = ALooper::GetNowUs();
-
-        ssize_t n =
-            internalRead((uint8_t *)data + numBytesRead, size - numBytesRead);
-
-        if (n < 0) {
-            if (numBytesRead == 0 || mContentLengthValid) {
-                return n;
-            }
-
-            // If there was an error we want to at least return the data
-            // we've already successfully read. The next call to read will
-            // then return the error.
-            n = 0;
-        }
-
-        int64_t delayUs = ALooper::GetNowUs() - startTimeUs;
-        addBandwidthMeasurement(n, delayUs);
-
-        numBytesRead += (size_t)n;
-
-        if (n == 0) {
-            if (mContentLengthValid) {
-                // We know the content length and made sure not to read beyond
-                // it and yet the server closed the connection on us.
-                return ERROR_IO;
-            }
-
-            break;
-        }
-    }
-
-    mOffset += numBytesRead;
-
-    return numBytesRead;
-}
-
-status_t NuHTTPDataSource::getSize(off64_t *size) {
-    *size = 0;
-
-    if (mState != CONNECTED) {
-        return ERROR_IO;
-    }
-
-    if (mContentLengthValid) {
-        *size = mContentLength;
-        return OK;
-    }
-
-    return ERROR_UNSUPPORTED;
-}
-
-uint32_t NuHTTPDataSource::flags() {
-    return kWantsPrefetching | kIsHTTPBasedSource;
-}
-
-// static
-void NuHTTPDataSource::MakeFullHeaders(
-        const KeyedVector<String8, String8> *overrides, String8 *headers) {
-    headers->setTo("");
-
-    headers->append("User-Agent: stagefright/1.1 (Linux;Android ");
-
-#if (PROPERTY_VALUE_MAX < 8)
-#error "PROPERTY_VALUE_MAX must be at least 8"
-#endif
-
-    char value[PROPERTY_VALUE_MAX];
-    property_get("ro.build.version.release", value, "Unknown");
-    headers->append(value);
-    headers->append(")\r\n");
-
-    if (overrides == NULL) {
-        return;
-    }
-
-    for (size_t i = 0; i < overrides->size(); ++i) {
-        String8 line;
-        line.append(overrides->keyAt(i));
-        line.append(": ");
-        line.append(overrides->valueAt(i));
-        line.append("\r\n");
-
-        headers->append(line);
-    }
-}
-
-void NuHTTPDataSource::applyTimeoutResponse() {
-    AString timeout;
-    if (mHTTP.find_header_value("X-SocketTimeout", &timeout)) {
-        const char *s = timeout.c_str();
-        char *end;
-        long tmp = strtol(s, &end, 10);
-        if (end == s || *end != '\0') {
-            LOGW("Illegal X-SocketTimeout value given.");
-            return;
-        }
-
-        LOGI("overriding default timeout, new timeout is %ld seconds", tmp);
-        mHTTP.setReceiveTimeout(tmp);
-    }
-}
-
-sp<DecryptHandle> NuHTTPDataSource::DrmInitialization() {
-    if (mDrmManagerClient == NULL) {
-        mDrmManagerClient = new DrmManagerClient();
-    }
-
-    if (mDrmManagerClient == NULL) {
-        return NULL;
-    }
-
-    if (mDecryptHandle == NULL) {
-        /* Note if redirect occurs, mUri is the redirect uri instead of the
-         * original one
-         */
-        mDecryptHandle = mDrmManagerClient->openDecryptSession(mUri);
-    }
-
-    if (mDecryptHandle == NULL) {
-        delete mDrmManagerClient;
-        mDrmManagerClient = NULL;
-    }
-
-    return mDecryptHandle;
-}
-
-void NuHTTPDataSource::getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client) {
-    handle = mDecryptHandle;
-
-    *client = mDrmManagerClient;
-}
-
-String8 NuHTTPDataSource::getUri() {
-    return mUri;
-}
-
-String8 NuHTTPDataSource::getMIMEType() const {
-    return mContentType;
-}
-
-}  // namespace android
diff --git a/media/libstagefright/ShoutcastSource.cpp b/media/libstagefright/ShoutcastSource.cpp
deleted file mode 100644
index 783f2d0..0000000
--- a/media/libstagefright/ShoutcastSource.cpp
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (C) 2009 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.
- */
-
-#include "include/HTTPStream.h"
-
-#include <stdlib.h>
-
-#include <media/stagefright/MediaBuffer.h>
-#include <media/stagefright/MediaBufferGroup.h>
-#include <media/stagefright/MediaDebug.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MetaData.h>
-#include <media/stagefright/ShoutcastSource.h>
-
-namespace android {
-
-ShoutcastSource::ShoutcastSource(HTTPStream *http)
-    : mHttp(http),
-      mMetaDataOffset(0),
-      mBytesUntilMetaData(0),
-      mGroup(NULL),
-      mStarted(false) {
-    AString metaint;
-    if (mHttp->find_header_value("icy-metaint", &metaint)) {
-        char *end;
-        const char *start = metaint.c_str();
-        mMetaDataOffset = strtol(start, &end, 10);
-        CHECK(end > start && *end == '\0');
-        CHECK(mMetaDataOffset > 0);
-
-        mBytesUntilMetaData = mMetaDataOffset;
-    }
-}
-
-ShoutcastSource::~ShoutcastSource() {
-    if (mStarted) {
-        stop();
-    }
-
-    delete mHttp;
-    mHttp = NULL;
-}
-
-status_t ShoutcastSource::start(MetaData *) {
-    CHECK(!mStarted);
-
-    mGroup = new MediaBufferGroup;
-    mGroup->add_buffer(new MediaBuffer(4096));  // XXX
-
-    mStarted = true;
-
-    return OK;
-}
-
-status_t ShoutcastSource::stop() {
-    CHECK(mStarted);
-
-    delete mGroup;
-    mGroup = NULL;
-
-    mStarted = false;
-
-    return OK;
-}
-
-sp<MetaData> ShoutcastSource::getFormat() {
-    sp<MetaData> meta = new MetaData;
-    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG);
-    meta->setInt32(kKeySampleRate, 44100);
-    meta->setInt32(kKeyChannelCount, 2);  // XXX
-
-    return meta;
-}
-
-status_t ShoutcastSource::read(
-        MediaBuffer **out, const ReadOptions *options) {
-    CHECK(mStarted);
-
-    *out = NULL;
-
-    int64_t seekTimeUs;
-    ReadOptions::SeekMode mode;
-    if (options && options->getSeekTo(&seekTimeUs, &mode)) {
-        return ERROR_UNSUPPORTED;
-    }
-
-    MediaBuffer *buffer;
-    status_t err = mGroup->acquire_buffer(&buffer);
-    if (err != OK) {
-        return err;
-    }
-
-    *out = buffer;
-
-    size_t num_bytes = buffer->size();
-    if (mMetaDataOffset > 0 && num_bytes > mBytesUntilMetaData) {
-        num_bytes = mBytesUntilMetaData;
-    }
-
-    ssize_t n = mHttp->receive(buffer->data(), num_bytes);
-
-    if (n <= 0) {
-        return (status_t)n;
-    }
-
-    buffer->set_range(0, n);
-
-    mBytesUntilMetaData -= (size_t)n;
-
-    if (mBytesUntilMetaData == 0) {
-        unsigned char num_16_byte_blocks = 0;
-        n = mHttp->receive((char *)&num_16_byte_blocks, 1);
-        CHECK_EQ(n, 1);
-
-        char meta[255 * 16];
-        size_t meta_size = num_16_byte_blocks * 16;
-        size_t meta_length = 0;
-        while (meta_length < meta_size) {
-            n = mHttp->receive(&meta[meta_length], meta_size - meta_length);
-            if (n <= 0) {
-                return (status_t)n;
-            }
-
-            meta_length += (size_t) n;
-        }
-
-        while (meta_length > 0 && meta[meta_length - 1] == '\0') {
-            --meta_length;
-        }
-
-        if (meta_length > 0) {
-            // Technically we should probably attach this meta data to the
-            // next buffer. XXX
-            buffer->meta_data()->setData('shou', 'shou', meta, meta_length);
-        }
-
-        mBytesUntilMetaData = mMetaDataOffset;
-    }
-
-    return OK;
-}
-
-}  // namespace android
-
diff --git a/media/libstagefright/include/HTTPBase.h b/media/libstagefright/include/HTTPBase.h
index 2e25dd9..0e9af69 100644
--- a/media/libstagefright/include/HTTPBase.h
+++ b/media/libstagefright/include/HTTPBase.h
@@ -53,6 +53,8 @@
 
     static sp<HTTPBase> Create(uint32_t flags = 0);
 
+    static void RegisterSocketUser(int s, uid_t uid);
+
 protected:
     void addBandwidthMeasurement(size_t numBytes, int64_t delayUs);
 
diff --git a/media/libstagefright/include/HTTPStream.h b/media/libstagefright/include/HTTPStream.h
deleted file mode 100644
index 88ba9d6..0000000
--- a/media/libstagefright/include/HTTPStream.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2009 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 HTTP_STREAM_H_
-
-#define HTTP_STREAM_H_
-
-#include <sys/types.h>
-
-#include <media/stagefright/foundation/AString.h>
-#include <media/stagefright/MediaErrors.h>
-#include <utils/KeyedVector.h>
-#include <utils/threads.h>
-
-namespace android {
-
-class HTTPStream {
-public:
-    HTTPStream();
-    ~HTTPStream();
-
-    void setUID(uid_t uid);
-
-    status_t connect(const char *server, int port = -1, bool https = false);
-    status_t disconnect();
-
-    status_t send(const char *data, size_t size);
-
-    // Assumes data is a '\0' terminated string.
-    status_t send(const char *data);
-
-    // Receive up to "size" bytes of data.
-    ssize_t receive(void *data, size_t size);
-
-    status_t receive_header(int *http_status);
-
-    // The header key used to retrieve the status line.
-    static const char *kStatusKey;
-
-    bool find_header_value(
-            const AString &key, AString *value) const;
-
-    // Pass a negative value to disable the timeout.
-    void setReceiveTimeout(int seconds);
-
-    // Receive a line of data terminated by CRLF, line will be '\0' terminated
-    // _excluding_ the termianting CRLF.
-    status_t receive_line(char *line, size_t size);
-
-    static void RegisterSocketUser(int s, uid_t uid);
-
-private:
-    enum State {
-        READY,
-        CONNECTING,
-        CONNECTED
-    };
-
-    State mState;
-    Mutex mLock;
-
-    bool mUIDValid;
-    uid_t mUID;
-
-    int mSocket;
-
-    KeyedVector<AString, AString> mHeaders;
-
-    void *mSSLContext;
-    void *mSSL;
-
-    HTTPStream(const HTTPStream &);
-    HTTPStream &operator=(const HTTPStream &);
-};
-
-}  // namespace android
-
-#endif  // HTTP_STREAM_H_
diff --git a/media/libstagefright/include/NuHTTPDataSource.h b/media/libstagefright/include/NuHTTPDataSource.h
deleted file mode 100644
index c265b3a..0000000
--- a/media/libstagefright/include/NuHTTPDataSource.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2010 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 NU_HTTP_DATA_SOURCE_H_
-
-#define NU_HTTP_DATA_SOURCE_H_
-
-#include <utils/List.h>
-#include <utils/String8.h>
-#include <utils/threads.h>
-
-#include "HTTPStream.h"
-#include "include/HTTPBase.h"
-
-namespace android {
-
-struct NuHTTPDataSource : public HTTPBase {
-    NuHTTPDataSource(uint32_t flags = 0);
-
-    virtual status_t connect(
-            const char *uri,
-            const KeyedVector<String8, String8> *headers = NULL,
-            off64_t offset = 0);
-
-    virtual void disconnect();
-
-    virtual status_t initCheck() const;
-
-    virtual ssize_t readAt(off64_t offset, void *data, size_t size);
-    virtual status_t getSize(off64_t *size);
-    virtual uint32_t flags();
-
-    virtual sp<DecryptHandle> DrmInitialization();
-    virtual void getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client);
-    virtual String8 getUri();
-
-    virtual String8 getMIMEType() const;
-
-protected:
-    virtual ~NuHTTPDataSource();
-
-private:
-    enum State {
-        DISCONNECTED,
-        CONNECTING,
-        CONNECTED
-    };
-
-    Mutex mLock;
-
-    uint32_t mFlags;
-
-    State mState;
-
-    String8 mHost;
-    unsigned mPort;
-    String8 mPath;
-    bool mHTTPS;
-    String8 mHeaders;
-    String8 mUri;
-
-    HTTPStream mHTTP;
-    off64_t mOffset;
-    off64_t mContentLength;
-    bool mContentLengthValid;
-    bool mHasChunkedTransferEncoding;
-
-    String8 mContentType;
-
-    // The number of data bytes in the current chunk before any subsequent
-    // chunk header (or -1 if no more chunks).
-    ssize_t mChunkDataBytesLeft;
-
-    sp<DecryptHandle> mDecryptHandle;
-    DrmManagerClient *mDrmManagerClient;
-
-    status_t connect(
-            const char *uri, const String8 &headers, off64_t offset);
-
-    status_t connect(
-            const char *host, unsigned port, const char *path,
-            bool https,
-            const String8 &headers,
-            off64_t offset);
-
-    // Read up to "size" bytes of data, respect transfer encoding.
-    ssize_t internalRead(void *data, size_t size);
-
-    void applyTimeoutResponse();
-
-    static void MakeFullHeaders(
-            const KeyedVector<String8, String8> *overrides,
-            String8 *headers);
-
-    NuHTTPDataSource(const NuHTTPDataSource &);
-    NuHTTPDataSource &operator=(const NuHTTPDataSource &);
-};
-
-}  // namespace android
-
-#endif  // NU_HTTP_DATA_SOURCE_H_
diff --git a/media/libstagefright/include/OMX.h b/media/libstagefright/include/OMX.h
index ec3e5fa..d54b1c1 100644
--- a/media/libstagefright/include/OMX.h
+++ b/media/libstagefright/include/OMX.h
@@ -121,6 +121,7 @@
     virtual ~OMX();
 
 private:
+    struct CallbackDispatcherThread;
     struct CallbackDispatcher;
 
     Mutex mLock;
diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp
index d23aa3a..25f30d6 100644
--- a/media/libstagefright/omx/OMX.cpp
+++ b/media/libstagefright/omx/OMX.cpp
@@ -20,8 +20,6 @@
 
 #include <dlfcn.h>
 
-#include <sys/prctl.h>
-
 #include "../include/OMX.h"
 
 #include "../include/OMXNodeInstance.h"
@@ -38,11 +36,32 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
+// This provides the underlying Thread used by CallbackDispatcher.
+// Note that deriving CallbackDispatcher from Thread does not work.
+
+struct OMX::CallbackDispatcherThread : public Thread {
+    CallbackDispatcherThread(CallbackDispatcher *dispatcher)
+        : mDispatcher(dispatcher) {
+    }
+
+private:
+    CallbackDispatcher *mDispatcher;
+
+    bool threadLoop();
+
+    CallbackDispatcherThread(const CallbackDispatcherThread &);
+    CallbackDispatcherThread &operator=(const CallbackDispatcherThread &);
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
 struct OMX::CallbackDispatcher : public RefBase {
     CallbackDispatcher(OMXNodeInstance *owner);
 
     void post(const omx_message &msg);
 
+    bool loop();
+
 protected:
     virtual ~CallbackDispatcher();
 
@@ -54,13 +73,10 @@
     Condition mQueueChanged;
     List<omx_message> mQueue;
 
-    pthread_t mThread;
+    sp<CallbackDispatcherThread> mThread;
 
     void dispatch(const omx_message &msg);
 
-    static void *ThreadWrapper(void *me);
-    void threadEntry();
-
     CallbackDispatcher(const CallbackDispatcher &);
     CallbackDispatcher &operator=(const CallbackDispatcher &);
 };
@@ -68,13 +84,8 @@
 OMX::CallbackDispatcher::CallbackDispatcher(OMXNodeInstance *owner)
     : mOwner(owner),
       mDone(false) {
-    pthread_attr_t attr;
-    pthread_attr_init(&attr);
-    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
-
-    pthread_create(&mThread, &attr, ThreadWrapper, this);
-
-    pthread_attr_destroy(&attr);
+    mThread = new CallbackDispatcherThread(this);
+    mThread->run("OMXCallbackDisp", ANDROID_PRIORITY_AUDIO);
 }
 
 OMX::CallbackDispatcher::~CallbackDispatcher() {
@@ -86,10 +97,8 @@
     }
 
     // Don't call join on myself
-    CHECK(mThread != pthread_self());
-
-    void *dummy;
-    pthread_join(mThread, &dummy);
+    status_t status = mThread->join();
+    CHECK(status == NO_ERROR);
 }
 
 void OMX::CallbackDispatcher::post(const omx_message &msg) {
@@ -107,17 +116,7 @@
     mOwner->onMessage(msg);
 }
 
-// static
-void *OMX::CallbackDispatcher::ThreadWrapper(void *me) {
-    static_cast<CallbackDispatcher *>(me)->threadEntry();
-
-    return NULL;
-}
-
-void OMX::CallbackDispatcher::threadEntry() {
-    androidSetThreadPriority(0, ANDROID_PRIORITY_AUDIO);
-    prctl(PR_SET_NAME, (unsigned long)"OMXCallbackDisp", 0, 0, 0);
-
+bool OMX::CallbackDispatcher::loop() {
     for (;;) {
         omx_message msg;
 
@@ -137,6 +136,14 @@
 
         dispatch(msg);
     }
+
+    return false;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+bool OMX::CallbackDispatcherThread::threadLoop() {
+    return mDispatcher->loop();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/media/libstagefright/rtsp/ARTSPConnection.cpp b/media/libstagefright/rtsp/ARTSPConnection.cpp
index 072d6b2..b398c9d 100644
--- a/media/libstagefright/rtsp/ARTSPConnection.cpp
+++ b/media/libstagefright/rtsp/ARTSPConnection.cpp
@@ -34,7 +34,7 @@
 #include <openssl/md5.h>
 #include <sys/socket.h>
 
-#include "HTTPStream.h"
+#include "HTTPBase.h"
 
 namespace android {
 
@@ -251,7 +251,7 @@
     mSocket = socket(AF_INET, SOCK_STREAM, 0);
 
     if (mUIDValid) {
-        HTTPStream::RegisterSocketUser(mSocket, mUID);
+        HTTPBase::RegisterSocketUser(mSocket, mUID);
     }
 
     MakeSocketBlocking(mSocket, false);
diff --git a/media/libstagefright/rtsp/MyHandler.h b/media/libstagefright/rtsp/MyHandler.h
index 3188959..71d68f6 100644
--- a/media/libstagefright/rtsp/MyHandler.h
+++ b/media/libstagefright/rtsp/MyHandler.h
@@ -40,7 +40,7 @@
 #include <sys/socket.h>
 #include <netdb.h>
 
-#include "HTTPStream.h"
+#include "HTTPBase.h"
 
 // If no access units are received within 5 secs, assume that the rtp
 // stream has ended and signal end of stream.
@@ -1181,8 +1181,8 @@
                     &info->mRTPSocket, &info->mRTCPSocket, &rtpPort);
 
             if (mUIDValid) {
-                HTTPStream::RegisterSocketUser(info->mRTPSocket, mUID);
-                HTTPStream::RegisterSocketUser(info->mRTCPSocket, mUID);
+                HTTPBase::RegisterSocketUser(info->mRTPSocket, mUID);
+                HTTPBase::RegisterSocketUser(info->mRTCPSocket, mUID);
             }
 
             request.append("Transport: RTP/AVP/UDP;unicast;client_port=");
diff --git a/services/audioflinger/AudioPolicyService.cpp b/services/audioflinger/AudioPolicyService.cpp
index 47ca3a0..8e16d94 100644
--- a/services/audioflinger/AudioPolicyService.cpp
+++ b/services/audioflinger/AudioPolicyService.cpp
@@ -48,9 +48,6 @@
 static const int kDumpLockSleep = 20000;
 
 static bool checkPermission() {
-#ifndef HAVE_ANDROID_OS
-    return true;
-#endif
     if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
     bool ok = checkCallingPermission(String16("android.permission.MODIFY_AUDIO_SETTINGS"));
     if (!ok) LOGE("Request requires android.permission.MODIFY_AUDIO_SETTINGS");
diff --git a/services/input/InputApplication.h b/services/input/InputApplication.h
index cc80062..8902f7a 100644
--- a/services/input/InputApplication.h
+++ b/services/input/InputApplication.h
@@ -26,26 +26,32 @@
 namespace android {
 
 /*
- * A handle to an application that can receive input.
- * Used by the native input dispatcher to indirectly refer to the window manager objects
+ * Describes the properties of an application that can receive input.
+ *
+ * Used by the native input dispatcher as a handle for the window manager objects
  * that describe an application.
  */
 class InputApplicationHandle : public RefBase {
+public:
+    String8 name;
+    nsecs_t dispatchingTimeout;
+
+    /**
+     * Requests that the state of this object be updated to reflect
+     * the most current available information about the application.
+     *
+     * This method should only be called from within the input dispatcher's
+     * critical section.
+     *
+     * Returns true on success, or false if the handle is no longer valid.
+     */
+    virtual bool update() = 0;
+
 protected:
     InputApplicationHandle() { }
     virtual ~InputApplicationHandle() { }
 };
 
-
-/*
- * An input application describes properties of an application that can receive input.
- */
-struct InputApplication {
-    sp<InputApplicationHandle> inputApplicationHandle;
-    String8 name;
-    nsecs_t dispatchingTimeout;
-};
-
 } // namespace android
 
 #endif // _UI_INPUT_APPLICATION_H
diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp
index 10b9083..1cac5025 100644
--- a/services/input/InputDispatcher.cpp
+++ b/services/input/InputDispatcher.cpp
@@ -211,11 +211,8 @@
     mPendingEvent(NULL), mAppSwitchSawKeyDown(false), mAppSwitchDueTime(LONG_LONG_MAX),
     mNextUnblockedEvent(NULL),
     mDispatchEnabled(true), mDispatchFrozen(false), mInputFilterEnabled(false),
-    mFocusedWindow(NULL),
-    mFocusedApplication(NULL),
     mCurrentInputTargetsValid(false),
-    mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE),
-    mLastHoverWindow(NULL) {
+    mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
     mLooper = new Looper(false);
 
     mInboundQueue.headSentinel.refCount = -1;
@@ -501,16 +498,15 @@
         if (motionEntry->action == AMOTION_EVENT_ACTION_DOWN
                 && (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER)
                 && mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY
-                && mInputTargetWaitApplication != NULL) {
+                && mInputTargetWaitApplicationHandle != NULL) {
             int32_t x = int32_t(motionEntry->firstSample.pointerCoords[0].
                     getAxisValue(AMOTION_EVENT_AXIS_X));
             int32_t y = int32_t(motionEntry->firstSample.pointerCoords[0].
                     getAxisValue(AMOTION_EVENT_AXIS_Y));
-            const InputWindow* touchedWindow = findTouchedWindowAtLocked(x, y);
-            if (touchedWindow
-                    && touchedWindow->inputWindowHandle != NULL
-                    && touchedWindow->inputWindowHandle->getInputApplicationHandle()
-                            != mInputTargetWaitApplication) {
+            sp<InputWindowHandle> touchedWindowHandle = findTouchedWindowAtLocked(x, y);
+            if (touchedWindowHandle != NULL
+                    && touchedWindowHandle->inputApplicationHandle
+                            != mInputTargetWaitApplicationHandle) {
                 // User touched a different application than the one we are waiting on.
                 // Flag the event, and start pruning the input queue.
                 mNextUnblockedEvent = motionEntry;
@@ -524,25 +520,25 @@
     return needWake;
 }
 
-const InputWindow* InputDispatcher::findTouchedWindowAtLocked(int32_t x, int32_t y) {
+sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t x, int32_t y) {
     // Traverse windows from front to back to find touched window.
-    size_t numWindows = mWindows.size();
+    size_t numWindows = mWindowHandles.size();
     for (size_t i = 0; i < numWindows; i++) {
-        const InputWindow* window = & mWindows.editItemAt(i);
-        int32_t flags = window->layoutParamsFlags;
+        sp<InputWindowHandle> windowHandle = mWindowHandles.itemAt(i);
+        int32_t flags = windowHandle->layoutParamsFlags;
 
-        if (window->visible) {
-            if (!(flags & InputWindow::FLAG_NOT_TOUCHABLE)) {
-                bool isTouchModal = (flags & (InputWindow::FLAG_NOT_FOCUSABLE
-                        | InputWindow::FLAG_NOT_TOUCH_MODAL)) == 0;
-                if (isTouchModal || window->touchableRegionContainsPoint(x, y)) {
+        if (windowHandle->visible) {
+            if (!(flags & InputWindowHandle::FLAG_NOT_TOUCHABLE)) {
+                bool isTouchModal = (flags & (InputWindowHandle::FLAG_NOT_FOCUSABLE
+                        | InputWindowHandle::FLAG_NOT_TOUCH_MODAL)) == 0;
+                if (isTouchModal || windowHandle->touchableRegionContainsPoint(x, y)) {
                     // Found window.
-                    return window;
+                    return windowHandle;
                 }
             }
         }
 
-        if (flags & InputWindow::FLAG_SYSTEM_ERROR) {
+        if (flags & InputWindowHandle::FLAG_SYSTEM_ERROR) {
             // Error window is on top but not visible, so touch is dropped.
             return NULL;
         }
@@ -781,8 +777,8 @@
         if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
             CommandEntry* commandEntry = postCommandLocked(
                     & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
-            if (mFocusedWindow) {
-                commandEntry->inputWindowHandle = mFocusedWindow->inputWindowHandle;
+            if (mFocusedWindowHandle != NULL) {
+                commandEntry->inputWindowHandle = mFocusedWindowHandle;
             }
             commandEntry->keyEntry = entry;
             entry->refCount += 1;
@@ -1011,7 +1007,7 @@
     mCurrentInputTargetsValid = false;
     mCurrentInputTargets.clear();
     mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
-    mInputTargetWaitApplication.clear();
+    mInputTargetWaitApplicationHandle.clear();
 }
 
 void InputDispatcher::commitTargetsLocked() {
@@ -1019,9 +1015,11 @@
 }
 
 int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
-        const EventEntry* entry, const InputApplication* application, const InputWindow* window,
+        const EventEntry* entry,
+        const sp<InputApplicationHandle>& applicationHandle,
+        const sp<InputWindowHandle>& windowHandle,
         nsecs_t* nextWakeupTime) {
-    if (application == NULL && window == NULL) {
+    if (applicationHandle == NULL && windowHandle == NULL) {
         if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
 #if DEBUG_FOCUS
             LOGD("Waiting for system to become ready for input.");
@@ -1030,29 +1028,29 @@
             mInputTargetWaitStartTime = currentTime;
             mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
             mInputTargetWaitTimeoutExpired = false;
-            mInputTargetWaitApplication.clear();
+            mInputTargetWaitApplicationHandle.clear();
         }
     } else {
         if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
 #if DEBUG_FOCUS
             LOGD("Waiting for application to become ready for input: %s",
-                    getApplicationWindowLabelLocked(application, window).string());
+                    getApplicationWindowLabelLocked(applicationHandle, windowHandle).string());
 #endif
-            nsecs_t timeout = window ? window->dispatchingTimeout :
-                application ? application->dispatchingTimeout : DEFAULT_INPUT_DISPATCHING_TIMEOUT;
+            nsecs_t timeout = windowHandle != NULL ? windowHandle->dispatchingTimeout :
+                applicationHandle != NULL ?
+                        applicationHandle->dispatchingTimeout : DEFAULT_INPUT_DISPATCHING_TIMEOUT;
 
             mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
             mInputTargetWaitStartTime = currentTime;
             mInputTargetWaitTimeoutTime = currentTime + timeout;
             mInputTargetWaitTimeoutExpired = false;
-            mInputTargetWaitApplication.clear();
+            mInputTargetWaitApplicationHandle.clear();
 
-            if (window && window->inputWindowHandle != NULL) {
-                mInputTargetWaitApplication =
-                        window->inputWindowHandle->getInputApplicationHandle();
+            if (windowHandle != NULL) {
+                mInputTargetWaitApplicationHandle = windowHandle->inputApplicationHandle;
             }
-            if (mInputTargetWaitApplication == NULL && application) {
-                mInputTargetWaitApplication = application->inputApplicationHandle;
+            if (mInputTargetWaitApplicationHandle == NULL && applicationHandle != NULL) {
+                mInputTargetWaitApplicationHandle = applicationHandle;
             }
         }
     }
@@ -1062,7 +1060,8 @@
     }
 
     if (currentTime >= mInputTargetWaitTimeoutTime) {
-        onANRLocked(currentTime, application, window, entry->eventTime, mInputTargetWaitStartTime);
+        onANRLocked(currentTime, applicationHandle, windowHandle,
+                entry->eventTime, mInputTargetWaitStartTime);
 
         // Force poll loop to wake up immediately on next iteration once we get the
         // ANR response back from the policy.
@@ -1129,15 +1128,15 @@
 
     // If there is no currently focused window and no focused application
     // then drop the event.
-    if (! mFocusedWindow) {
-        if (mFocusedApplication) {
+    if (mFocusedWindowHandle == NULL) {
+        if (mFocusedApplicationHandle != NULL) {
 #if DEBUG_FOCUS
             LOGD("Waiting because there is no focused window but there is a "
                     "focused application that may eventually add a window: %s.",
-                    getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
+                    getApplicationWindowLabelLocked(mFocusedApplicationHandle, NULL).string());
 #endif
             injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
-                    mFocusedApplication, NULL, nextWakeupTime);
+                    mFocusedApplicationHandle, NULL, nextWakeupTime);
             goto Unresponsive;
         }
 
@@ -1147,34 +1146,34 @@
     }
 
     // Check permissions.
-    if (! checkInjectionPermission(mFocusedWindow, entry->injectionState)) {
+    if (! checkInjectionPermission(mFocusedWindowHandle, entry->injectionState)) {
         injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
         goto Failed;
     }
 
     // If the currently focused window is paused then keep waiting.
-    if (mFocusedWindow->paused) {
+    if (mFocusedWindowHandle->paused) {
 #if DEBUG_FOCUS
         LOGD("Waiting because focused window is paused.");
 #endif
         injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
-                mFocusedApplication, mFocusedWindow, nextWakeupTime);
+                mFocusedApplicationHandle, mFocusedWindowHandle, nextWakeupTime);
         goto Unresponsive;
     }
 
     // If the currently focused window is still working on previous events then keep waiting.
-    if (! isWindowFinishedWithPreviousInputLocked(mFocusedWindow)) {
+    if (! isWindowFinishedWithPreviousInputLocked(mFocusedWindowHandle)) {
 #if DEBUG_FOCUS
         LOGD("Waiting because focused window still processing previous input.");
 #endif
         injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
-                mFocusedApplication, mFocusedWindow, nextWakeupTime);
+                mFocusedApplicationHandle, mFocusedWindowHandle, nextWakeupTime);
         goto Unresponsive;
     }
 
     // Success!  Output targets.
     injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
-    addWindowTargetLocked(mFocusedWindow,
+    addWindowTargetLocked(mFocusedWindowHandle,
             InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS, BitSet32(0));
 
     // Done.
@@ -1236,7 +1235,7 @@
     // Update the touch state as needed based on the properties of the touch event.
     int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
     InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
-    const InputWindow* newHoverWindow = NULL;
+    sp<InputWindowHandle> newHoverWindowHandle;
 
     bool isSplit = mTouchState.split;
     bool switchedDevice = mTouchState.deviceId >= 0
@@ -1279,42 +1278,44 @@
                 getAxisValue(AMOTION_EVENT_AXIS_X));
         int32_t y = int32_t(sample->pointerCoords[pointerIndex].
                 getAxisValue(AMOTION_EVENT_AXIS_Y));
-        const InputWindow* newTouchedWindow = NULL;
-        const InputWindow* topErrorWindow = NULL;
+        sp<InputWindowHandle> newTouchedWindowHandle;
+        sp<InputWindowHandle> topErrorWindowHandle;
         bool isTouchModal = false;
 
         // Traverse windows from front to back to find touched window and outside targets.
-        size_t numWindows = mWindows.size();
+        size_t numWindows = mWindowHandles.size();
         for (size_t i = 0; i < numWindows; i++) {
-            const InputWindow* window = & mWindows.editItemAt(i);
-            int32_t flags = window->layoutParamsFlags;
+            sp<InputWindowHandle> windowHandle = mWindowHandles.itemAt(i);
+            int32_t flags = windowHandle->layoutParamsFlags;
 
-            if (flags & InputWindow::FLAG_SYSTEM_ERROR) {
-                if (! topErrorWindow) {
-                    topErrorWindow = window;
+            if (flags & InputWindowHandle::FLAG_SYSTEM_ERROR) {
+                if (topErrorWindowHandle == NULL) {
+                    topErrorWindowHandle = windowHandle;
                 }
             }
 
-            if (window->visible) {
-                if (! (flags & InputWindow::FLAG_NOT_TOUCHABLE)) {
-                    isTouchModal = (flags & (InputWindow::FLAG_NOT_FOCUSABLE
-                            | InputWindow::FLAG_NOT_TOUCH_MODAL)) == 0;
-                    if (isTouchModal || window->touchableRegionContainsPoint(x, y)) {
-                        if (! screenWasOff || flags & InputWindow::FLAG_TOUCHABLE_WHEN_WAKING) {
-                            newTouchedWindow = window;
+            if (windowHandle->visible) {
+                if (! (flags & InputWindowHandle::FLAG_NOT_TOUCHABLE)) {
+                    isTouchModal = (flags & (InputWindowHandle::FLAG_NOT_FOCUSABLE
+                            | InputWindowHandle::FLAG_NOT_TOUCH_MODAL)) == 0;
+                    if (isTouchModal || windowHandle->touchableRegionContainsPoint(x, y)) {
+                        if (! screenWasOff
+                                || (flags & InputWindowHandle::FLAG_TOUCHABLE_WHEN_WAKING)) {
+                            newTouchedWindowHandle = windowHandle;
                         }
                         break; // found touched window, exit window loop
                     }
                 }
 
                 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
-                        && (flags & InputWindow::FLAG_WATCH_OUTSIDE_TOUCH)) {
+                        && (flags & InputWindowHandle::FLAG_WATCH_OUTSIDE_TOUCH)) {
                     int32_t outsideTargetFlags = InputTarget::FLAG_DISPATCH_AS_OUTSIDE;
-                    if (isWindowObscuredAtPointLocked(window, x, y)) {
+                    if (isWindowObscuredAtPointLocked(windowHandle, x, y)) {
                         outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
                     }
 
-                    mTempTouchState.addOrUpdateWindow(window, outsideTargetFlags, BitSet32(0));
+                    mTempTouchState.addOrUpdateWindow(
+                            windowHandle, outsideTargetFlags, BitSet32(0));
                 }
             }
         }
@@ -1322,7 +1323,7 @@
         // If there is an error window but it is not taking focus (typically because
         // it is invisible) then wait for it.  Any other focused window may in
         // fact be in ANR state.
-        if (topErrorWindow && newTouchedWindow != topErrorWindow) {
+        if (topErrorWindowHandle != NULL && newTouchedWindowHandle != topErrorWindowHandle) {
 #if DEBUG_FOCUS
             LOGD("Waiting because system error window is pending.");
 #endif
@@ -1333,26 +1334,26 @@
         }
 
         // Figure out whether splitting will be allowed for this window.
-        if (newTouchedWindow && newTouchedWindow->supportsSplitTouch()) {
+        if (newTouchedWindowHandle != NULL && newTouchedWindowHandle->supportsSplitTouch()) {
             // New window supports splitting.
             isSplit = true;
         } else if (isSplit) {
             // New window does not support splitting but we have already split events.
             // Assign the pointer to the first foreground window we find.
             // (May be NULL which is why we put this code block before the next check.)
-            newTouchedWindow = mTempTouchState.getFirstForegroundWindow();
+            newTouchedWindowHandle = mTempTouchState.getFirstForegroundWindowHandle();
         }
 
         // If we did not find a touched window then fail.
-        if (! newTouchedWindow) {
-            if (mFocusedApplication) {
+        if (newTouchedWindowHandle == NULL) {
+            if (mFocusedApplicationHandle != NULL) {
 #if DEBUG_FOCUS
                 LOGD("Waiting because there is no touched window but there is a "
                         "focused application that may eventually add a new window: %s.",
-                        getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
+                        getApplicationWindowLabelLocked(mFocusedApplicationHandle, NULL).string());
 #endif
                 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
-                        mFocusedApplication, NULL, nextWakeupTime);
+                        mFocusedApplicationHandle, NULL, nextWakeupTime);
                 goto Unresponsive;
             }
 
@@ -1366,20 +1367,20 @@
         if (isSplit) {
             targetFlags |= InputTarget::FLAG_SPLIT;
         }
-        if (isWindowObscuredAtPointLocked(newTouchedWindow, x, y)) {
+        if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
             targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
         }
 
         // Update hover state.
         if (isHoverAction) {
-            newHoverWindow = newTouchedWindow;
+            newHoverWindowHandle = newTouchedWindowHandle;
 
             // Ensure all subsequent motion samples are also within the touched window.
             // Set *outSplitBatchAfterSample to the sample before the first one that is not
             // within the touched window.
             if (!isTouchModal) {
                 while (sample->next) {
-                    if (!newHoverWindow->touchableRegionContainsPoint(
+                    if (!newHoverWindowHandle->touchableRegionContainsPoint(
                             sample->next->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X),
                             sample->next->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y))) {
                         *outSplitBatchAfterSample = sample;
@@ -1389,7 +1390,7 @@
                 }
             }
         } else if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
-            newHoverWindow = mLastHoverWindow;
+            newHoverWindowHandle = mLastHoverWindowHandle;
         }
 
         // Update the temporary touch state.
@@ -1398,7 +1399,7 @@
             uint32_t pointerId = entry->pointerProperties[pointerIndex].id;
             pointerIds.markBit(pointerId);
         }
-        mTempTouchState.addOrUpdateWindow(newTouchedWindow, targetFlags, pointerIds);
+        mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
     } else {
         /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
 
@@ -1420,19 +1421,22 @@
             int32_t x = int32_t(sample->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
             int32_t y = int32_t(sample->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
 
-            const InputWindow* oldTouchedWindow = mTempTouchState.getFirstForegroundWindow();
-            const InputWindow* newTouchedWindow = findTouchedWindowAtLocked(x, y);
-            if (oldTouchedWindow != newTouchedWindow && newTouchedWindow) {
+            sp<InputWindowHandle> oldTouchedWindowHandle =
+                    mTempTouchState.getFirstForegroundWindowHandle();
+            sp<InputWindowHandle> newTouchedWindowHandle = findTouchedWindowAtLocked(x, y);
+            if (oldTouchedWindowHandle != newTouchedWindowHandle
+                    && newTouchedWindowHandle != NULL) {
 #if DEBUG_FOCUS
                 LOGD("Touch is slipping out of window %s into window %s.",
-                        oldTouchedWindow->name.string(), newTouchedWindow->name.string());
+                        oldTouchedWindowHandle->name.string(),
+                        newTouchedWindowHandle->name.string());
 #endif
                 // Make a slippery exit from the old window.
-                mTempTouchState.addOrUpdateWindow(oldTouchedWindow,
+                mTempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
                         InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT, BitSet32(0));
 
                 // Make a slippery entrance into the new window.
-                if (newTouchedWindow->supportsSplitTouch()) {
+                if (newTouchedWindowHandle->supportsSplitTouch()) {
                     isSplit = true;
                 }
 
@@ -1441,7 +1445,7 @@
                 if (isSplit) {
                     targetFlags |= InputTarget::FLAG_SPLIT;
                 }
-                if (isWindowObscuredAtPointLocked(newTouchedWindow, x, y)) {
+                if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
                     targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
                 }
 
@@ -1449,7 +1453,7 @@
                 if (isSplit) {
                     pointerIds.markBit(entry->pointerProperties[0].id);
                 }
-                mTempTouchState.addOrUpdateWindow(newTouchedWindow, targetFlags, pointerIds);
+                mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
 
                 // Split the batch here so we send exactly one sample.
                 *outSplitBatchAfterSample = &entry->firstSample;
@@ -1457,25 +1461,25 @@
         }
     }
 
-    if (newHoverWindow != mLastHoverWindow) {
+    if (newHoverWindowHandle != mLastHoverWindowHandle) {
         // Split the batch here so we send exactly one sample as part of ENTER or EXIT.
         *outSplitBatchAfterSample = &entry->firstSample;
 
         // Let the previous window know that the hover sequence is over.
-        if (mLastHoverWindow) {
+        if (mLastHoverWindowHandle != NULL) {
 #if DEBUG_HOVER
-            LOGD("Sending hover exit event to window %s.", mLastHoverWindow->name.string());
+            LOGD("Sending hover exit event to window %s.", mLastHoverWindowHandle->name.string());
 #endif
-            mTempTouchState.addOrUpdateWindow(mLastHoverWindow,
+            mTempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
                     InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
         }
 
         // Let the new window know that the hover sequence is starting.
-        if (newHoverWindow) {
+        if (newHoverWindowHandle != NULL) {
 #if DEBUG_HOVER
-            LOGD("Sending hover enter event to window %s.", newHoverWindow->name.string());
+            LOGD("Sending hover enter event to window %s.", newHoverWindowHandle->name.string());
 #endif
-            mTempTouchState.addOrUpdateWindow(newHoverWindow,
+            mTempTouchState.addOrUpdateWindow(newHoverWindowHandle,
                     InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER, BitSet32(0));
         }
     }
@@ -1488,7 +1492,8 @@
             const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
             if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
                 haveForegroundWindow = true;
-                if (! checkInjectionPermission(touchedWindow.window, entry->injectionState)) {
+                if (! checkInjectionPermission(touchedWindow.windowHandle,
+                        entry->injectionState)) {
                     injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
                     injectionPermission = INJECTION_PERMISSION_DENIED;
                     goto Failed;
@@ -1510,14 +1515,15 @@
     // Check whether windows listening for outside touches are owned by the same UID. If it is
     // set the policy flag that we will not reveal coordinate information to this window.
     if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
-        const InputWindow* foregroundWindow = mTempTouchState.getFirstForegroundWindow();
-        const int32_t foregroundWindowUid = foregroundWindow->ownerUid;
+        sp<InputWindowHandle> foregroundWindowHandle =
+                mTempTouchState.getFirstForegroundWindowHandle();
+        const int32_t foregroundWindowUid = foregroundWindowHandle->ownerUid;
         for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
             const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
             if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
-                const InputWindow* inputWindow = touchedWindow.window;
-                if (inputWindow->ownerUid != foregroundWindowUid) {
-                    mTempTouchState.addOrUpdateWindow(inputWindow,
+                sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
+                if (inputWindowHandle->ownerUid != foregroundWindowUid) {
+                    mTempTouchState.addOrUpdateWindow(inputWindowHandle,
                             InputTarget::FLAG_ZERO_COORDS, BitSet32(0));
                 }
             }
@@ -1529,22 +1535,22 @@
         const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
         if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
             // If the touched window is paused then keep waiting.
-            if (touchedWindow.window->paused) {
+            if (touchedWindow.windowHandle->paused) {
 #if DEBUG_FOCUS
                 LOGD("Waiting because touched window is paused.");
 #endif
                 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
-                        NULL, touchedWindow.window, nextWakeupTime);
+                        NULL, touchedWindow.windowHandle, nextWakeupTime);
                 goto Unresponsive;
             }
 
             // If the touched window is still working on previous events then keep waiting.
-            if (! isWindowFinishedWithPreviousInputLocked(touchedWindow.window)) {
+            if (! isWindowFinishedWithPreviousInputLocked(touchedWindow.windowHandle)) {
 #if DEBUG_FOCUS
                 LOGD("Waiting because touched window still processing previous input.");
 #endif
                 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
-                        NULL, touchedWindow.window, nextWakeupTime);
+                        NULL, touchedWindow.windowHandle, nextWakeupTime);
                 goto Unresponsive;
             }
         }
@@ -1557,12 +1563,13 @@
     // engine only supports touch events.  We would need to add a mechanism similar
     // to View.onGenericMotionEvent to enable wallpapers to handle these events.
     if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
-        const InputWindow* foregroundWindow = mTempTouchState.getFirstForegroundWindow();
-        if (foregroundWindow->hasWallpaper) {
-            for (size_t i = 0; i < mWindows.size(); i++) {
-                const InputWindow* window = & mWindows[i];
-                if (window->layoutParamsType == InputWindow::TYPE_WALLPAPER) {
-                    mTempTouchState.addOrUpdateWindow(window,
+        sp<InputWindowHandle> foregroundWindowHandle =
+                mTempTouchState.getFirstForegroundWindowHandle();
+        if (foregroundWindowHandle->hasWallpaper) {
+            for (size_t i = 0; i < mWindowHandles.size(); i++) {
+                sp<InputWindowHandle> windowHandle = mWindowHandles.itemAt(i);
+                if (windowHandle->layoutParamsType == InputWindowHandle::TYPE_WALLPAPER) {
+                    mTempTouchState.addOrUpdateWindow(windowHandle,
                             InputTarget::FLAG_WINDOW_IS_OBSCURED
                                     | InputTarget::FLAG_DISPATCH_AS_IS,
                             BitSet32(0));
@@ -1576,7 +1583,7 @@
 
     for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
         const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);
-        addWindowTargetLocked(touchedWindow.window, touchedWindow.targetFlags,
+        addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
                 touchedWindow.pointerIds);
     }
 
@@ -1658,7 +1665,7 @@
             }
 
             // Update hover state.
-            mLastHoverWindow = newHoverWindow;
+            mLastHoverWindowHandle = newHoverWindowHandle;
         }
     } else {
 #if DEBUG_FOCUS
@@ -1681,16 +1688,16 @@
     return injectionResult;
 }
 
-void InputDispatcher::addWindowTargetLocked(const InputWindow* window, int32_t targetFlags,
-        BitSet32 pointerIds) {
+void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
+        int32_t targetFlags, BitSet32 pointerIds) {
     mCurrentInputTargets.push();
 
     InputTarget& target = mCurrentInputTargets.editTop();
-    target.inputChannel = window->inputChannel;
+    target.inputChannel = windowHandle->inputChannel;
     target.flags = targetFlags;
-    target.xOffset = - window->frameLeft;
-    target.yOffset = - window->frameTop;
-    target.scaleFactor = window->scaleFactor;
+    target.xOffset = - windowHandle->frameLeft;
+    target.yOffset = - windowHandle->frameTop;
+    target.scaleFactor = windowHandle->scaleFactor;
     target.pointerIds = pointerIds;
 }
 
@@ -1708,17 +1715,17 @@
     }
 }
 
-bool InputDispatcher::checkInjectionPermission(const InputWindow* window,
+bool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
         const InjectionState* injectionState) {
     if (injectionState
-            && (window == NULL || window->ownerUid != injectionState->injectorUid)
+            && (windowHandle == NULL || windowHandle->ownerUid != injectionState->injectorUid)
             && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
-        if (window) {
-            LOGW("Permission denied: injecting event from pid %d uid %d to window "
-                    "with input channel %s owned by uid %d",
+        if (windowHandle != NULL) {
+            LOGW("Permission denied: injecting event from pid %d uid %d to window %s "
+                    "owned by uid %d",
                     injectionState->injectorPid, injectionState->injectorUid,
-                    window->inputChannel->getName().string(),
-                    window->ownerUid);
+                    windowHandle->name.string(),
+                    windowHandle->ownerUid);
         } else {
             LOGW("Permission denied: injecting event from pid %d uid %d",
                     injectionState->injectorPid, injectionState->injectorUid);
@@ -1729,22 +1736,24 @@
 }
 
 bool InputDispatcher::isWindowObscuredAtPointLocked(
-        const InputWindow* window, int32_t x, int32_t y) const {
-    size_t numWindows = mWindows.size();
+        const sp<InputWindowHandle>& windowHandle, int32_t x, int32_t y) const {
+    size_t numWindows = mWindowHandles.size();
     for (size_t i = 0; i < numWindows; i++) {
-        const InputWindow* other = & mWindows.itemAt(i);
-        if (other == window) {
+        sp<InputWindowHandle> otherHandle = mWindowHandles.itemAt(i);
+        if (otherHandle == windowHandle) {
             break;
         }
-        if (other->visible && ! other->isTrustedOverlay() && other->frameContainsPoint(x, y)) {
+        if (otherHandle->visible && ! otherHandle->isTrustedOverlay()
+                && otherHandle->frameContainsPoint(x, y)) {
             return true;
         }
     }
     return false;
 }
 
-bool InputDispatcher::isWindowFinishedWithPreviousInputLocked(const InputWindow* window) {
-    ssize_t connectionIndex = getConnectionIndexLocked(window->inputChannel);
+bool InputDispatcher::isWindowFinishedWithPreviousInputLocked(
+        const sp<InputWindowHandle>& windowHandle) {
+    ssize_t connectionIndex = getConnectionIndexLocked(windowHandle->inputChannel);
     if (connectionIndex >= 0) {
         sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
         return connection->outboundQueue.isEmpty();
@@ -1753,19 +1762,20 @@
     }
 }
 
-String8 InputDispatcher::getApplicationWindowLabelLocked(const InputApplication* application,
-        const InputWindow* window) {
-    if (application) {
-        if (window) {
-            String8 label(application->name);
+String8 InputDispatcher::getApplicationWindowLabelLocked(
+        const sp<InputApplicationHandle>& applicationHandle,
+        const sp<InputWindowHandle>& windowHandle) {
+    if (applicationHandle != NULL) {
+        if (windowHandle != NULL) {
+            String8 label(applicationHandle->name);
             label.append(" - ");
-            label.append(window->name);
+            label.append(windowHandle->name);
             return label;
         } else {
-            return application->name;
+            return applicationHandle->name;
         }
-    } else if (window) {
-        return window->name;
+    } else if (windowHandle != NULL) {
+        return windowHandle->name;
     } else {
         return String8("<unknown application or window>");
     }
@@ -2422,11 +2432,11 @@
             }
 
             InputTarget target;
-            const InputWindow* window = getWindowLocked(connection->inputChannel);
-            if (window) {
-                target.xOffset = -window->frameLeft;
-                target.yOffset = -window->frameTop;
-                target.scaleFactor = window->scaleFactor;
+            sp<InputWindowHandle> windowHandle = getWindowHandleLocked(connection->inputChannel);
+            if (windowHandle != NULL) {
+                target.xOffset = -windowHandle->frameLeft;
+                target.yOffset = -windowHandle->frameTop;
+                target.scaleFactor = windowHandle->scaleFactor;
             } else {
                 target.xOffset = 0;
                 target.yOffset = 0;
@@ -2809,7 +2819,7 @@
                     }
 
                     if (action == AMOTION_EVENT_ACTION_HOVER_MOVE) {
-                        if (!mLastHoverWindow) {
+                        if (mLastHoverWindowHandle == NULL) {
 #if DEBUG_BATCHING
                             LOGD("Not streaming hover move because there is no "
                                     "last hovered window.");
@@ -2817,15 +2827,16 @@
                             goto NoBatchingOrStreaming;
                         }
 
-                        const InputWindow* hoverWindow = findTouchedWindowAtLocked(
+                        sp<InputWindowHandle> hoverWindowHandle = findTouchedWindowAtLocked(
                                 pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X),
                                 pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
-                        if (mLastHoverWindow != hoverWindow) {
+                        if (mLastHoverWindowHandle != hoverWindowHandle) {
 #if DEBUG_BATCHING
                             LOGD("Not streaming hover move because the last hovered window "
                                     "is '%s' but the currently hovered window is '%s'.",
-                                    mLastHoverWindow->name.string(),
-                                    hoverWindow ? hoverWindow->name.string() : "<null>");
+                                    mLastHoverWindowHandle->name.string(),
+                                    hoverWindowHandle != NULL
+                                            ? hoverWindowHandle->name.string() : "<null>");
 #endif
                             goto NoBatchingOrStreaming;
                         }
@@ -3125,113 +3136,109 @@
     }
 }
 
-const InputWindow* InputDispatcher::getWindowLocked(const sp<InputChannel>& inputChannel) {
-    for (size_t i = 0; i < mWindows.size(); i++) {
-        const InputWindow* window = & mWindows[i];
-        if (window->inputChannel == inputChannel) {
-            return window;
+sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
+        const sp<InputChannel>& inputChannel) const {
+    size_t numWindows = mWindowHandles.size();
+    for (size_t i = 0; i < numWindows; i++) {
+        const sp<InputWindowHandle>& windowHandle = mWindowHandles.itemAt(i);
+        if (windowHandle->inputChannel == inputChannel) {
+            return windowHandle;
         }
     }
     return NULL;
 }
 
-void InputDispatcher::setInputWindows(const Vector<InputWindow>& inputWindows) {
+bool InputDispatcher::hasWindowHandleLocked(
+        const sp<InputWindowHandle>& windowHandle) const {
+    size_t numWindows = mWindowHandles.size();
+    for (size_t i = 0; i < numWindows; i++) {
+        if (mWindowHandles.itemAt(i) == windowHandle) {
+            return true;
+        }
+    }
+    return false;
+}
+
+void InputDispatcher::setInputWindows(const Vector<sp<InputWindowHandle> >& inputWindowHandles) {
 #if DEBUG_FOCUS
     LOGD("setInputWindows");
 #endif
     { // acquire lock
         AutoMutex _l(mLock);
 
-        // Clear old window pointers.
-        sp<InputChannel> oldFocusedWindowChannel;
-        if (mFocusedWindow) {
-            oldFocusedWindowChannel = mFocusedWindow->inputChannel;
-            mFocusedWindow = NULL;
-        }
-        sp<InputChannel> oldLastHoverWindowChannel;
-        if (mLastHoverWindow) {
-            oldLastHoverWindowChannel = mLastHoverWindow->inputChannel;
-            mLastHoverWindow = NULL;
-        }
+        mWindowHandles = inputWindowHandles;
 
-        mWindows.clear();
-
-        // Loop over new windows and rebuild the necessary window pointers for
-        // tracking focus and touch.
-        mWindows.appendVector(inputWindows);
-
-        size_t numWindows = mWindows.size();
-        for (size_t i = 0; i < numWindows; i++) {
-            const InputWindow* window = & mWindows.itemAt(i);
-            if (window->hasFocus) {
-                mFocusedWindow = window;
-                break;
+        sp<InputWindowHandle> newFocusedWindowHandle;
+        bool foundHoveredWindow = false;
+        for (size_t i = 0; i < mWindowHandles.size(); i++) {
+            const sp<InputWindowHandle>& windowHandle = mWindowHandles.itemAt(i);
+            if (!windowHandle->update() || windowHandle->inputChannel == NULL) {
+                mWindowHandles.removeAt(i--);
+                continue;
+            }
+            if (windowHandle->hasFocus) {
+                newFocusedWindowHandle = windowHandle;
+            }
+            if (windowHandle == mLastHoverWindowHandle) {
+                foundHoveredWindow = true;
             }
         }
 
-        if (oldFocusedWindowChannel != NULL) {
-            if (!mFocusedWindow || oldFocusedWindowChannel != mFocusedWindow->inputChannel) {
+        if (!foundHoveredWindow) {
+            mLastHoverWindowHandle = NULL;
+        }
+
+        if (mFocusedWindowHandle != newFocusedWindowHandle) {
+            if (mFocusedWindowHandle != NULL) {
 #if DEBUG_FOCUS
                 LOGD("Focus left window: %s",
-                        oldFocusedWindowChannel->getName().string());
+                        mFocusedWindowHandle->name.string());
 #endif
                 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
                         "focus left window");
-                synthesizeCancelationEventsForInputChannelLocked(oldFocusedWindowChannel, options);
-                oldFocusedWindowChannel.clear();
+                synthesizeCancelationEventsForInputChannelLocked(
+                        mFocusedWindowHandle->inputChannel, options);
             }
-        }
-        if (mFocusedWindow && oldFocusedWindowChannel == NULL) {
+            if (newFocusedWindowHandle != NULL) {
 #if DEBUG_FOCUS
-            LOGD("Focus entered window: %s",
-                    mFocusedWindow->inputChannel->getName().string());
+                LOGD("Focus entered window: %s",
+                        newFocusedWindowHandle->name.string());
 #endif
+            }
+            mFocusedWindowHandle = newFocusedWindowHandle;
         }
 
-        for (size_t i = 0; i < mTouchState.windows.size(); ) {
+        for (size_t i = 0; i < mTouchState.windows.size(); i++) {
             TouchedWindow& touchedWindow = mTouchState.windows.editItemAt(i);
-            const InputWindow* window = getWindowLocked(touchedWindow.channel);
-            if (window) {
-                touchedWindow.window = window;
-                i += 1;
-            } else {
+            if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
 #if DEBUG_FOCUS
-                LOGD("Touched window was removed: %s", touchedWindow.channel->getName().string());
+                LOGD("Touched window was removed: %s", touchedWindow.windowHandle->name.string());
 #endif
                 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
                         "touched window was removed");
-                synthesizeCancelationEventsForInputChannelLocked(touchedWindow.channel, options);
-                mTouchState.windows.removeAt(i);
+                synthesizeCancelationEventsForInputChannelLocked(
+                        touchedWindow.windowHandle->inputChannel, options);
+                mTouchState.windows.removeAt(i--);
             }
         }
-
-        // Recover the last hovered window.
-        if (oldLastHoverWindowChannel != NULL) {
-            mLastHoverWindow = getWindowLocked(oldLastHoverWindowChannel);
-            oldLastHoverWindowChannel.clear();
-        }
-
-#if DEBUG_FOCUS
-        //logDispatchStateLocked();
-#endif
     } // release lock
 
     // Wake up poll loop since it may need to make new input dispatching choices.
     mLooper->wake();
 }
 
-void InputDispatcher::setFocusedApplication(const InputApplication* inputApplication) {
+void InputDispatcher::setFocusedApplication(
+        const sp<InputApplicationHandle>& inputApplicationHandle) {
 #if DEBUG_FOCUS
     LOGD("setFocusedApplication");
 #endif
     { // acquire lock
         AutoMutex _l(mLock);
 
-        releaseFocusedApplicationLocked();
-
-        if (inputApplication) {
-            mFocusedApplicationStorage = *inputApplication;
-            mFocusedApplication = & mFocusedApplicationStorage;
+        if (inputApplicationHandle != NULL && inputApplicationHandle->update()) {
+            mFocusedApplicationHandle = inputApplicationHandle;
+        } else {
+            mFocusedApplicationHandle.clear();
         }
 
 #if DEBUG_FOCUS
@@ -3243,13 +3250,6 @@
     mLooper->wake();
 }
 
-void InputDispatcher::releaseFocusedApplicationLocked() {
-    if (mFocusedApplication) {
-        mFocusedApplication = NULL;
-        mFocusedApplicationStorage.inputApplicationHandle.clear();
-    }
-}
-
 void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
 #if DEBUG_FOCUS
     LOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
@@ -3315,15 +3315,15 @@
     { // acquire lock
         AutoMutex _l(mLock);
 
-        const InputWindow* fromWindow = getWindowLocked(fromChannel);
-        const InputWindow* toWindow = getWindowLocked(toChannel);
-        if (! fromWindow || ! toWindow) {
+        sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromChannel);
+        sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toChannel);
+        if (fromWindowHandle == NULL || toWindowHandle == NULL) {
 #if DEBUG_FOCUS
             LOGD("Cannot transfer focus because from or to window not found.");
 #endif
             return false;
         }
-        if (fromWindow == toWindow) {
+        if (fromWindowHandle == toWindowHandle) {
 #if DEBUG_FOCUS
             LOGD("Trivial transfer to same window.");
 #endif
@@ -3333,7 +3333,7 @@
         bool found = false;
         for (size_t i = 0; i < mTouchState.windows.size(); i++) {
             const TouchedWindow& touchedWindow = mTouchState.windows[i];
-            if (touchedWindow.window == fromWindow) {
+            if (touchedWindow.windowHandle == fromWindowHandle) {
                 int32_t oldTargetFlags = touchedWindow.targetFlags;
                 BitSet32 pointerIds = touchedWindow.pointerIds;
 
@@ -3342,7 +3342,7 @@
                 int32_t newTargetFlags = oldTargetFlags
                         & (InputTarget::FLAG_FOREGROUND
                                 | InputTarget::FLAG_SPLIT | InputTarget::FLAG_DISPATCH_AS_IS);
-                mTouchState.addOrUpdateWindow(toWindow, newTargetFlags, pointerIds);
+                mTouchState.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
 
                 found = true;
                 break;
@@ -3392,7 +3392,7 @@
     resetTargetsLocked();
 
     mTouchState.reset();
-    mLastHoverWindow = NULL;
+    mLastHoverWindowHandle.clear();
 }
 
 void InputDispatcher::logDispatchStateLocked() {
@@ -3415,15 +3415,15 @@
     dump.appendFormat(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
     dump.appendFormat(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
 
-    if (mFocusedApplication) {
+    if (mFocusedApplicationHandle != NULL) {
         dump.appendFormat(INDENT "FocusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
-                mFocusedApplication->name.string(),
-                mFocusedApplication->dispatchingTimeout / 1000000.0);
+                mFocusedApplicationHandle->name.string(),
+                mFocusedApplicationHandle->dispatchingTimeout / 1000000.0);
     } else {
         dump.append(INDENT "FocusedApplication: <null>\n");
     }
     dump.appendFormat(INDENT "FocusedWindow: name='%s'\n",
-            mFocusedWindow != NULL ? mFocusedWindow->name.string() : "<null>");
+            mFocusedWindowHandle != NULL ? mFocusedWindowHandle->name.string() : "<null>");
 
     dump.appendFormat(INDENT "TouchDown: %s\n", toString(mTouchState.down));
     dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split));
@@ -3434,37 +3434,37 @@
         for (size_t i = 0; i < mTouchState.windows.size(); i++) {
             const TouchedWindow& touchedWindow = mTouchState.windows[i];
             dump.appendFormat(INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
-                    i, touchedWindow.window->name.string(), touchedWindow.pointerIds.value,
+                    i, touchedWindow.windowHandle->name.string(), touchedWindow.pointerIds.value,
                     touchedWindow.targetFlags);
         }
     } else {
         dump.append(INDENT "TouchedWindows: <none>\n");
     }
 
-    if (!mWindows.isEmpty()) {
+    if (!mWindowHandles.isEmpty()) {
         dump.append(INDENT "Windows:\n");
-        for (size_t i = 0; i < mWindows.size(); i++) {
-            const InputWindow& window = mWindows[i];
+        for (size_t i = 0; i < mWindowHandles.size(); i++) {
+            const sp<InputWindowHandle>& windowHandle = mWindowHandles.itemAt(i);
             dump.appendFormat(INDENT2 "%d: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, "
                     "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
                     "frame=[%d,%d][%d,%d], scale=%f, "
                     "touchableRegion=",
-                    i, window.name.string(),
-                    toString(window.paused),
-                    toString(window.hasFocus),
-                    toString(window.hasWallpaper),
-                    toString(window.visible),
-                    toString(window.canReceiveKeys),
-                    window.layoutParamsFlags, window.layoutParamsType,
-                    window.layer,
-                    window.frameLeft, window.frameTop,
-                    window.frameRight, window.frameBottom,
-                    window.scaleFactor);
-            dumpRegion(dump, window.touchableRegion);
-            dump.appendFormat(", inputFeatures=0x%08x", window.inputFeatures);
+                    i, windowHandle->name.string(),
+                    toString(windowHandle->paused),
+                    toString(windowHandle->hasFocus),
+                    toString(windowHandle->hasWallpaper),
+                    toString(windowHandle->visible),
+                    toString(windowHandle->canReceiveKeys),
+                    windowHandle->layoutParamsFlags, windowHandle->layoutParamsType,
+                    windowHandle->layer,
+                    windowHandle->frameLeft, windowHandle->frameTop,
+                    windowHandle->frameRight, windowHandle->frameBottom,
+                    windowHandle->scaleFactor);
+            dumpRegion(dump, windowHandle->touchableRegion);
+            dump.appendFormat(", inputFeatures=0x%08x", windowHandle->inputFeatures);
             dump.appendFormat(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
-                    window.ownerPid, window.ownerUid,
-                    window.dispatchingTimeout / 1000000.0);
+                    windowHandle->ownerPid, windowHandle->ownerUid,
+                    windowHandle->dispatchingTimeout / 1000000.0);
         }
     } else {
         dump.append(INDENT "Windows: <none>\n");
@@ -3636,23 +3636,19 @@
 }
 
 void InputDispatcher::onANRLocked(
-        nsecs_t currentTime, const InputApplication* application, const InputWindow* window,
+        nsecs_t currentTime, const sp<InputApplicationHandle>& applicationHandle,
+        const sp<InputWindowHandle>& windowHandle,
         nsecs_t eventTime, nsecs_t waitStartTime) {
     LOGI("Application is not responding: %s.  "
             "%01.1fms since event, %01.1fms since wait started",
-            getApplicationWindowLabelLocked(application, window).string(),
+            getApplicationWindowLabelLocked(applicationHandle, windowHandle).string(),
             (currentTime - eventTime) / 1000000.0,
             (currentTime - waitStartTime) / 1000000.0);
 
     CommandEntry* commandEntry = postCommandLocked(
             & InputDispatcher::doNotifyANRLockedInterruptible);
-    if (application) {
-        commandEntry->inputApplicationHandle = application->inputApplicationHandle;
-    }
-    if (window) {
-        commandEntry->inputWindowHandle = window->inputWindowHandle;
-        commandEntry->inputChannel = window->inputChannel;
-    }
+    commandEntry->inputApplicationHandle = applicationHandle;
+    commandEntry->inputWindowHandle = windowHandle;
 }
 
 void InputDispatcher::doNotifyConfigurationChangedInterruptible(
@@ -3686,7 +3682,9 @@
 
     mLock.lock();
 
-    resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, commandEntry->inputChannel);
+    resumeAfterTargetsNotReadyTimeoutLocked(newTimeout,
+            commandEntry->inputWindowHandle != NULL
+                    ? commandEntry->inputWindowHandle->inputChannel : NULL);
 }
 
 void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
@@ -4560,11 +4558,10 @@
     split = other.split;
     deviceId = other.deviceId;
     source = other.source;
-    windows.clear();
-    windows.appendVector(other.windows);
+    windows = other.windows;
 }
 
-void InputDispatcher::TouchState::addOrUpdateWindow(const InputWindow* window,
+void InputDispatcher::TouchState::addOrUpdateWindow(const sp<InputWindowHandle>& windowHandle,
         int32_t targetFlags, BitSet32 pointerIds) {
     if (targetFlags & InputTarget::FLAG_SPLIT) {
         split = true;
@@ -4572,7 +4569,7 @@
 
     for (size_t i = 0; i < windows.size(); i++) {
         TouchedWindow& touchedWindow = windows.editItemAt(i);
-        if (touchedWindow.window == window) {
+        if (touchedWindow.windowHandle == windowHandle) {
             touchedWindow.targetFlags |= targetFlags;
             if (targetFlags & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
                 touchedWindow.targetFlags &= ~InputTarget::FLAG_DISPATCH_AS_IS;
@@ -4585,10 +4582,9 @@
     windows.push();
 
     TouchedWindow& touchedWindow = windows.editTop();
-    touchedWindow.window = window;
+    touchedWindow.windowHandle = windowHandle;
     touchedWindow.targetFlags = targetFlags;
     touchedWindow.pointerIds = pointerIds;
-    touchedWindow.channel = window->inputChannel;
 }
 
 void InputDispatcher::TouchState::filterNonAsIsTouchWindows() {
@@ -4605,11 +4601,11 @@
     }
 }
 
-const InputWindow* InputDispatcher::TouchState::getFirstForegroundWindow() const {
+sp<InputWindowHandle> InputDispatcher::TouchState::getFirstForegroundWindowHandle() const {
     for (size_t i = 0; i < windows.size(); i++) {
         const TouchedWindow& window = windows.itemAt(i);
         if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
-            return window.window;
+            return window.windowHandle;
         }
     }
     return NULL;
@@ -4621,8 +4617,8 @@
     for (size_t i = 0; i < windows.size(); i++) {
         const TouchedWindow& window = windows.itemAt(i);
         if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
-            if (haveSlipperyForegroundWindow
-                    || !(window.window->layoutParamsFlags & InputWindow::FLAG_SLIPPERY)) {
+            if (haveSlipperyForegroundWindow || !(window.windowHandle->layoutParamsFlags
+                    & InputWindowHandle::FLAG_SLIPPERY)) {
                 return false;
             }
             haveSlipperyForegroundWindow = true;
diff --git a/services/input/InputDispatcher.h b/services/input/InputDispatcher.h
index bdd1922..15fd274 100644
--- a/services/input/InputDispatcher.h
+++ b/services/input/InputDispatcher.h
@@ -321,13 +321,14 @@
      *
      * This method may be called on any thread (usually by the input manager).
      */
-    virtual void setInputWindows(const Vector<InputWindow>& inputWindows) = 0;
+    virtual void setInputWindows(const Vector<sp<InputWindowHandle> >& inputWindowHandles) = 0;
 
     /* Sets the focused application.
      *
      * This method may be called on any thread (usually by the input manager).
      */
-    virtual void setFocusedApplication(const InputApplication* inputApplication) = 0;
+    virtual void setFocusedApplication(
+            const sp<InputApplicationHandle>& inputApplicationHandle) = 0;
 
     /* Sets the input dispatching mode.
      *
@@ -406,8 +407,8 @@
             int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,
             uint32_t policyFlags);
 
-    virtual void setInputWindows(const Vector<InputWindow>& inputWindows);
-    virtual void setFocusedApplication(const InputApplication* inputApplication);
+    virtual void setInputWindows(const Vector<sp<InputWindowHandle> >& inputWindowHandles);
+    virtual void setFocusedApplication(const sp<InputApplicationHandle>& inputApplicationHandle);
     virtual void setInputDispatchMode(bool enabled, bool frozen);
     virtual void setInputFilterEnabled(bool enabled);
 
@@ -578,7 +579,6 @@
         sp<Connection> connection;
         nsecs_t eventTime;
         KeyEntry* keyEntry;
-        sp<InputChannel> inputChannel;
         sp<InputApplicationHandle> inputApplicationHandle;
         sp<InputWindowHandle> inputWindowHandle;
         int32_t userActivityEventType;
@@ -894,7 +894,7 @@
     // to transfer focus to a new application.
     EventEntry* mNextUnblockedEvent;
 
-    const InputWindow* findTouchedWindowAtLocked(int32_t x, int32_t y);
+    sp<InputWindowHandle> findTouchedWindowAtLocked(int32_t x, int32_t y);
 
     // All registered connections mapped by receive pipe file descriptor.
     KeyedVector<int, sp<Connection> > mConnectionsByReceiveFd;
@@ -953,19 +953,19 @@
     bool mDispatchFrozen;
     bool mInputFilterEnabled;
 
-    Vector<InputWindow> mWindows;
+    Vector<sp<InputWindowHandle> > mWindowHandles;
 
-    const InputWindow* getWindowLocked(const sp<InputChannel>& inputChannel);
+    sp<InputWindowHandle> getWindowHandleLocked(const sp<InputChannel>& inputChannel) const;
+    bool hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const;
 
     // Focus tracking for keys, trackball, etc.
-    const InputWindow* mFocusedWindow;
+    sp<InputWindowHandle> mFocusedWindowHandle;
 
     // Focus tracking for touch.
     struct TouchedWindow {
-        const InputWindow* window;
+        sp<InputWindowHandle> windowHandle;
         int32_t targetFlags;
         BitSet32 pointerIds;        // zero unless target flag FLAG_SPLIT is set
-        sp<InputChannel> channel;
     };
     struct TouchState {
         bool down;
@@ -978,9 +978,10 @@
         ~TouchState();
         void reset();
         void copyFrom(const TouchState& other);
-        void addOrUpdateWindow(const InputWindow* window,int32_t targetFlags, BitSet32 pointerIds);
+        void addOrUpdateWindow(const sp<InputWindowHandle>& windowHandle,
+                int32_t targetFlags, BitSet32 pointerIds);
         void filterNonAsIsTouchWindows();
-        const InputWindow* getFirstForegroundWindow() const;
+        sp<InputWindowHandle> getFirstForegroundWindowHandle() const;
         bool isSlippery() const;
     };
 
@@ -988,9 +989,7 @@
     TouchState mTempTouchState;
 
     // Focused application.
-    InputApplication* mFocusedApplication;
-    InputApplication mFocusedApplicationStorage; // preallocated storage for mFocusedApplication
-    void releaseFocusedApplicationLocked();
+    sp<InputApplicationHandle> mFocusedApplicationHandle;
 
     // Dispatch inbound events.
     bool dispatchConfigurationChangedLocked(
@@ -1021,16 +1020,17 @@
     nsecs_t mInputTargetWaitStartTime;
     nsecs_t mInputTargetWaitTimeoutTime;
     bool mInputTargetWaitTimeoutExpired;
-    sp<InputApplicationHandle> mInputTargetWaitApplication;
+    sp<InputApplicationHandle> mInputTargetWaitApplicationHandle;
 
     // Contains the last window which received a hover event.
-    const InputWindow* mLastHoverWindow;
+    sp<InputWindowHandle> mLastHoverWindowHandle;
 
     // Finding targets for input events.
     void resetTargetsLocked();
     void commitTargetsLocked();
     int32_t handleTargetsNotReadyLocked(nsecs_t currentTime, const EventEntry* entry,
-            const InputApplication* application, const InputWindow* window,
+            const sp<InputApplicationHandle>& applicationHandle,
+            const sp<InputWindowHandle>& windowHandle,
             nsecs_t* nextWakeupTime);
     void resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
             const sp<InputChannel>& inputChannel);
@@ -1043,15 +1043,17 @@
             nsecs_t* nextWakeupTime, bool* outConflictingPointerActions,
             const MotionSample** outSplitBatchAfterSample);
 
-    void addWindowTargetLocked(const InputWindow* window, int32_t targetFlags,
-            BitSet32 pointerIds);
+    void addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
+            int32_t targetFlags, BitSet32 pointerIds);
     void addMonitoringTargetsLocked();
     void pokeUserActivityLocked(const EventEntry* eventEntry);
-    bool checkInjectionPermission(const InputWindow* window, const InjectionState* injectionState);
-    bool isWindowObscuredAtPointLocked(const InputWindow* window, int32_t x, int32_t y) const;
-    bool isWindowFinishedWithPreviousInputLocked(const InputWindow* window);
-    String8 getApplicationWindowLabelLocked(const InputApplication* application,
-            const InputWindow* window);
+    bool checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
+            const InjectionState* injectionState);
+    bool isWindowObscuredAtPointLocked(const sp<InputWindowHandle>& windowHandle,
+            int32_t x, int32_t y) const;
+    bool isWindowFinishedWithPreviousInputLocked(const sp<InputWindowHandle>& windowHandle);
+    String8 getApplicationWindowLabelLocked(const sp<InputApplicationHandle>& applicationHandle,
+            const sp<InputWindowHandle>& windowHandle);
 
     // Manage the dispatch cycle for a single connection.
     // These methods are deliberately not Interruptible because doing all of the work
@@ -1100,7 +1102,8 @@
     void onDispatchCycleBrokenLocked(
             nsecs_t currentTime, const sp<Connection>& connection);
     void onANRLocked(
-            nsecs_t currentTime, const InputApplication* application, const InputWindow* window,
+            nsecs_t currentTime, const sp<InputApplicationHandle>& applicationHandle,
+            const sp<InputWindowHandle>& windowHandle,
             nsecs_t eventTime, nsecs_t waitStartTime);
 
     // Outbound policy interactions.
diff --git a/services/input/InputWindow.cpp b/services/input/InputWindow.cpp
index b552f6d..0ce8867 100644
--- a/services/input/InputWindow.cpp
+++ b/services/input/InputWindow.cpp
@@ -22,25 +22,25 @@
 
 namespace android {
 
-// --- InputWindow ---
+// --- InputWindowHandle ---
 
-bool InputWindow::touchableRegionContainsPoint(int32_t x, int32_t y) const {
+bool InputWindowHandle::touchableRegionContainsPoint(int32_t x, int32_t y) const {
     return touchableRegion.contains(x, y);
 }
 
-bool InputWindow::frameContainsPoint(int32_t x, int32_t y) const {
+bool InputWindowHandle::frameContainsPoint(int32_t x, int32_t y) const {
     return x >= frameLeft && x <= frameRight
             && y >= frameTop && y <= frameBottom;
 }
 
-bool InputWindow::isTrustedOverlay() const {
+bool InputWindowHandle::isTrustedOverlay() const {
     return layoutParamsType == TYPE_INPUT_METHOD
             || layoutParamsType == TYPE_INPUT_METHOD_DIALOG
             || layoutParamsType == TYPE_SECURE_SYSTEM_OVERLAY;
 }
 
-bool InputWindow::supportsSplitTouch() const {
-    return layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH;
+bool InputWindowHandle::supportsSplitTouch() const {
+    return layoutParamsFlags & FLAG_SPLIT_TOUCH;
 }
 
 } // namespace android
diff --git a/services/input/InputWindow.h b/services/input/InputWindow.h
index d166ad4..272081c 100644
--- a/services/input/InputWindow.h
+++ b/services/input/InputWindow.h
@@ -31,29 +31,14 @@
 
 /*
  * A handle to a window that can receive input.
+ *
  * Used by the native input dispatcher to indirectly refer to the window manager objects
  * that describe a window.
  */
 class InputWindowHandle : public RefBase {
-protected:
-    InputWindowHandle(const sp<InputApplicationHandle>& inputApplicationHandle) :
-            mInputApplicationHandle(inputApplicationHandle) { }
-    virtual ~InputWindowHandle() { }
-
 public:
-    inline sp<InputApplicationHandle> getInputApplicationHandle() {
-        return mInputApplicationHandle;
-    }
+    const sp<InputApplicationHandle> inputApplicationHandle;
 
-private:
-    sp<InputApplicationHandle> mInputApplicationHandle;
-};
-
-
-/*
- * An input window describes the bounds of a window that can receive input.
- */
-struct InputWindow {
     // Window flags from WindowManager.LayoutParams
     enum {
         FLAG_ALLOW_LOCK_WHILE_SCREEN_ON     = 0x00000001,
@@ -164,6 +149,22 @@
     bool isTrustedOverlay() const;
 
     bool supportsSplitTouch() const;
+
+    /**
+     * Requests that the state of this object be updated to reflect
+     * the most current available information about the application.
+     *
+     * This method should only be called from within the input dispatcher's
+     * critical section.
+     *
+     * Returns true on success, or false if the handle is no longer valid.
+     */
+    virtual bool update() = 0;
+
+protected:
+    InputWindowHandle(const sp<InputApplicationHandle>& inputApplicationHandle) :
+            inputApplicationHandle(inputApplicationHandle) { }
+    virtual ~InputWindowHandle() { }
 };
 
 } // namespace android
diff --git a/services/input/tests/InputReader_test.cpp b/services/input/tests/InputReader_test.cpp
index 67067de..131894a 100644
--- a/services/input/tests/InputReader_test.cpp
+++ b/services/input/tests/InputReader_test.cpp
@@ -369,11 +369,12 @@
         return INPUT_EVENT_INJECTION_FAILED;
     }
 
-    virtual void setInputWindows(const Vector<InputWindow>& inputWindows) {
+    virtual void setInputWindows(const Vector<sp<InputWindowHandle> >& inputWindowHandles) {
         ADD_FAILURE() << "Should never be called by input reader.";
     }
 
-    virtual void setFocusedApplication(const InputApplication* inputApplication) {
+    virtual void setFocusedApplication(
+            const sp<InputApplicationHandle>& inputApplicationHandle) {
         ADD_FAILURE() << "Should never be called by input reader.";
     }
 
diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
index 80cdf6b..f99951fa 100644
--- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -1155,9 +1155,7 @@
             | AccessibilityNodeInfo.ACTION_CLEAR_SELECTION;
 
         private static final int RETRIEVAL_ALLOWING_EVENT_TYPES =
-            AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_END
-            | AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_START
-            | AccessibilityEvent.TYPE_VIEW_CLICKED | AccessibilityEvent.TYPE_VIEW_FOCUSED
+            AccessibilityEvent.TYPE_VIEW_CLICKED | AccessibilityEvent.TYPE_VIEW_FOCUSED
             | AccessibilityEvent.TYPE_VIEW_HOVER_ENTER | AccessibilityEvent.TYPE_VIEW_HOVER_EXIT
             | AccessibilityEvent.TYPE_VIEW_LONG_CLICKED | AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED
             | AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED | AccessibilityEvent.TYPE_VIEW_SELECTED
diff --git a/services/java/com/android/server/accessibility/TouchExplorer.java b/services/java/com/android/server/accessibility/TouchExplorer.java
index 1af7015..dbd9474 100644
--- a/services/java/com/android/server/accessibility/TouchExplorer.java
+++ b/services/java/com/android/server/accessibility/TouchExplorer.java
@@ -838,8 +838,6 @@
     */
     private void sendAccessibilityEvent(int eventType) {
         AccessibilityEvent event = AccessibilityEvent.obtain(eventType);
-        event.setPackageName(mContext.getPackageName());
-        event.setClassName(getClass().getName());
         mAccessibilityManager.sendAccessibilityEvent(event);
     }
 
diff --git a/services/java/com/android/server/wm/AppWindowToken.java b/services/java/com/android/server/wm/AppWindowToken.java
index d3d9df4..bfa2b39 100644
--- a/services/java/com/android/server/wm/AppWindowToken.java
+++ b/services/java/com/android/server/wm/AppWindowToken.java
@@ -101,7 +101,7 @@
     boolean firstWindowDrawn;
 
     // Input application handle used by the input dispatcher.
-    InputApplicationHandle mInputApplicationHandle;
+    final InputApplicationHandle mInputApplicationHandle;
 
     AppWindowToken(WindowManagerService _service, IApplicationToken _token) {
         super(_service, _token.asBinder(),
diff --git a/services/java/com/android/server/wm/InputApplication.java b/services/java/com/android/server/wm/InputApplication.java
deleted file mode 100644
index e04fd31..0000000
--- a/services/java/com/android/server/wm/InputApplication.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- */
-
-package com.android.server.wm;
-
-
-/**
- * Describes input-related application properties for use by the input dispatcher.
- * @hide
- */
-public final class InputApplication {
-    // Application handle.
-    public InputApplicationHandle inputApplicationHandle;
-
-    // Application name.
-    public String name;
-
-    // Dispatching timeout.
-    public long dispatchingTimeoutNanos;
-
-    public void recycle() {
-        inputApplicationHandle = null;
-    }
-}
diff --git a/services/java/com/android/server/wm/InputApplicationHandle.java b/services/java/com/android/server/wm/InputApplicationHandle.java
index 64c8e7e..d78b1d9 100644
--- a/services/java/com/android/server/wm/InputApplicationHandle.java
+++ b/services/java/com/android/server/wm/InputApplicationHandle.java
@@ -32,6 +32,12 @@
     // The window manager's application window token.
     public final AppWindowToken appWindowToken;
 
+    // Application name.
+    public String name;
+
+    // Dispatching timeout.
+    public long dispatchingTimeoutNanos;
+
     private native void nativeDispose();
 
     public InputApplicationHandle(AppWindowToken appWindowToken) {
diff --git a/services/java/com/android/server/wm/InputManager.java b/services/java/com/android/server/wm/InputManager.java
index 65007f9..3133a19 100644
--- a/services/java/com/android/server/wm/InputManager.java
+++ b/services/java/com/android/server/wm/InputManager.java
@@ -25,7 +25,6 @@
 import android.content.res.Configuration;
 import android.database.ContentObserver;
 import android.os.Environment;
-import android.os.Handler;
 import android.os.Looper;
 import android.os.MessageQueue;
 import android.os.SystemProperties;
@@ -83,10 +82,10 @@
     private static native int nativeInjectInputEvent(InputEvent event,
             int injectorPid, int injectorUid, int syncMode, int timeoutMillis,
             int policyFlags);
-    private static native void nativeSetInputWindows(InputWindow[] windows);
+    private static native void nativeSetInputWindows(InputWindowHandle[] windowHandles);
     private static native void nativeSetInputDispatchMode(boolean enabled, boolean frozen);
     private static native void nativeSetSystemUiVisibility(int visibility);
-    private static native void nativeSetFocusedApplication(InputApplication application);
+    private static native void nativeSetFocusedApplication(InputApplicationHandle application);
     private static native InputDevice nativeGetInputDevice(int deviceId);
     private static native void nativeGetInputConfiguration(Configuration configuration);
     private static native int[] nativeGetInputDeviceIds();
@@ -372,11 +371,11 @@
         return nativeGetInputDeviceIds();
     }
     
-    public void setInputWindows(InputWindow[] windows) {
-        nativeSetInputWindows(windows);
+    public void setInputWindows(InputWindowHandle[] windowHandles) {
+        nativeSetInputWindows(windowHandles);
     }
     
-    public void setFocusedApplication(InputApplication application) {
+    public void setFocusedApplication(InputApplicationHandle application) {
         nativeSetFocusedApplication(application);
     }
     
diff --git a/services/java/com/android/server/wm/InputMonitor.java b/services/java/com/android/server/wm/InputMonitor.java
index 6806634..08a3560 100644
--- a/services/java/com/android/server/wm/InputMonitor.java
+++ b/services/java/com/android/server/wm/InputMonitor.java
@@ -17,7 +17,6 @@
 package com.android.server.wm;
 
 import android.graphics.Rect;
-import android.os.Binder;
 import android.os.Process;
 import android.os.RemoteException;
 import android.util.Log;
@@ -26,6 +25,7 @@
 import android.view.WindowManager;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 
 final class InputMonitor {
     private final WindowManagerService mService;
@@ -42,12 +42,14 @@
     // When true, need to call updateInputWindowsLw().
     private boolean mUpdateInputWindowsNeeded = true;
 
-    // Temporary list of windows information to provide to the input dispatcher.
-    private InputWindowList mTempInputWindows = new InputWindowList();
-    
-    // Temporary input application object to provide to the input dispatcher.
-    private InputApplication mTempInputApplication = new InputApplication();
-    
+    // Fake handles for the drag surface, lazily initialized.
+    private InputApplicationHandle mDragApplicationHandle;
+    private InputWindowHandle mDragWindowHandle;
+
+    // Array of window handles to provide to the input dispatcher.
+    private InputWindowHandle[] mInputWindowHandles;
+    private int mInputWindowHandleCount;
+
     // Set to true when the first input device configuration change notification
     // is received to indicate that the input devices are ready.
     private final Object mInputDevicesReadyMonitor = new Object();
@@ -68,8 +70,10 @@
 
         synchronized (mService.mWindowMap) {
             WindowState windowState = (WindowState) inputWindowHandle.windowState;
-            Slog.i(WindowManagerService.TAG, "WINDOW DIED " + windowState);
-            mService.removeWindowLocked(windowState.mSession, windowState);
+            if (windowState != null) {
+                Slog.i(WindowManagerService.TAG, "WINDOW DIED " + windowState);
+                mService.removeWindowLocked(windowState.mSession, windowState);
+            }
         }
     }
     
@@ -94,8 +98,11 @@
         
         if (appWindowToken == null && inputApplicationHandle != null) {
             appWindowToken = inputApplicationHandle.appWindowToken;
-            Slog.i(WindowManagerService.TAG, "Input event dispatching timed out sending to application "
-                    + appWindowToken.stringName);
+            if (appWindowToken != null) {
+                Slog.i(WindowManagerService.TAG,
+                        "Input event dispatching timed out sending to application "
+                                + appWindowToken.stringName);
+            }
         }
 
         if (appWindowToken != null && appWindowToken.appToken != null) {
@@ -114,32 +121,59 @@
         return 0; // abort dispatching
     }
 
-    private void addDragInputWindowLw(InputWindowList windowList) {
-        final InputWindow inputWindow = windowList.add();
-        inputWindow.inputChannel = mService.mDragState.mServerChannel;
-        inputWindow.name = "drag";
-        inputWindow.layoutParamsFlags = 0;
-        inputWindow.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG;
-        inputWindow.dispatchingTimeoutNanos = WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
-        inputWindow.visible = true;
-        inputWindow.canReceiveKeys = false;
-        inputWindow.hasFocus = true;
-        inputWindow.hasWallpaper = false;
-        inputWindow.paused = false;
-        inputWindow.layer = mService.mDragState.getDragLayerLw();
-        inputWindow.ownerPid = Process.myPid();
-        inputWindow.ownerUid = Process.myUid();
-        inputWindow.inputFeatures = 0;
-        inputWindow.scaleFactor = 1.0f;
+    private void addDragInputWindowLw() {
+        if (mDragWindowHandle == null) {
+            mDragApplicationHandle = new InputApplicationHandle(null);
+            mDragApplicationHandle.name = "drag";
+            mDragApplicationHandle.dispatchingTimeoutNanos =
+                    WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
+
+            mDragWindowHandle = new InputWindowHandle(mDragApplicationHandle, null);
+            mDragWindowHandle.name = "drag";
+            mDragWindowHandle.layoutParamsFlags = 0;
+            mDragWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG;
+            mDragWindowHandle.dispatchingTimeoutNanos =
+                    WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
+            mDragWindowHandle.visible = true;
+            mDragWindowHandle.canReceiveKeys = false;
+            mDragWindowHandle.hasFocus = true;
+            mDragWindowHandle.hasWallpaper = false;
+            mDragWindowHandle.paused = false;
+            mDragWindowHandle.ownerPid = Process.myPid();
+            mDragWindowHandle.ownerUid = Process.myUid();
+            mDragWindowHandle.inputFeatures = 0;
+            mDragWindowHandle.scaleFactor = 1.0f;
+
+            // The drag window cannot receive new touches.
+            mDragWindowHandle.touchableRegion.setEmpty();
+        }
+
+        mDragWindowHandle.layer = mService.mDragState.getDragLayerLw();
 
         // The drag window covers the entire display
-        inputWindow.frameLeft = 0;
-        inputWindow.frameTop = 0;
-        inputWindow.frameRight = mService.mDisplay.getRealWidth();
-        inputWindow.frameBottom = mService.mDisplay.getRealHeight();
+        mDragWindowHandle.frameLeft = 0;
+        mDragWindowHandle.frameTop = 0;
+        mDragWindowHandle.frameRight = mService.mDisplay.getRealWidth();
+        mDragWindowHandle.frameBottom = mService.mDisplay.getRealHeight();
 
-        // The drag window cannot receive new touches.
-        inputWindow.touchableRegion.setEmpty();
+        addInputWindowHandleLw(mDragWindowHandle);
+    }
+
+    private void addInputWindowHandleLw(InputWindowHandle windowHandle) {
+        if (mInputWindowHandles == null) {
+            mInputWindowHandles = new InputWindowHandle[16];
+        }
+        if (mInputWindowHandleCount >= mInputWindowHandles.length) {
+            mInputWindowHandles = Arrays.copyOf(mInputWindowHandles,
+                    mInputWindowHandleCount * 2);
+        }
+        mInputWindowHandles[mInputWindowHandleCount++] = windowHandle;
+    }
+
+    private void clearInputWindowHandlesLw() {
+        while (mInputWindowHandleCount != 0) {
+            mInputWindowHandles[--mInputWindowHandleCount] = null;
+        }
     }
 
     public void setUpdateInputWindowsNeededLw() {
@@ -154,7 +188,7 @@
         mUpdateInputWindowsNeeded = false;
 
         if (false) Slog.d(WindowManagerService.TAG, ">>>>>> ENTERED updateInputWindowsLw");
-        
+
         // Populate the input window list with information about all of the windows that
         // could potentially receive input.
         // As an optimization, we could try to prune the list of windows but this turns
@@ -168,7 +202,7 @@
             if (WindowManagerService.DEBUG_DRAG) {
                 Log.d(WindowManagerService.TAG, "Inserting drag window");
             }
-            addDragInputWindowLw(mTempInputWindows);
+            addDragInputWindowLw();
         }
 
         final int N = windows.size();
@@ -194,48 +228,48 @@
             }
 
             // Add a window to our list of input windows.
-            final InputWindow inputWindow = mTempInputWindows.add();
-            inputWindow.inputWindowHandle = child.mInputWindowHandle;
-            inputWindow.inputChannel = child.mInputChannel;
-            inputWindow.name = child.toString();
-            inputWindow.layoutParamsFlags = flags;
-            inputWindow.layoutParamsType = type;
-            inputWindow.dispatchingTimeoutNanos = child.getInputDispatchingTimeoutNanos();
-            inputWindow.visible = isVisible;
-            inputWindow.canReceiveKeys = child.canReceiveKeys();
-            inputWindow.hasFocus = hasFocus;
-            inputWindow.hasWallpaper = hasWallpaper;
-            inputWindow.paused = child.mAppToken != null ? child.mAppToken.paused : false;
-            inputWindow.layer = child.mLayer;
-            inputWindow.ownerPid = child.mSession.mPid;
-            inputWindow.ownerUid = child.mSession.mUid;
-            inputWindow.inputFeatures = child.mAttrs.inputFeatures;
+            final InputWindowHandle inputWindowHandle = child.mInputWindowHandle;
+            inputWindowHandle.inputChannel = child.mInputChannel;
+            inputWindowHandle.name = child.toString();
+            inputWindowHandle.layoutParamsFlags = flags;
+            inputWindowHandle.layoutParamsType = type;
+            inputWindowHandle.dispatchingTimeoutNanos = child.getInputDispatchingTimeoutNanos();
+            inputWindowHandle.visible = isVisible;
+            inputWindowHandle.canReceiveKeys = child.canReceiveKeys();
+            inputWindowHandle.hasFocus = hasFocus;
+            inputWindowHandle.hasWallpaper = hasWallpaper;
+            inputWindowHandle.paused = child.mAppToken != null ? child.mAppToken.paused : false;
+            inputWindowHandle.layer = child.mLayer;
+            inputWindowHandle.ownerPid = child.mSession.mPid;
+            inputWindowHandle.ownerUid = child.mSession.mUid;
+            inputWindowHandle.inputFeatures = child.mAttrs.inputFeatures;
 
             final Rect frame = child.mFrame;
-            inputWindow.frameLeft = frame.left;
-            inputWindow.frameTop = frame.top;
-            inputWindow.frameRight = frame.right;
-            inputWindow.frameBottom = frame.bottom;
+            inputWindowHandle.frameLeft = frame.left;
+            inputWindowHandle.frameTop = frame.top;
+            inputWindowHandle.frameRight = frame.right;
+            inputWindowHandle.frameBottom = frame.bottom;
 
             if (child.mGlobalScale != 1) {
                 // If we are scaling the window, input coordinates need
                 // to be inversely scaled to map from what is on screen
                 // to what is actually being touched in the UI.
-                inputWindow.scaleFactor = 1.0f/child.mGlobalScale;
+                inputWindowHandle.scaleFactor = 1.0f/child.mGlobalScale;
             } else {
-                inputWindow.scaleFactor = 1;
+                inputWindowHandle.scaleFactor = 1;
             }
 
-            child.getTouchableRegion(inputWindow.touchableRegion);
+            child.getTouchableRegion(inputWindowHandle.touchableRegion);
+
+            addInputWindowHandleLw(inputWindowHandle);
         }
 
         // Send windows to native code.
-        mService.mInputManager.setInputWindows(mTempInputWindows.toNullTerminatedArray());
-        
+        mService.mInputManager.setInputWindows(mInputWindowHandles);
+
         // Clear the list in preparation for the next round.
-        // Also avoids keeping InputChannel objects referenced unnecessarily.
-        mTempInputWindows.clear();
-        
+        clearInputWindowHandlesLw();
+
         if (false) Slog.d(WindowManagerService.TAG, "<<<<<<< EXITED updateInputWindowsLw");
     }
 
@@ -329,14 +363,11 @@
         if (newApp == null) {
             mService.mInputManager.setFocusedApplication(null);
         } else {
-            mTempInputApplication.inputApplicationHandle = newApp.mInputApplicationHandle;
-            mTempInputApplication.name = newApp.toString();
-            mTempInputApplication.dispatchingTimeoutNanos =
-                    newApp.inputDispatchingTimeoutNanos;
+            final InputApplicationHandle handle = newApp.mInputApplicationHandle;
+            handle.name = newApp.toString();
+            handle.dispatchingTimeoutNanos = newApp.inputDispatchingTimeoutNanos;
 
-            mService.mInputManager.setFocusedApplication(mTempInputApplication);
-
-            mTempInputApplication.recycle();
+            mService.mInputManager.setFocusedApplication(handle);
         }
     }
     
diff --git a/services/java/com/android/server/wm/InputWindow.java b/services/java/com/android/server/wm/InputWindow.java
deleted file mode 100644
index 655d734..0000000
--- a/services/java/com/android/server/wm/InputWindow.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- */
-
-package com.android.server.wm;
-
-import android.graphics.Region;
-import android.view.InputChannel;
-
-/**
- * Describes input-related window properties for use by the input dispatcher.
- * @hide
- */
-public final class InputWindow {
-    // The window handle.
-    public InputWindowHandle inputWindowHandle;
-
-    // The input channel associated with the window.
-    public InputChannel inputChannel;
-
-    // The window name.
-    public String name;
-
-    // Window layout params attributes.  (WindowManager.LayoutParams)
-    public int layoutParamsFlags;
-    public int layoutParamsType;
-
-    // Dispatching timeout.
-    public long dispatchingTimeoutNanos;
-
-    // Window frame.
-    public int frameLeft;
-    public int frameTop;
-    public int frameRight;
-    public int frameBottom;
-
-    // Global scaling factor applied to touch events when they are dispatched
-    // to the window
-    public float scaleFactor;
-
-    // Window touchable region.
-    public final Region touchableRegion = new Region();
-
-    // Window is visible.
-    public boolean visible;
-
-    // Window can receive keys.
-    public boolean canReceiveKeys;
-
-    // Window has focus.
-    public boolean hasFocus;
-
-    // Window has wallpaper.  (window is the current wallpaper target)
-    public boolean hasWallpaper;
-
-    // Input event dispatching is paused.
-    public boolean paused;
-
-    // Window layer.
-    public int layer;
-
-    // Id of process and user that owns the window.
-    public int ownerPid;
-    public int ownerUid;
-
-    // Window input features.
-    public int inputFeatures;
-
-    public void recycle() {
-        inputWindowHandle = null;
-        inputChannel = null;
-    }
-}
diff --git a/services/java/com/android/server/wm/InputWindowHandle.java b/services/java/com/android/server/wm/InputWindowHandle.java
index cc508c6..abf68d9 100644
--- a/services/java/com/android/server/wm/InputWindowHandle.java
+++ b/services/java/com/android/server/wm/InputWindowHandle.java
@@ -16,6 +16,8 @@
 
 package com.android.server.wm;
 
+import android.graphics.Region;
+import android.view.InputChannel;
 import android.view.WindowManagerPolicy;
 
 /**
@@ -35,6 +37,57 @@
     // The window manager's window state.
     public final WindowManagerPolicy.WindowState windowState;
 
+    // The input channel associated with the window.
+    public InputChannel inputChannel;
+
+    // The window name.
+    public String name;
+
+    // Window layout params attributes.  (WindowManager.LayoutParams)
+    public int layoutParamsFlags;
+    public int layoutParamsType;
+
+    // Dispatching timeout.
+    public long dispatchingTimeoutNanos;
+
+    // Window frame.
+    public int frameLeft;
+    public int frameTop;
+    public int frameRight;
+    public int frameBottom;
+
+    // Global scaling factor applied to touch events when they are dispatched
+    // to the window
+    public float scaleFactor;
+
+    // Window touchable region.
+    public final Region touchableRegion = new Region();
+
+    // Window is visible.
+    public boolean visible;
+
+    // Window can receive keys.
+    public boolean canReceiveKeys;
+
+    // Window has focus.
+    public boolean hasFocus;
+
+    // Window has wallpaper.  (window is the current wallpaper target)
+    public boolean hasWallpaper;
+
+    // Input event dispatching is paused.
+    public boolean paused;
+
+    // Window layer.
+    public int layer;
+
+    // Id of process and user that owns the window.
+    public int ownerPid;
+    public int ownerUid;
+
+    // Window input features.
+    public int inputFeatures;
+
     private native void nativeDispose();
 
     public InputWindowHandle(InputApplicationHandle inputApplicationHandle,
diff --git a/services/java/com/android/server/wm/InputWindowList.java b/services/java/com/android/server/wm/InputWindowList.java
deleted file mode 100644
index 6077337..0000000
--- a/services/java/com/android/server/wm/InputWindowList.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- */
-
-package com.android.server.wm;
-
-
-/**
- * A specialized list of window information objects backed by an array.
- * 
- * This class is part of an InputManager optimization to avoid allocating objects and arrays
- * unnecessarily.  Internally, it keeps an array full of demand-allocated objects that it
- * recycles each time the list is cleared.  The used portion of the array is padded with a null.
- * 
- * The contents of the list are intended to be Z-ordered from top to bottom.
- * 
- * @hide
- */
-public final class InputWindowList {
-    private InputWindow[] mArray;
-    private int mCount;
-    
-    /**
-     * Creates an empty list.
-     */
-    public InputWindowList() {
-        mArray = new InputWindow[8];
-    }
-    
-    /**
-     * Clears the list.
-     */
-    public void clear() {
-        if (mCount == 0) {
-            return;
-        }
-        
-        int count = mCount;
-        mCount = 0;
-        mArray[count] = mArray[0];
-        while (count > 0) {
-            count -= 1;
-            mArray[count].recycle();
-        }
-        mArray[0] = null;
-    }
-    
-    /**
-     * Adds an uninitialized input window object to the list and returns it.
-     */
-    public InputWindow add() {
-        if (mCount + 1 == mArray.length) {
-            InputWindow[] oldArray = mArray;
-            mArray = new InputWindow[oldArray.length * 2];
-            System.arraycopy(oldArray, 0, mArray, 0, mCount);
-        }
-        
-        // Grab object from tail (after used section) if available.
-        InputWindow item = mArray[mCount + 1];
-        if (item == null) {
-            item = new InputWindow();
-        }
-        
-        mArray[mCount] = item;
-        mCount += 1;
-        mArray[mCount] = null;
-        return item;
-    }
-    
-    /**
-     * Gets the input window objects as a null-terminated array.
-     * @return The input window array.
-     */
-    public InputWindow[] toNullTerminatedArray() {
-        return mArray;
-    }
-}
\ No newline at end of file
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
index b370ec9..d298ff7 100644
--- a/services/java/com/android/server/wm/WindowState.java
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -272,7 +272,7 @@
     float mSurfaceAlpha;
     
     // Input channel and input window handle used by the input dispatcher.
-    InputWindowHandle mInputWindowHandle;
+    final InputWindowHandle mInputWindowHandle;
     InputChannel mInputChannel;
     
     // Used to improve performance of toString()
@@ -306,6 +306,7 @@
             mIsFloatingLayer = false;
             mBaseLayer = 0;
             mSubLayer = 0;
+            mInputWindowHandle = null;
             return;
         }
         mDeathRecipient = deathRecipient;
diff --git a/services/jni/Android.mk b/services/jni/Android.mk
index e1c7305..6fa5dfa 100644
--- a/services/jni/Android.mk
+++ b/services/jni/Android.mk
@@ -4,10 +4,8 @@
 LOCAL_SRC_FILES:= \
     com_android_server_AlarmManagerService.cpp \
     com_android_server_BatteryService.cpp \
-    com_android_server_InputApplication.cpp \
     com_android_server_InputApplicationHandle.cpp \
     com_android_server_InputManager.cpp \
-    com_android_server_InputWindow.cpp \
     com_android_server_InputWindowHandle.cpp \
     com_android_server_LightsService.cpp \
     com_android_server_PowerManagerService.cpp \
diff --git a/services/jni/com_android_server_AlarmManagerService.cpp b/services/jni/com_android_server_AlarmManagerService.cpp
index c9a702a..e80dd04 100644
--- a/services/jni/com_android_server_AlarmManagerService.cpp
+++ b/services/jni/com_android_server_AlarmManagerService.cpp
@@ -32,17 +32,13 @@
 #include <stdlib.h>
 #include <errno.h>
 #include <unistd.h>
-
-#ifdef HAVE_ANDROID_OS
 #include <linux/ioctl.h>
 #include <linux/android_alarm.h>
-#endif
 
 namespace android {
 
 static jint android_server_AlarmManagerService_setKernelTimezone(JNIEnv* env, jobject obj, jint fd, jint minswest)
 {
-#ifdef HAVE_ANDROID_OS
     struct timezone tz;
 
     tz.tz_minuteswest = minswest;
@@ -57,30 +53,20 @@
     }
 
     return 0;
-#else
-    return -ENOSYS;
-#endif
 }
 
 static jint android_server_AlarmManagerService_init(JNIEnv* env, jobject obj)
 {
-#ifdef HAVE_ANDROID_OS
     return open("/dev/alarm", O_RDWR);
-#else
-	return -1;
-#endif
 }
 
 static void android_server_AlarmManagerService_close(JNIEnv* env, jobject obj, jint fd)
 {
-#ifdef HAVE_ANDROID_OS
 	close(fd);
-#endif
 }
 
 static void android_server_AlarmManagerService_set(JNIEnv* env, jobject obj, jint fd, jint type, jlong seconds, jlong nanoseconds)
 {
-#ifdef HAVE_ANDROID_OS
     struct timespec ts;
     ts.tv_sec = seconds;
     ts.tv_nsec = nanoseconds;
@@ -90,12 +76,10 @@
 	{
         LOGE("Unable to set alarm to %lld.%09lld: %s\n", seconds, nanoseconds, strerror(errno));
     }
-#endif
 }
 
 static jint android_server_AlarmManagerService_waitForAlarm(JNIEnv* env, jobject obj, jint fd)
 {
-#ifdef HAVE_ANDROID_OS
 	int result = 0;
 
 	do
@@ -110,7 +94,6 @@
     }
 
     return result;
-#endif
 }
 
 static JNINativeMethod sMethods[] = {
diff --git a/services/jni/com_android_server_BatteryService.cpp b/services/jni/com_android_server_BatteryService.cpp
index 98d0d92..b9f2c1f 100644
--- a/services/jni/com_android_server_BatteryService.cpp
+++ b/services/jni/com_android_server_BatteryService.cpp
@@ -32,10 +32,7 @@
 #include <errno.h>
 #include <unistd.h>
 #include <dirent.h>
-
-#ifdef HAVE_ANDROID_OS
 #include <linux/ioctl.h>
-#endif
 
 namespace android {
 
diff --git a/services/jni/com_android_server_InputApplication.cpp b/services/jni/com_android_server_InputApplication.cpp
deleted file mode 100644
index 1f80242..0000000
--- a/services/jni/com_android_server_InputApplication.cpp
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2011 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.
- */
-
-#define LOG_TAG "InputApplication"
-
-#include "JNIHelp.h"
-#include "jni.h"
-#include <android_runtime/AndroidRuntime.h>
-
-#include "com_android_server_InputApplication.h"
-#include "com_android_server_InputApplicationHandle.h"
-
-namespace android {
-
-static struct {
-    jfieldID inputApplicationHandle;
-    jfieldID name;
-    jfieldID dispatchingTimeoutNanos;
-} gInputApplicationClassInfo;
-
-
-// --- Global functions ---
-
-void android_server_InputApplication_toNative(
-        JNIEnv* env, jobject inputApplicationObj, InputApplication* outInputApplication) {
-    jobject inputApplicationHandleObj = env->GetObjectField(inputApplicationObj,
-            gInputApplicationClassInfo.inputApplicationHandle);
-    if (inputApplicationHandleObj) {
-        outInputApplication->inputApplicationHandle =
-                android_server_InputApplicationHandle_getHandle(env, inputApplicationHandleObj);
-        env->DeleteLocalRef(inputApplicationHandleObj);
-    } else {
-        outInputApplication->inputApplicationHandle = NULL;
-    }
-
-    jstring nameObj = jstring(env->GetObjectField(inputApplicationObj,
-            gInputApplicationClassInfo.name));
-    if (nameObj) {
-        const char* nameStr = env->GetStringUTFChars(nameObj, NULL);
-        outInputApplication->name.setTo(nameStr);
-        env->ReleaseStringUTFChars(nameObj, nameStr);
-        env->DeleteLocalRef(nameObj);
-    } else {
-        LOGE("InputApplication.name should not be null.");
-        outInputApplication->name.setTo("unknown");
-    }
-
-    outInputApplication->dispatchingTimeout = env->GetLongField(inputApplicationObj,
-            gInputApplicationClassInfo.dispatchingTimeoutNanos);
-}
-
-
-// --- JNI ---
-
-#define FIND_CLASS(var, className) \
-        var = env->FindClass(className); \
-        LOG_FATAL_IF(! var, "Unable to find class " className);
-
-#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
-        var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
-        LOG_FATAL_IF(! var, "Unable to find field " fieldName);
-
-int register_android_server_InputApplication(JNIEnv* env) {
-    jclass clazz;
-    FIND_CLASS(clazz, "com/android/server/wm/InputApplication");
-
-    GET_FIELD_ID(gInputApplicationClassInfo.inputApplicationHandle,
-            clazz,
-            "inputApplicationHandle", "Lcom/android/server/wm/InputApplicationHandle;");
-
-    GET_FIELD_ID(gInputApplicationClassInfo.name, clazz,
-            "name", "Ljava/lang/String;");
-
-    GET_FIELD_ID(gInputApplicationClassInfo.dispatchingTimeoutNanos,
-            clazz,
-            "dispatchingTimeoutNanos", "J");
-    return 0;
-}
-
-} /* namespace android */
diff --git a/services/jni/com_android_server_InputApplication.h b/services/jni/com_android_server_InputApplication.h
deleted file mode 100644
index 85fb891..0000000
--- a/services/jni/com_android_server_InputApplication.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2011 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_SERVER_INPUT_APPLICATION_H
-#define _ANDROID_SERVER_INPUT_APPLICATION_H
-
-#include <input/InputApplication.h>
-
-#include "JNIHelp.h"
-#include "jni.h"
-
-namespace android {
-
-extern void android_server_InputApplication_toNative(
-        JNIEnv* env, jobject inputApplicationObj, InputApplication* outInputApplication);
-
-} // namespace android
-
-#endif // _ANDROID_SERVER_INPUT_APPLICATION_H
diff --git a/services/jni/com_android_server_InputApplicationHandle.cpp b/services/jni/com_android_server_InputApplicationHandle.cpp
index 9516964..7de67d9 100644
--- a/services/jni/com_android_server_InputApplicationHandle.cpp
+++ b/services/jni/com_android_server_InputApplicationHandle.cpp
@@ -27,6 +27,8 @@
 
 static struct {
     jfieldID ptr;
+    jfieldID name;
+    jfieldID dispatchingTimeoutNanos;
 } gInputApplicationHandleClassInfo;
 
 static Mutex gHandleMutex;
@@ -47,6 +49,31 @@
     return env->NewLocalRef(mObjWeak);
 }
 
+bool NativeInputApplicationHandle::update() {
+    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    jobject obj = env->NewLocalRef(mObjWeak);
+    if (!obj) {
+        return false;
+    }
+
+    jstring nameObj = jstring(env->GetObjectField(obj,
+            gInputApplicationHandleClassInfo.name));
+    if (nameObj) {
+        const char* nameStr = env->GetStringUTFChars(nameObj, NULL);
+        name.setTo(nameStr);
+        env->ReleaseStringUTFChars(nameObj, nameStr);
+        env->DeleteLocalRef(nameObj);
+    } else {
+        name.setTo("<null>");
+    }
+
+    dispatchingTimeout = env->GetLongField(obj,
+            gInputApplicationHandleClassInfo.dispatchingTimeoutNanos);
+
+    env->DeleteLocalRef(obj);
+    return true;
+}
+
 
 // --- Global functions ---
 
@@ -113,6 +140,13 @@
     GET_FIELD_ID(gInputApplicationHandleClassInfo.ptr, clazz,
             "ptr", "I");
 
+    GET_FIELD_ID(gInputApplicationHandleClassInfo.name, clazz,
+            "name", "Ljava/lang/String;");
+
+    GET_FIELD_ID(gInputApplicationHandleClassInfo.dispatchingTimeoutNanos,
+            clazz,
+            "dispatchingTimeoutNanos", "J");
+
     return 0;
 }
 
diff --git a/services/jni/com_android_server_InputApplicationHandle.h b/services/jni/com_android_server_InputApplicationHandle.h
index 9d18721..04cd9d6 100644
--- a/services/jni/com_android_server_InputApplicationHandle.h
+++ b/services/jni/com_android_server_InputApplicationHandle.h
@@ -31,6 +31,8 @@
 
     jobject getInputApplicationHandleObjLocalRef(JNIEnv* env);
 
+    virtual bool update();
+
 private:
     jweak mObjWeak;
 };
diff --git a/services/jni/com_android_server_InputManager.cpp b/services/jni/com_android_server_InputManager.cpp
index 14a4109..de9c9d0 100644
--- a/services/jni/com_android_server_InputManager.cpp
+++ b/services/jni/com_android_server_InputManager.cpp
@@ -46,9 +46,7 @@
 #include <android/graphics/GraphicsJNI.h>
 
 #include "com_android_server_PowerManagerService.h"
-#include "com_android_server_InputApplication.h"
 #include "com_android_server_InputApplicationHandle.h"
-#include "com_android_server_InputWindow.h"
 #include "com_android_server_InputWindowHandle.h"
 
 namespace android {
@@ -175,8 +173,8 @@
             const sp<InputWindowHandle>& inputWindowHandle, bool monitor);
     status_t unregisterInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel);
 
-    void setInputWindows(JNIEnv* env, jobjectArray windowObjArray);
-    void setFocusedApplication(JNIEnv* env, jobject applicationObj);
+    void setInputWindows(JNIEnv* env, jobjectArray windowHandleObjArray);
+    void setFocusedApplication(JNIEnv* env, jobject applicationHandleObj);
     void setInputDispatchMode(bool enabled, bool frozen);
     void setSystemUiVisibility(int32_t visibility);
     void setPointerSpeed(int32_t speed);
@@ -582,31 +580,38 @@
     return isScreenOn();
 }
 
-void NativeInputManager::setInputWindows(JNIEnv* env, jobjectArray windowObjArray) {
-    Vector<InputWindow> windows;
+void NativeInputManager::setInputWindows(JNIEnv* env, jobjectArray windowHandleObjArray) {
+    Vector<sp<InputWindowHandle> > windowHandles;
 
-    bool newPointerGesturesEnabled = true;
-    jsize length = env->GetArrayLength(windowObjArray);
-    for (jsize i = 0; i < length; i++) {
-        jobject windowObj = env->GetObjectArrayElement(windowObjArray, i);
-        if (! windowObj) {
-            break; // found null element indicating end of used portion of the array
-        }
-
-        windows.push();
-        InputWindow& window = windows.editTop();
-        android_server_InputWindow_toNative(env, windowObj, &window);
-        if (window.inputChannel == NULL) {
-            windows.pop();
-        } else if (window.hasFocus) {
-            if (window.inputFeatures & InputWindow::INPUT_FEATURE_DISABLE_TOUCH_PAD_GESTURES) {
-                newPointerGesturesEnabled = false;
+    if (windowHandleObjArray) {
+        jsize length = env->GetArrayLength(windowHandleObjArray);
+        for (jsize i = 0; i < length; i++) {
+            jobject windowHandleObj = env->GetObjectArrayElement(windowHandleObjArray, i);
+            if (! windowHandleObj) {
+                break; // found null element indicating end of used portion of the array
             }
+
+            sp<InputWindowHandle> windowHandle =
+                    android_server_InputWindowHandle_getHandle(env, windowHandleObj);
+            if (windowHandle != NULL) {
+                windowHandles.push(windowHandle);
+            }
+            env->DeleteLocalRef(windowHandleObj);
         }
-        env->DeleteLocalRef(windowObj);
     }
 
-    mInputManager->getDispatcher()->setInputWindows(windows);
+    mInputManager->getDispatcher()->setInputWindows(windowHandles);
+
+    // Do this after the dispatcher has updated the window handle state.
+    bool newPointerGesturesEnabled = true;
+    size_t numWindows = windowHandles.size();
+    for (size_t i = 0; i < numWindows; i++) {
+        const sp<InputWindowHandle>& windowHandle = windowHandles.itemAt(i);
+        if (windowHandle->hasFocus && (windowHandle->inputFeatures
+                & InputWindowHandle::INPUT_FEATURE_DISABLE_TOUCH_PAD_GESTURES)) {
+            newPointerGesturesEnabled = false;
+        }
+    }
 
     uint32_t changes = 0;
     { // acquire lock
@@ -623,16 +628,10 @@
     }
 }
 
-void NativeInputManager::setFocusedApplication(JNIEnv* env, jobject applicationObj) {
-    if (applicationObj) {
-        InputApplication application;
-        android_server_InputApplication_toNative(env, applicationObj, &application);
-        if (application.inputApplicationHandle != NULL) {
-            mInputManager->getDispatcher()->setFocusedApplication(&application);
-            return;
-        }
-    }
-    mInputManager->getDispatcher()->setFocusedApplication(NULL);
+void NativeInputManager::setFocusedApplication(JNIEnv* env, jobject applicationHandleObj) {
+    sp<InputApplicationHandle> applicationHandle =
+            android_server_InputApplicationHandle_getHandle(env, applicationHandleObj);
+    mInputManager->getDispatcher()->setFocusedApplication(applicationHandle);
 }
 
 void NativeInputManager::setInputDispatchMode(bool enabled, bool frozen) {
@@ -1137,21 +1136,21 @@
 }
 
 static void android_server_InputManager_nativeSetInputWindows(JNIEnv* env, jclass clazz,
-        jobjectArray windowObjArray) {
+        jobjectArray windowHandleObjArray) {
     if (checkInputManagerUnitialized(env)) {
         return;
     }
 
-    gNativeInputManager->setInputWindows(env, windowObjArray);
+    gNativeInputManager->setInputWindows(env, windowHandleObjArray);
 }
 
 static void android_server_InputManager_nativeSetFocusedApplication(JNIEnv* env, jclass clazz,
-        jobject applicationObj) {
+        jobject applicationHandleObj) {
     if (checkInputManagerUnitialized(env)) {
         return;
     }
 
-    gNativeInputManager->setFocusedApplication(env, applicationObj);
+    gNativeInputManager->setFocusedApplication(env, applicationHandleObj);
 }
 
 static void android_server_InputManager_nativeSetInputDispatchMode(JNIEnv* env,
@@ -1313,9 +1312,9 @@
             (void*) android_server_InputManager_nativeSetInputFilterEnabled },
     { "nativeInjectInputEvent", "(Landroid/view/InputEvent;IIIII)I",
             (void*) android_server_InputManager_nativeInjectInputEvent },
-    { "nativeSetInputWindows", "([Lcom/android/server/wm/InputWindow;)V",
+    { "nativeSetInputWindows", "([Lcom/android/server/wm/InputWindowHandle;)V",
             (void*) android_server_InputManager_nativeSetInputWindows },
-    { "nativeSetFocusedApplication", "(Lcom/android/server/wm/InputApplication;)V",
+    { "nativeSetFocusedApplication", "(Lcom/android/server/wm/InputApplicationHandle;)V",
             (void*) android_server_InputManager_nativeSetFocusedApplication },
     { "nativeSetInputDispatchMode", "(ZZ)V",
             (void*) android_server_InputManager_nativeSetInputDispatchMode },
diff --git a/services/jni/com_android_server_InputWindow.cpp b/services/jni/com_android_server_InputWindow.cpp
deleted file mode 100644
index 0426f63..0000000
--- a/services/jni/com_android_server_InputWindow.cpp
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Copyright (C) 2011 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.
- */
-
-#define LOG_TAG "InputWindow"
-
-#include "JNIHelp.h"
-#include "jni.h"
-#include <android_runtime/AndroidRuntime.h>
-
-#include <android_view_InputChannel.h>
-#include <android/graphics/Region.h>
-#include "com_android_server_InputWindow.h"
-#include "com_android_server_InputWindowHandle.h"
-
-namespace android {
-
-static struct {
-    jfieldID inputWindowHandle;
-    jfieldID inputChannel;
-    jfieldID name;
-    jfieldID layoutParamsFlags;
-    jfieldID layoutParamsType;
-    jfieldID dispatchingTimeoutNanos;
-    jfieldID frameLeft;
-    jfieldID frameTop;
-    jfieldID frameRight;
-    jfieldID frameBottom;
-    jfieldID scaleFactor;
-    jfieldID touchableRegion;
-    jfieldID visible;
-    jfieldID canReceiveKeys;
-    jfieldID hasFocus;
-    jfieldID hasWallpaper;
-    jfieldID paused;
-    jfieldID layer;
-    jfieldID ownerPid;
-    jfieldID ownerUid;
-    jfieldID inputFeatures;
-} gInputWindowClassInfo;
-
-
-// --- Global functions ---
-
-void android_server_InputWindow_toNative(
-        JNIEnv* env, jobject inputWindowObj, InputWindow* outInputWindow) {
-    jobject inputWindowHandleObj = env->GetObjectField(inputWindowObj,
-            gInputWindowClassInfo.inputWindowHandle);
-    if (inputWindowHandleObj) {
-        outInputWindow->inputWindowHandle =
-                android_server_InputWindowHandle_getHandle(env, inputWindowHandleObj);
-        env->DeleteLocalRef(inputWindowHandleObj);
-    } else {
-        outInputWindow->inputWindowHandle = NULL;
-    }
-
-    jobject inputChannelObj = env->GetObjectField(inputWindowObj,
-            gInputWindowClassInfo.inputChannel);
-    if (inputChannelObj) {
-        outInputWindow->inputChannel =
-                android_view_InputChannel_getInputChannel(env, inputChannelObj);
-        env->DeleteLocalRef(inputChannelObj);
-    } else {
-        outInputWindow->inputChannel = NULL;
-    }
-
-    jstring nameObj = jstring(env->GetObjectField(inputWindowObj,
-            gInputWindowClassInfo.name));
-    if (nameObj) {
-        const char* nameStr = env->GetStringUTFChars(nameObj, NULL);
-        outInputWindow->name.setTo(nameStr);
-        env->ReleaseStringUTFChars(nameObj, nameStr);
-        env->DeleteLocalRef(nameObj);
-    } else {
-        LOGE("InputWindow.name should not be null.");
-        outInputWindow->name.setTo("unknown");
-    }
-
-    outInputWindow->layoutParamsFlags = env->GetIntField(inputWindowObj,
-            gInputWindowClassInfo.layoutParamsFlags);
-    outInputWindow->layoutParamsType = env->GetIntField(inputWindowObj,
-            gInputWindowClassInfo.layoutParamsType);
-    outInputWindow->dispatchingTimeout = env->GetLongField(inputWindowObj,
-            gInputWindowClassInfo.dispatchingTimeoutNanos);
-    outInputWindow->frameLeft = env->GetIntField(inputWindowObj,
-            gInputWindowClassInfo.frameLeft);
-    outInputWindow->frameTop = env->GetIntField(inputWindowObj,
-            gInputWindowClassInfo.frameTop);
-    outInputWindow->frameRight = env->GetIntField(inputWindowObj,
-            gInputWindowClassInfo.frameRight);
-    outInputWindow->frameBottom = env->GetIntField(inputWindowObj,
-            gInputWindowClassInfo.frameBottom);
-    outInputWindow->scaleFactor = env->GetFloatField(inputWindowObj,
-            gInputWindowClassInfo.scaleFactor);
-
-    jobject regionObj = env->GetObjectField(inputWindowObj,
-            gInputWindowClassInfo.touchableRegion);
-    if (regionObj) {
-        SkRegion* region = android_graphics_Region_getSkRegion(env, regionObj);
-        outInputWindow->touchableRegion.set(*region);
-        env->DeleteLocalRef(regionObj);
-    } else {
-        outInputWindow->touchableRegion.setEmpty();
-    }
-
-    outInputWindow->visible = env->GetBooleanField(inputWindowObj,
-            gInputWindowClassInfo.visible);
-    outInputWindow->canReceiveKeys = env->GetBooleanField(inputWindowObj,
-            gInputWindowClassInfo.canReceiveKeys);
-    outInputWindow->hasFocus = env->GetBooleanField(inputWindowObj,
-            gInputWindowClassInfo.hasFocus);
-    outInputWindow->hasWallpaper = env->GetBooleanField(inputWindowObj,
-            gInputWindowClassInfo.hasWallpaper);
-    outInputWindow->paused = env->GetBooleanField(inputWindowObj,
-            gInputWindowClassInfo.paused);
-    outInputWindow->layer = env->GetIntField(inputWindowObj,
-            gInputWindowClassInfo.layer);
-    outInputWindow->ownerPid = env->GetIntField(inputWindowObj,
-            gInputWindowClassInfo.ownerPid);
-    outInputWindow->ownerUid = env->GetIntField(inputWindowObj,
-            gInputWindowClassInfo.ownerUid);
-    outInputWindow->inputFeatures = env->GetIntField(inputWindowObj,
-            gInputWindowClassInfo.inputFeatures);
-}
-
-
-// --- JNI ---
-
-#define FIND_CLASS(var, className) \
-        var = env->FindClass(className); \
-        LOG_FATAL_IF(! var, "Unable to find class " className);
-
-#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
-        var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
-        LOG_FATAL_IF(! var, "Unable to find field " fieldName);
-
-int register_android_server_InputWindow(JNIEnv* env) {
-    jclass clazz;
-    FIND_CLASS(clazz, "com/android/server/wm/InputWindow");
-
-    GET_FIELD_ID(gInputWindowClassInfo.inputWindowHandle, clazz,
-            "inputWindowHandle", "Lcom/android/server/wm/InputWindowHandle;");
-
-    GET_FIELD_ID(gInputWindowClassInfo.inputChannel, clazz,
-            "inputChannel", "Landroid/view/InputChannel;");
-
-    GET_FIELD_ID(gInputWindowClassInfo.name, clazz,
-            "name", "Ljava/lang/String;");
-
-    GET_FIELD_ID(gInputWindowClassInfo.layoutParamsFlags, clazz,
-            "layoutParamsFlags", "I");
-
-    GET_FIELD_ID(gInputWindowClassInfo.layoutParamsType, clazz,
-            "layoutParamsType", "I");
-
-    GET_FIELD_ID(gInputWindowClassInfo.dispatchingTimeoutNanos, clazz,
-            "dispatchingTimeoutNanos", "J");
-
-    GET_FIELD_ID(gInputWindowClassInfo.frameLeft, clazz,
-            "frameLeft", "I");
-
-    GET_FIELD_ID(gInputWindowClassInfo.frameTop, clazz,
-            "frameTop", "I");
-
-    GET_FIELD_ID(gInputWindowClassInfo.frameRight, clazz,
-            "frameRight", "I");
-
-    GET_FIELD_ID(gInputWindowClassInfo.frameBottom, clazz,
-            "frameBottom", "I");
-
-    GET_FIELD_ID(gInputWindowClassInfo.scaleFactor, clazz,
-            "scaleFactor", "F");
-
-    GET_FIELD_ID(gInputWindowClassInfo.touchableRegion, clazz,
-            "touchableRegion", "Landroid/graphics/Region;");
-
-    GET_FIELD_ID(gInputWindowClassInfo.visible, clazz,
-            "visible", "Z");
-
-    GET_FIELD_ID(gInputWindowClassInfo.canReceiveKeys, clazz,
-            "canReceiveKeys", "Z");
-
-    GET_FIELD_ID(gInputWindowClassInfo.hasFocus, clazz,
-            "hasFocus", "Z");
-
-    GET_FIELD_ID(gInputWindowClassInfo.hasWallpaper, clazz,
-            "hasWallpaper", "Z");
-
-    GET_FIELD_ID(gInputWindowClassInfo.paused, clazz,
-            "paused", "Z");
-
-    GET_FIELD_ID(gInputWindowClassInfo.layer, clazz,
-            "layer", "I");
-
-    GET_FIELD_ID(gInputWindowClassInfo.ownerPid, clazz,
-            "ownerPid", "I");
-
-    GET_FIELD_ID(gInputWindowClassInfo.ownerUid, clazz,
-            "ownerUid", "I");
-
-    GET_FIELD_ID(gInputWindowClassInfo.inputFeatures, clazz,
-            "inputFeatures", "I");
-    return 0;
-}
-
-} /* namespace android */
diff --git a/services/jni/com_android_server_InputWindow.h b/services/jni/com_android_server_InputWindow.h
deleted file mode 100644
index eaf7bde..0000000
--- a/services/jni/com_android_server_InputWindow.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2011 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_SERVER_INPUT_WINDOW_H
-#define _ANDROID_SERVER_INPUT_WINDOW_H
-
-#include <input/InputWindow.h>
-
-#include "JNIHelp.h"
-#include "jni.h"
-
-namespace android {
-
-extern void android_server_InputWindow_toNative(
-        JNIEnv* env, jobject inputWindowObj, InputWindow* outInputWindow);
-
-} // namespace android
-
-#endif // _ANDROID_SERVER_INPUT_WINDOW_H
diff --git a/services/jni/com_android_server_InputWindowHandle.cpp b/services/jni/com_android_server_InputWindowHandle.cpp
index aaf679c..09be881 100644
--- a/services/jni/com_android_server_InputWindowHandle.cpp
+++ b/services/jni/com_android_server_InputWindowHandle.cpp
@@ -21,6 +21,9 @@
 #include <android_runtime/AndroidRuntime.h>
 #include <utils/threads.h>
 
+#include <android_view_InputChannel.h>
+#include <android/graphics/Region.h>
+
 #include "com_android_server_InputWindowHandle.h"
 #include "com_android_server_InputApplicationHandle.h"
 
@@ -29,6 +32,26 @@
 static struct {
     jfieldID ptr;
     jfieldID inputApplicationHandle;
+    jfieldID inputChannel;
+    jfieldID name;
+    jfieldID layoutParamsFlags;
+    jfieldID layoutParamsType;
+    jfieldID dispatchingTimeoutNanos;
+    jfieldID frameLeft;
+    jfieldID frameTop;
+    jfieldID frameRight;
+    jfieldID frameBottom;
+    jfieldID scaleFactor;
+    jfieldID touchableRegion;
+    jfieldID visible;
+    jfieldID canReceiveKeys;
+    jfieldID hasFocus;
+    jfieldID hasWallpaper;
+    jfieldID paused;
+    jfieldID layer;
+    jfieldID ownerPid;
+    jfieldID ownerUid;
+    jfieldID inputFeatures;
 } gInputWindowHandleClassInfo;
 
 static Mutex gHandleMutex;
@@ -51,6 +74,83 @@
     return env->NewLocalRef(mObjWeak);
 }
 
+bool NativeInputWindowHandle::update() {
+    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    jobject obj = env->NewLocalRef(mObjWeak);
+    if (!obj) {
+        return false;
+    }
+
+    jobject inputChannelObj = env->GetObjectField(obj,
+            gInputWindowHandleClassInfo.inputChannel);
+    if (inputChannelObj) {
+        inputChannel = android_view_InputChannel_getInputChannel(env, inputChannelObj);
+        env->DeleteLocalRef(inputChannelObj);
+    } else {
+        inputChannel = NULL;
+    }
+
+    jstring nameObj = jstring(env->GetObjectField(obj,
+            gInputWindowHandleClassInfo.name));
+    if (nameObj) {
+        const char* nameStr = env->GetStringUTFChars(nameObj, NULL);
+        name.setTo(nameStr);
+        env->ReleaseStringUTFChars(nameObj, nameStr);
+        env->DeleteLocalRef(nameObj);
+    } else {
+        name.setTo("<null>");
+    }
+
+    layoutParamsFlags = env->GetIntField(obj,
+            gInputWindowHandleClassInfo.layoutParamsFlags);
+    layoutParamsType = env->GetIntField(obj,
+            gInputWindowHandleClassInfo.layoutParamsType);
+    dispatchingTimeout = env->GetLongField(obj,
+            gInputWindowHandleClassInfo.dispatchingTimeoutNanos);
+    frameLeft = env->GetIntField(obj,
+            gInputWindowHandleClassInfo.frameLeft);
+    frameTop = env->GetIntField(obj,
+            gInputWindowHandleClassInfo.frameTop);
+    frameRight = env->GetIntField(obj,
+            gInputWindowHandleClassInfo.frameRight);
+    frameBottom = env->GetIntField(obj,
+            gInputWindowHandleClassInfo.frameBottom);
+    scaleFactor = env->GetFloatField(obj,
+            gInputWindowHandleClassInfo.scaleFactor);
+
+    jobject regionObj = env->GetObjectField(obj,
+            gInputWindowHandleClassInfo.touchableRegion);
+    if (regionObj) {
+        SkRegion* region = android_graphics_Region_getSkRegion(env, regionObj);
+        touchableRegion.set(*region);
+        env->DeleteLocalRef(regionObj);
+    } else {
+        touchableRegion.setEmpty();
+    }
+
+    visible = env->GetBooleanField(obj,
+            gInputWindowHandleClassInfo.visible);
+    canReceiveKeys = env->GetBooleanField(obj,
+            gInputWindowHandleClassInfo.canReceiveKeys);
+    hasFocus = env->GetBooleanField(obj,
+            gInputWindowHandleClassInfo.hasFocus);
+    hasWallpaper = env->GetBooleanField(obj,
+            gInputWindowHandleClassInfo.hasWallpaper);
+    paused = env->GetBooleanField(obj,
+            gInputWindowHandleClassInfo.paused);
+    layer = env->GetIntField(obj,
+            gInputWindowHandleClassInfo.layer);
+    ownerPid = env->GetIntField(obj,
+            gInputWindowHandleClassInfo.ownerPid);
+    ownerUid = env->GetIntField(obj,
+            gInputWindowHandleClassInfo.ownerUid);
+    inputFeatures = env->GetIntField(obj,
+            gInputWindowHandleClassInfo.inputFeatures);
+
+    env->DeleteLocalRef(obj);
+    return true;
+}
+
 
 // --- Global functions ---
 
@@ -127,6 +227,65 @@
             clazz,
             "inputApplicationHandle", "Lcom/android/server/wm/InputApplicationHandle;");
 
+    GET_FIELD_ID(gInputWindowHandleClassInfo.inputChannel, clazz,
+            "inputChannel", "Landroid/view/InputChannel;");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.name, clazz,
+            "name", "Ljava/lang/String;");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.layoutParamsFlags, clazz,
+            "layoutParamsFlags", "I");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.layoutParamsType, clazz,
+            "layoutParamsType", "I");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.dispatchingTimeoutNanos, clazz,
+            "dispatchingTimeoutNanos", "J");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.frameLeft, clazz,
+            "frameLeft", "I");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.frameTop, clazz,
+            "frameTop", "I");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.frameRight, clazz,
+            "frameRight", "I");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.frameBottom, clazz,
+            "frameBottom", "I");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.scaleFactor, clazz,
+            "scaleFactor", "F");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.touchableRegion, clazz,
+            "touchableRegion", "Landroid/graphics/Region;");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.visible, clazz,
+            "visible", "Z");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.canReceiveKeys, clazz,
+            "canReceiveKeys", "Z");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.hasFocus, clazz,
+            "hasFocus", "Z");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.hasWallpaper, clazz,
+            "hasWallpaper", "Z");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.paused, clazz,
+            "paused", "Z");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.layer, clazz,
+            "layer", "I");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.ownerPid, clazz,
+            "ownerPid", "I");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.ownerUid, clazz,
+            "ownerUid", "I");
+
+    GET_FIELD_ID(gInputWindowHandleClassInfo.inputFeatures, clazz,
+            "inputFeatures", "I");
     return 0;
 }
 
diff --git a/services/jni/com_android_server_InputWindowHandle.h b/services/jni/com_android_server_InputWindowHandle.h
index 43f2a6b..913c3b1 100644
--- a/services/jni/com_android_server_InputWindowHandle.h
+++ b/services/jni/com_android_server_InputWindowHandle.h
@@ -32,6 +32,8 @@
 
     jobject getInputWindowHandleObjLocalRef(JNIEnv* env);
 
+    virtual bool update();
+
 private:
     jweak mObjWeak;
 };
diff --git a/services/jni/onload.cpp b/services/jni/onload.cpp
index 9dff48b..4178039 100644
--- a/services/jni/onload.cpp
+++ b/services/jni/onload.cpp
@@ -22,9 +22,7 @@
 namespace android {
 int register_android_server_AlarmManagerService(JNIEnv* env);
 int register_android_server_BatteryService(JNIEnv* env);
-int register_android_server_InputApplication(JNIEnv* env);
 int register_android_server_InputApplicationHandle(JNIEnv* env);
-int register_android_server_InputWindow(JNIEnv* env);
 int register_android_server_InputWindowHandle(JNIEnv* env);
 int register_android_server_InputManager(JNIEnv* env);
 int register_android_server_LightsService(JNIEnv* env);
@@ -51,9 +49,7 @@
     LOG_ASSERT(env, "Could not retrieve the env!");
 
     register_android_server_PowerManagerService(env);
-    register_android_server_InputApplication(env);
     register_android_server_InputApplicationHandle(env);
-    register_android_server_InputWindow(env);
     register_android_server_InputWindowHandle(env);
     register_android_server_InputManager(env);
     register_android_server_LightsService(env);