Merge "Avoid throwing when forceRefresh() missing server."
diff --git a/core/java/android/hardware/SensorEvent.java b/core/java/android/hardware/SensorEvent.java
index 91f0098..b111b84 100644
--- a/core/java/android/hardware/SensorEvent.java
+++ b/core/java/android/hardware/SensorEvent.java
@@ -204,6 +204,12 @@
      * values[0]: Ambient light level in SI lux units
      * </ul>
      * 
+     * <h4>{@link android.hardware.Sensor#TYPE_PRESSURE Sensor.TYPE_PRESSURE}:</h4>
+     * <ul>
+     * <p>
+     * values[0]: Atmospheric pressure in hPa (millibar)
+     * </ul>
+     *
      * <h4>{@link android.hardware.Sensor#TYPE_PROXIMITY Sensor.TYPE_PROXIMITY}:
      * </h4>
      * 
@@ -247,6 +253,23 @@
      *  <p>Elements of the rotation vector are unitless.
      *  The x,y, and z axis are defined in the same way as the acceleration
      *  sensor.</p>
+     *  The reference coordinate system is defined as a direct orthonormal basis,
+     *  where:
+     * </p>
+     *
+     * <ul>
+     * <li>X is defined as the vector product <b>Y.Z</b> (It is tangential to
+     * the ground at the device's current location and roughly points East).</li>
+     * <li>Y is tangential to the ground at the device's current location and
+     * points towards the magnetic North Pole.</li>
+     * <li>Z points towards the sky and is perpendicular to the ground.</li>
+     * </ul>
+     *
+     * <p>
+     * <center><img src="../../../images/axis_globe.png"
+     * alt="World coordinate-system diagram." border="0" /></center>
+     * </p>
+     *
      * <ul>
      * <p>
      * values[0]: x*sin(&#952/2)
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index b0f3ac3..e344197 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -2080,7 +2080,6 @@
         final int NU = uidStats.size();
         boolean didPid = false;
         long nowRealtime = SystemClock.elapsedRealtime();
-        StringBuilder sb = new StringBuilder(64);
         for (int i=0; i<NU; i++) {
             Uid uid = uidStats.valueAt(i);
             SparseArray<? extends Uid.Pid> pids = uid.getPidStats();
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 8a18aaf..9395d5c 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -388,6 +388,12 @@
         public static final int TYPE_POINTER = FIRST_SYSTEM_WINDOW+18;
 
         /**
+         * Window type: Navigation bar (when distinct from status bar)
+         * @hide
+         */
+        public static final int TYPE_NAVIGATION_BAR = FIRST_SYSTEM_WINDOW+19;
+
+        /**
          * End of types of system windows.
          */
         public static final int LAST_SYSTEM_WINDOW      = 2999;
diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java
index 5c3563f..1e576ce 100644
--- a/core/java/com/android/internal/app/ActionBarImpl.java
+++ b/core/java/com/android/internal/app/ActionBarImpl.java
@@ -396,7 +396,10 @@
         int selectedTabPosition = mSelectedTab != null
                 ? mSelectedTab.getPosition() : mSavedTabPosition;
         mActionView.removeTabAt(position);
-        mTabs.remove(position);
+        TabImpl removedTab = mTabs.remove(position);
+        if (removedTab != null) {
+            removedTab.setPosition(-1);
+        }
 
         final int newTabCount = mTabs.size();
         for (int i = position; i < newTabCount; i++) {
@@ -670,7 +673,7 @@
         private Object mTag;
         private Drawable mIcon;
         private CharSequence mText;
-        private int mPosition;
+        private int mPosition = -1;
         private View mCustomView;
 
         @Override
@@ -702,6 +705,7 @@
         @Override
         public Tab setCustomView(View view) {
             mCustomView = view;
+            if (mPosition >= 0) mActionView.updateTab(mPosition);
             return this;
         }
 
@@ -732,6 +736,7 @@
         @Override
         public Tab setIcon(Drawable icon) {
             mIcon = icon;
+            if (mPosition >= 0) mActionView.updateTab(mPosition);
             return this;
         }
 
@@ -743,6 +748,7 @@
         @Override
         public Tab setText(CharSequence text) {
             mText = text;
+            if (mPosition >= 0) mActionView.updateTab(mPosition);
             return this;
         }
 
diff --git a/core/java/com/android/internal/view/menu/MenuDialogHelper.java b/core/java/com/android/internal/view/menu/MenuDialogHelper.java
index 6387c9b..5c8e057 100644
--- a/core/java/com/android/internal/view/menu/MenuDialogHelper.java
+++ b/core/java/com/android/internal/view/menu/MenuDialogHelper.java
@@ -37,6 +37,7 @@
     private MenuBuilder mMenu;
     private AlertDialog mDialog;
     ListMenuPresenter mPresenter;
+    private MenuPresenter.Callback mPresenterCallback;
     
     public MenuDialogHelper(MenuBuilder menu) {
         mMenu = menu;
@@ -124,6 +125,10 @@
 
     }
 
+    public void setPresenterCallback(MenuPresenter.Callback cb) {
+        mPresenterCallback = cb;
+    }
+
     /**
      * Dismisses the menu's dialog.
      * 
@@ -145,10 +150,16 @@
         if (allMenusAreClosing || menu == mMenu) {
             dismiss();
         }
+        if (mPresenterCallback != null) {
+            mPresenterCallback.onCloseMenu(menu, allMenusAreClosing);
+        }
     }
 
     @Override
     public boolean onOpenSubMenu(MenuBuilder subMenu) {
+        if (mPresenterCallback != null) {
+            return mPresenterCallback.onOpenSubMenu(subMenu);
+        }
         return false;
     }
 
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index d4813ba..d6f439a 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -390,8 +390,8 @@
             mHomeLayout.setVisibility(vis);
 
             if ((flagsChanged & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
-                mHomeAsUpView.setVisibility((options & ActionBar.DISPLAY_HOME_AS_UP) != 0
-                        ? VISIBLE : GONE);
+                final boolean isUp = (options & ActionBar.DISPLAY_HOME_AS_UP) != 0;
+                mHomeAsUpView.setVisibility(isUp ? VISIBLE : GONE);
             }
 
             if ((flagsChanged & ActionBar.DISPLAY_USE_LOGO) != 0) {
@@ -419,6 +419,17 @@
         } else {
             invalidate();
         }
+
+        // Make sure the home button has an accurate content description for accessibility.
+        if ((options & ActionBar.DISPLAY_DISABLE_HOME) != 0) {
+            mHomeLayout.setContentDescription(null);
+        } else if ((options & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
+            mHomeLayout.setContentDescription(mContext.getResources().getText(
+                    R.string.action_bar_up_description));
+        } else {
+            mHomeLayout.setContentDescription(mContext.getResources().getText(
+                    R.string.action_bar_home_description));
+        }
     }
 
     public void setIcon(Drawable icon) {
@@ -587,6 +598,10 @@
         }
     }
 
+    public void updateTab(int position) {
+        ((TabView) mTabLayout.getChildAt(position)).update();
+    }
+
     public void removeTabAt(int position) {
         if (mTabLayout != null) {
             mTabLayout.removeViewAt(position);
@@ -929,46 +944,76 @@
 
     private static class TabView extends LinearLayout {
         private ActionBar.Tab mTab;
+        private TextView mTextView;
+        private ImageView mIconView;
+        private View mCustomView;
 
         public TabView(Context context, ActionBar.Tab tab) {
             super(context, null, com.android.internal.R.attr.actionBarTabStyle);
             mTab = tab;
 
+            update();
+
+            setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
+                    LayoutParams.MATCH_PARENT, 1));
+        }
+
+        public void update() {
+            final ActionBar.Tab tab = mTab;
             final View custom = tab.getCustomView();
             if (custom != null) {
                 addView(custom);
+                mCustomView = custom;
+                if (mTextView != null) mTextView.setVisibility(GONE);
+                if (mIconView != null) {
+                    mIconView.setVisibility(GONE);
+                    mIconView.setImageDrawable(null);
+                }
             } else {
-                // TODO Style tabs based on the theme
+                if (mCustomView != null) {
+                    removeView(mCustomView);
+                    mCustomView = null;
+                }
 
                 final Drawable icon = tab.getIcon();
                 final CharSequence text = tab.getText();
 
                 if (icon != null) {
-                    ImageView iconView = new ImageView(context);
-                    iconView.setImageDrawable(icon);
-                    LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT,
-                            LayoutParams.WRAP_CONTENT);
-                    lp.gravity = Gravity.CENTER_VERTICAL;
-                    iconView.setLayoutParams(lp);
-                    addView(iconView);
+                    if (mIconView == null) {
+                        ImageView iconView = new ImageView(getContext());
+                        LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT,
+                                LayoutParams.WRAP_CONTENT);
+                        lp.gravity = Gravity.CENTER_VERTICAL;
+                        iconView.setLayoutParams(lp);
+                        addView(iconView, 0);
+                        mIconView = iconView;
+                    }
+                    mIconView.setImageDrawable(icon);
+                    mIconView.setVisibility(VISIBLE);
+                } else if (mIconView != null) {
+                    mIconView.setVisibility(GONE);
+                    mIconView.setImageDrawable(null);
                 }
 
                 if (text != null) {
-                    TextView textView = new TextView(context, null,
-                            com.android.internal.R.attr.actionBarTabTextStyle);
-                    textView.setText(text);
-                    textView.setSingleLine();
-                    textView.setEllipsize(TruncateAt.END);
-                    LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT,
-                            LayoutParams.WRAP_CONTENT);
-                    lp.gravity = Gravity.CENTER_VERTICAL;
-                    textView.setLayoutParams(lp);
-                    addView(textView);
+                    if (mTextView == null) {
+                        TextView textView = new TextView(getContext(), null,
+                                com.android.internal.R.attr.actionBarTabTextStyle);
+                        textView.setSingleLine();
+                        textView.setEllipsize(TruncateAt.END);
+                        LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT,
+                                LayoutParams.WRAP_CONTENT);
+                        lp.gravity = Gravity.CENTER_VERTICAL;
+                        textView.setLayoutParams(lp);
+                        addView(textView);
+                        mTextView = textView;
+                    }
+                    mTextView.setText(text);
+                    mTextView.setVisibility(VISIBLE);
+                } else {
+                    mTextView.setVisibility(GONE);
                 }
             }
-
-            setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
-                    LayoutParams.MATCH_PARENT, 1));
         }
 
         public ActionBar.Tab getTab() {
diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp
index 97580f54..4687ee0 100644
--- a/core/jni/android_hardware_Camera.cpp
+++ b/core/jni/android_hardware_Camera.cpp
@@ -218,7 +218,7 @@
 
                         if (mCallbackBuffers.isEmpty()) {
                             LOGV("Out of buffers, clearing callback!");
-                            mCamera->setPreviewCallbackFlags(FRAME_CALLBACK_FLAG_NOOP);
+                            mCamera->setPreviewCallbackFlags(CAMERA_FRAME_CALLBACK_FLAG_NOOP);
                             mManualCameraCallbackSet = false;
 
                             if (obj == NULL) {
@@ -305,22 +305,22 @@
     mManualCameraCallbackSet = false;
 
     // In order to limit the over usage of binder threads, all non-manual buffer
-    // callbacks use FRAME_CALLBACK_FLAG_BARCODE_SCANNER mode now.
+    // callbacks use CAMERA_FRAME_CALLBACK_FLAG_BARCODE_SCANNER mode now.
     //
     // Continuous callbacks will have the callback re-registered from handleMessage.
     // Manual buffer mode will operate as fast as possible, relying on the finite supply
     // of buffers for throttling.
 
     if (!installed) {
-        mCamera->setPreviewCallbackFlags(FRAME_CALLBACK_FLAG_NOOP);
+        mCamera->setPreviewCallbackFlags(CAMERA_FRAME_CALLBACK_FLAG_NOOP);
         clearCallbackBuffers_l(env, &mCallbackBuffers);
     } else if (mManualBufferMode) {
         if (!mCallbackBuffers.isEmpty()) {
-            mCamera->setPreviewCallbackFlags(FRAME_CALLBACK_FLAG_CAMERA);
+            mCamera->setPreviewCallbackFlags(CAMERA_FRAME_CALLBACK_FLAG_CAMERA);
             mManualCameraCallbackSet = true;
         }
     } else {
-        mCamera->setPreviewCallbackFlags(FRAME_CALLBACK_FLAG_BARCODE_SCANNER);
+        mCamera->setPreviewCallbackFlags(CAMERA_FRAME_CALLBACK_FLAG_BARCODE_SCANNER);
         clearCallbackBuffers_l(env, &mCallbackBuffers);
     }
 }
@@ -343,7 +343,7 @@
                 // next frame. This may have come unset had we not had a
                 // callbackbuffer ready for it last time.
                 if (mManualBufferMode && !mManualCameraCallbackSet) {
-                    mCamera->setPreviewCallbackFlags(FRAME_CALLBACK_FLAG_CAMERA);
+                    mCamera->setPreviewCallbackFlags(CAMERA_FRAME_CALLBACK_FLAG_CAMERA);
                     mManualCameraCallbackSet = true;
                 }
                 break;
@@ -456,7 +456,7 @@
 
         // clear callbacks
         if (camera != NULL) {
-            camera->setPreviewCallbackFlags(FRAME_CALLBACK_FLAG_NOOP);
+            camera->setPreviewCallbackFlags(CAMERA_FRAME_CALLBACK_FLAG_NOOP);
             camera->disconnect();
         }
 
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index 0681195..b432d65 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -282,6 +282,16 @@
             code, (int32_t)&data, (int32_t)reply, flags);
         jthrowable excep = env->ExceptionOccurred();
 
+        if (excep) {
+            report_exception(env, excep,
+                "*** Uncaught remote exception!  "
+                "(Exceptions are not yet supported across processes.)");
+            res = JNI_FALSE;
+
+            /* clean up JNI local ref -- we don't return to Java code */
+            env->DeleteLocalRef(excep);
+        }
+
         // Restore the Java binder thread's state if it changed while
         // processing a call (as it would if the Parcel's header had a
         // new policy mask and Parcel.enforceInterface() changed
@@ -294,14 +304,12 @@
             set_dalvik_blockguard_policy(env, strict_policy_before);
         }
 
-        if (excep) {
-            report_exception(env, excep,
-                "*** Uncaught remote exception!  "
-                "(Exceptions are not yet supported across processes.)");
-            res = JNI_FALSE;
-
+        jthrowable excep2 = env->ExceptionOccurred();
+        if (excep2) {
+            report_exception(env, excep2,
+                "*** Uncaught exception in onBinderStrictModePolicyChange");
             /* clean up JNI local ref -- we don't return to Java code */
-            env->DeleteLocalRef(excep);
+            env->DeleteLocalRef(excep2);
         }
 
         //aout << "onTransact to Java code; result=" << res << endl
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 2ed39e4..1c4bffd 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -496,6 +496,12 @@
         android:label="@string/permlab_hardware_test"
         android:description="@string/permdesc_hardware_test" />
 
+    <!-- Allows access to configure network interfaces, configure/use IPSec, etc.
+         @hide -->
+    <permission android:name="android.permission.NET_ADMIN"
+        android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
+        android:protectionLevel="signature" />
+
     <!-- =========================================== -->
     <!-- Permissions associated with telephony state -->
     <!-- =========================================== -->
diff --git a/core/res/res/layout/status_bar_latest_event_content.xml b/core/res/res/layout/status_bar_latest_event_content.xml
index c64b90e..676c38b 100644
--- a/core/res/res/layout/status_bar_latest_event_content.xml
+++ b/core/res/res/layout/status_bar_latest_event_content.xml
@@ -1,56 +1,48 @@
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:orientation="vertical"
-        android:paddingTop="7dp"
-        android:paddingLeft="5dp"
-        >
-
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    >
+    <ImageView android:id="@+id/icon"
+        android:layout_width="@dimen/notification_large_icon_width"
+        android:layout_height="@dimen/notification_large_icon_height"
+        android:background="@drawable/notify_panel_notification_icon_bg"
+        android:scaleType="center"
+        />
     <LinearLayout
-        android:layout_width="match_parent"
+        android:layout_width="0dp"
         android:layout_height="wrap_content"
-        android:orientation="horizontal"
-        android:paddingTop="3dp"
+        android:layout_gravity="center_vertical"
+        android:layout_weight="1"
+        android:orientation="vertical"
+        android:paddingLeft="16dp"
         >
-        <!--com.android.server.status.AnimatedImageView android:id="@+id/icon" -->
-        <ImageView android:id="@+id/icon"
-            android:layout_width="25dp"
-            android:layout_height="25dp"
-            android:scaleType="fitCenter"
-            android:src="@drawable/arrow_down_float"/>
         <TextView android:id="@+id/title"
             android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Title"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_weight="1"
             android:singleLine="true"
             android:ellipsize="marquee"
             android:fadingEdge="horizontal"
-            android:paddingLeft="4dp"
+            android:layout_marginBottom="-3dp"
             />
-    </LinearLayout>
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal"
-        >
         <TextView android:id="@+id/text"
             android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
-            android:layout_width="wrap_content"
+            android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_weight="1"
+            android:layout_marginTop="-2dp"
             android:singleLine="true"
             android:ellipsize="marquee"
             android:fadingEdge="horizontal"
-            android:paddingLeft="4dp"
-            />
-        <android.widget.DateTimeView android:id="@+id/time"
-            android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
-            android:layout_marginLeft="4dp"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:singleLine="true"
-            android:paddingRight="5dp"
             />
     </LinearLayout>
+    <TextView android:id="@+id/info"
+        android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Info"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:singleLine="true"
+        android:gravity="center_vertical"
+        android:paddingLeft="8dp"
+        />
 </LinearLayout>
+
diff --git a/core/res/res/layout/status_bar_latest_event_content_large_icon.xml b/core/res/res/layout/status_bar_latest_event_content_large_icon.xml
new file mode 100644
index 0000000..ebdaaa3
--- /dev/null
+++ b/core/res/res/layout/status_bar_latest_event_content_large_icon.xml
@@ -0,0 +1,50 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    >
+    <LinearLayout
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_vertical"
+        android:layout_weight="1"
+        android:orientation="vertical"
+        android:paddingLeft="16dp"
+        >
+        <TextView android:id="@+id/title"
+            android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Title"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:singleLine="true"
+            android:ellipsize="marquee"
+            android:fadingEdge="horizontal"
+            android:layout_marginBottom="-3dp"
+            />
+        <TextView android:id="@+id/text"
+            android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:layout_marginTop="-2dp"
+            android:singleLine="true"
+            android:ellipsize="marquee"
+            android:fadingEdge="horizontal"
+            />
+    </LinearLayout>
+    <TextView android:id="@+id/info"
+        android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Info"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:singleLine="true"
+        android:gravity="center_vertical"
+        android:paddingLeft="4dp"
+        android:paddingRight="4dp"
+        />
+    <ImageView android:id="@+id/icon"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="bottom"
+        android:layout_marginBottom="13dip"
+        android:scaleType="center"
+        />
+</LinearLayout>
+
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index bc419ec..fa662ed 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2815,4 +2815,10 @@
     <!-- Description of the button to decrement the NumberPicker value. [CHAR LIMIT=NONE] -->
     <string name="number_picker_decrement_button">Decrement</string>
 
+    <!-- Content description for the action bar "home" affordance. [CHAR LIMIT=NONE] -->
+    <string name="action_bar_home_description">Navigate home</string>
+    <!-- Content description for the action bar "up" affordance. [CHAR LIMIT=NONE] -->
+    <string name="action_bar_up_description">Navigate up</string>
+    <!-- Content description for the action menu overflow button. [CHAR LIMIT=NONE] -->
+    <string name="action_menu_overflow_description">More options</string>
 </resources>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index e666698..2d44f62 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -217,7 +217,6 @@
 
     <style name="TextAppearance.StatusBar">
         <item name="android:textAppearance">?android:attr/textAppearanceSmall</item>
-        <item name="android:textColor">?android:attr/textColorPrimary</item>
     </style>
     <style name="TextAppearance.StatusBar.Ticker">
     </style>
@@ -226,15 +225,13 @@
     </style>
 
     <style name="TextAppearance.StatusBar.Icon">
-        <item name="android:textStyle">bold</item>
     </style>
     <style name="TextAppearance.StatusBar.EventContent">
-        <item name="android:textAppearance">?android:attr/textAppearanceSmall</item>
-        <item name="android:textColor">?android:attr/textColorPrimaryInverse</item>
+        <item name="android:textColor">#ff999999</item>
+        <item name="android:textSize">14sp</item>
     </style>
     <style name="TextAppearance.StatusBar.EventContent.Title">
-        <item name="android:textSize">18sp</item>
-        <item name="android:textStyle">bold</item>
+        <item name="android:textColor">?android:attr/textColorPrimary</item>
     </style>
     <style name="TextAppearance.StatusBar.EventContent.Info">
         <item name="android:textAppearance">?android:attr/textAppearanceLarge</item>
@@ -1117,7 +1114,7 @@
 
     <style name="Widget.ActionButton.Overflow">
         <item name="android:src">@drawable/ic_menu_more</item>
-        <item name="android:contentDescription">@string/more_item_label</item>
+        <item name="android:contentDescription">@string/action_menu_overflow_description</item>
     </style>
 
     <style name="Widget.ActionButton.CloseMode">
@@ -1778,6 +1775,7 @@
         <item name="android:background">?android:attr/selectableItemBackground</item>
         <item name="android:paddingLeft">16dip</item>
         <item name="android:paddingRight">16dip</item>
+        <item name="android:contentDescription">@string/action_menu_overflow_description</item>
     </style>
 
     <style name="Widget.Holo.ActionButton.TextButton" parent="Widget.Holo.ButtonBar.Button">
@@ -2112,6 +2110,7 @@
         <item name="android:src">@android:drawable/ic_menu_moreoverflow_holo_light</item>
         <item name="android:paddingLeft">16dip</item>
         <item name="android:paddingRight">16dip</item>
+        <item name="android:contentDescription">@string/action_menu_overflow_description</item>
     </style>
 
     <style name="Widget.Holo.Light.ActionBarView_TabView" parent="Widget.Holo.ActionBarView_TabView">
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index 1870a4a..5ed7966 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -66,6 +66,10 @@
         <group gid="mtp" />
     </permission>
 
+    <permission name="android.permission.NET_ADMIN" >
+        <group gid="net_admin" />
+    </permission>
+
     <!-- The group that /cache belongs to, linked to the permission
          set on the applications that can access /cache -->
     <permission name="android.permission.ACCESS_CACHE_FILESYSTEM" >
diff --git a/docs/html/guide/topics/graphics/animation.jd b/docs/html/guide/topics/graphics/animation.jd
index 3b1716c..e10ab3e 100644
--- a/docs/html/guide/topics/graphics/animation.jd
+++ b/docs/html/guide/topics/graphics/animation.jd
@@ -903,7 +903,7 @@
     <code>"floatType"</code> unless you specify something else or if the <code>valuesFrom</code>
     and <code>valuesTo</code> values are colors.</dd>
 
-    <dt><code>android:startDelay</code></dt>
+    <dt><code>android:startOffset</code></dt>
 
     <dd>The delay, in milliseconds, before the animation begins playing (after calling {@link
     android.animation.ValueAnimator#start start()}).</dd>
diff --git a/include/camera/Camera.h b/include/camera/Camera.h
index 3c6dccc..7106bfa 100644
--- a/include/camera/Camera.h
+++ b/include/camera/Camera.h
@@ -20,122 +20,28 @@
 #include <utils/Timers.h>
 #include <camera/ICameraClient.h>
 #include <gui/ISurfaceTexture.h>
+#include <system/camera.h>
 
 namespace android {
 
-/*
- * A set of bit masks for specifying how the received preview frames are
- * handled before the previewCallback() call.
- *
- * The least significant 3 bits of an "int" value are used for this purpose:
- *
- * ..... 0 0 0
- *       ^ ^ ^
- *       | | |---------> determine whether the callback is enabled or not
- *       | |-----------> determine whether the callback is one-shot or not
- *       |-------------> determine whether the frame is copied out or not
- *
- * WARNING:
- * When a frame is sent directly without copying, it is the frame receiver's
- * responsiblity to make sure that the frame data won't get corrupted by
- * subsequent preview frames filled by the camera. This flag is recommended
- * only when copying out data brings significant performance price and the
- * handling/processing of the received frame data is always faster than
- * the preview frame rate so that data corruption won't occur.
- *
- * For instance,
- * 1. 0x00 disables the callback. In this case, copy out and one shot bits
- *    are ignored.
- * 2. 0x01 enables a callback without copying out the received frames. A
- *    typical use case is the Camcorder application to avoid making costly
- *    frame copies.
- * 3. 0x05 is enabling a callback with frame copied out repeatedly. A typical
- *    use case is the Camera application.
- * 4. 0x07 is enabling a callback with frame copied out only once. A typical use
- *    case is the Barcode scanner application.
- */
-#define FRAME_CALLBACK_FLAG_ENABLE_MASK              0x01
-#define FRAME_CALLBACK_FLAG_ONE_SHOT_MASK            0x02
-#define FRAME_CALLBACK_FLAG_COPY_OUT_MASK            0x04
-
-// Typical use cases
-#define FRAME_CALLBACK_FLAG_NOOP                     0x00
-#define FRAME_CALLBACK_FLAG_CAMCORDER                0x01
-#define FRAME_CALLBACK_FLAG_CAMERA                   0x05
-#define FRAME_CALLBACK_FLAG_BARCODE_SCANNER          0x07
-
-// msgType in notifyCallback and dataCallback functions
-enum {
-    CAMERA_MSG_ERROR            = 0x0001,
-    CAMERA_MSG_SHUTTER          = 0x0002,
-    CAMERA_MSG_FOCUS            = 0x0004,
-    CAMERA_MSG_ZOOM             = 0x0008,
-    CAMERA_MSG_PREVIEW_FRAME    = 0x0010,
-    CAMERA_MSG_VIDEO_FRAME      = 0x0020,
-    CAMERA_MSG_POSTVIEW_FRAME   = 0x0040,
-    CAMERA_MSG_RAW_IMAGE        = 0x0080,
-    CAMERA_MSG_COMPRESSED_IMAGE = 0x0100,
-    CAMERA_MSG_RAW_IMAGE_NOTIFY = 0x0200,
-    CAMERA_MSG_ALL_MSGS         = 0xFFFF
-};
-
-// cmdType in sendCommand functions
-enum {
-    CAMERA_CMD_START_SMOOTH_ZOOM     = 1,
-    CAMERA_CMD_STOP_SMOOTH_ZOOM      = 2,
-    // Set the clockwise rotation of preview display (setPreviewDisplay) in
-    // degrees. This affects the preview frames and the picture displayed after
-    // snapshot. This method is useful for portrait mode applications. Note that
-    // preview display of front-facing cameras is flipped horizontally before
-    // the rotation, that is, the image is reflected along the central vertical
-    // axis of the camera sensor. So the users can see themselves as looking
-    // into a mirror.
-    //
-    // This does not affect the order of byte array of CAMERA_MSG_PREVIEW_FRAME,
-    // CAMERA_MSG_VIDEO_FRAME, CAMERA_MSG_POSTVIEW_FRAME, CAMERA_MSG_RAW_IMAGE,
-    // or CAMERA_MSG_COMPRESSED_IMAGE. This is not allowed to be set during
-    // preview.
-    CAMERA_CMD_SET_DISPLAY_ORIENTATION = 3,
-
-    // cmdType to disable/enable shutter sound.
-    // In sendCommand passing arg1 = 0 will disable,
-    // while passing arg1 = 1 will enable the shutter sound.
-    CAMERA_CMD_ENABLE_SHUTTER_SOUND = 4,
-
-    // cmdType to play recording sound.
-    CAMERA_CMD_PLAY_RECORDING_SOUND = 5,
-};
-
-// camera fatal errors
-enum {
-    CAMERA_ERROR_UNKNOWN  = 1,
-    CAMERA_ERROR_SERVER_DIED = 100
-};
-
-enum {
-    CAMERA_FACING_BACK = 0, /* The facing of the camera is opposite to that of the screen. */
-    CAMERA_FACING_FRONT = 1 /* The facing of the camera is the same as that of the screen. */
-};
-
 struct CameraInfo {
-
     /**
-     * The direction that the camera faces to. It should be
-     * CAMERA_FACING_BACK or CAMERA_FACING_FRONT.
+     * The direction that the camera faces to. It should be CAMERA_FACING_BACK
+     * or CAMERA_FACING_FRONT.
      */
     int facing;
 
     /**
      * The orientation of the camera image. The value is the angle that the
-     * camera image needs to be rotated clockwise so it shows correctly on
-     * the display in its natural orientation. It should be 0, 90, 180, or 270.
+     * camera image needs to be rotated clockwise so it shows correctly on the
+     * display in its natural orientation. It should be 0, 90, 180, or 270.
      *
      * For example, suppose a device has a naturally tall screen. The
      * back-facing camera sensor is mounted in landscape. You are looking at
      * the screen. If the top side of the camera sensor is aligned with the
      * right edge of the screen in natural orientation, the value should be
-     * 90. If the top side of a front-facing camera sensor is aligned with
-     * the right of the screen, the value should be 270.
+     * 90. If the top side of a front-facing camera sensor is aligned with the
+     * right of the screen, the value should be 270.
      */
     int orientation;
 };
diff --git a/include/camera/CameraHardwareInterface.h b/include/camera/CameraHardwareInterface.h
deleted file mode 100644
index 3f34120..0000000
--- a/include/camera/CameraHardwareInterface.h
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * Copyright (C) 2008 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_HARDWARE_CAMERA_HARDWARE_INTERFACE_H
-#define ANDROID_HARDWARE_CAMERA_HARDWARE_INTERFACE_H
-
-#include <binder/IMemory.h>
-#include <ui/egl/android_natives.h>
-#include <utils/RefBase.h>
-#include <surfaceflinger/ISurface.h>
-#include <ui/android_native_buffer.h>
-#include <ui/GraphicBuffer.h>
-#include <camera/Camera.h>
-#include <camera/CameraParameters.h>
-
-namespace android {
-
-typedef void (*notify_callback)(int32_t msgType,
-                                int32_t ext1,
-                                int32_t ext2,
-                                void* user);
-
-typedef void (*data_callback)(int32_t msgType,
-                              const sp<IMemory>& dataPtr,
-                              void* user);
-
-typedef void (*data_callback_timestamp)(nsecs_t timestamp,
-                                        int32_t msgType,
-                                        const sp<IMemory>& dataPtr,
-                                        void* user);
-
-/**
- * CameraHardwareInterface.h defines the interface to the
- * camera hardware abstraction layer, used for setting and getting
- * parameters, live previewing, and taking pictures.
- *
- * It is a referenced counted interface with RefBase as its base class.
- * CameraService calls openCameraHardware() to retrieve a strong pointer to the
- * instance of this interface and may be called multiple times. The
- * following steps describe a typical sequence:
- *
- *   -# After CameraService calls openCameraHardware(), getParameters() and
- *      setParameters() are used to initialize the camera instance.
- *      CameraService calls getPreviewHeap() to establish access to the
- *      preview heap so it can be registered with SurfaceFlinger for
- *      efficient display updating while in preview mode.
- *   -# startPreview() is called.  The camera instance then periodically
- *      sends the message CAMERA_MSG_PREVIEW_FRAME (if enabled) each time
- *      a new preview frame is available.  If data callback code needs to use
- *      this memory after returning, it must copy the data.
- *
- * Prior to taking a picture, CameraService calls autofocus(). When auto
- * focusing has completed, the camera instance sends a CAMERA_MSG_FOCUS notification,
- * which informs the application whether focusing was successful. The camera instance
- * only sends this message once and it is up  to the application to call autoFocus()
- * again if refocusing is desired.
- *
- * CameraService calls takePicture() to request the camera instance take a
- * picture. At this point, if a shutter, postview, raw, and/or compressed callback
- * is desired, the corresponding message must be enabled. As with CAMERA_MSG_PREVIEW_FRAME,
- * any memory provided in a data callback must be copied if it's needed after returning.
- */
-class CameraHardwareInterface : public virtual RefBase {
-public:
-    virtual ~CameraHardwareInterface() { }
-
-    /** Set the ANativeWindow to which preview frames are sent */
-    virtual status_t setPreviewWindow(const sp<ANativeWindow>& buf) = 0;
-
-    /** Set the notification and data callbacks */
-    virtual void setCallbacks(notify_callback notify_cb,
-                              data_callback data_cb,
-                              data_callback_timestamp data_cb_timestamp,
-                              void* user) = 0;
-
-    /**
-     * The following three functions all take a msgtype,
-     * which is a bitmask of the messages defined in
-     * include/ui/Camera.h
-     */
-
-    /**
-     * Enable a message, or set of messages.
-     */
-    virtual void        enableMsgType(int32_t msgType) = 0;
-
-    /**
-     * Disable a message, or a set of messages.
-     *
-     * Once received a call to disableMsgType(CAMERA_MSG_VIDEO_FRAME), camera hal
-     * should not rely on its client to call releaseRecordingFrame() to release
-     * video recording frames sent out by the cameral hal before and after the
-     * disableMsgType(CAMERA_MSG_VIDEO_FRAME) call. Camera hal clients must not
-     * modify/access any video recording frame after calling
-     * disableMsgType(CAMERA_MSG_VIDEO_FRAME).
-     */
-    virtual void        disableMsgType(int32_t msgType) = 0;
-
-    /**
-     * Query whether a message, or a set of messages, is enabled.
-     * Note that this is operates as an AND, if any of the messages
-     * queried are off, this will return false.
-     */
-    virtual bool        msgTypeEnabled(int32_t msgType) = 0;
-
-    /**
-     * Start preview mode.
-     */
-    virtual status_t    startPreview() = 0;
-
-    /**
-     * Stop a previously started preview.
-     */
-    virtual void        stopPreview() = 0;
-
-    /**
-     * Returns true if preview is enabled.
-     */
-    virtual bool        previewEnabled() = 0;
-
-    /**
-     * Request the camera hal to store meta data or real YUV data in
-     * the video buffers send out via CAMERA_MSG_VIDEO_FRRAME for a
-     * recording session. If it is not called, the default camera
-     * hal behavior is to store real YUV data in the video buffers.
-     *
-     * This method should be called before startRecording() in order
-     * to be effective.
-     *
-     * If meta data is stored in the video buffers, it is up to the
-     * receiver of the video buffers to interpret the contents and
-     * to find the actual frame data with the help of the meta data
-     * in the buffer. How this is done is outside of the scope of
-     * this method.
-     *
-     * Some camera hal may not support storing meta data in the video
-     * buffers, but all camera hal should support storing real YUV data
-     * in the video buffers. If the camera hal does not support storing
-     * the meta data in the video buffers when it is requested to do
-     * do, INVALID_OPERATION must be returned. It is very useful for
-     * the camera hal to pass meta data rather than the actual frame
-     * data directly to the video encoder, since the amount of the
-     * uncompressed frame data can be very large if video size is large.
-     *
-     * @param enable if true to instruct the camera hal to store
-     *      meta data in the video buffers; false to instruct
-     *      the camera hal to store real YUV data in the video
-     *      buffers.
-     *
-     * @return OK on success.
-     */
-    virtual status_t    storeMetaDataInBuffers(bool enable) {
-                            return enable? INVALID_OPERATION: OK;
-                        }
-
-    /**
-     * Start record mode. When a record image is available a CAMERA_MSG_VIDEO_FRAME
-     * message is sent with the corresponding frame. Every record frame must be released
-     * by a cameral hal client via releaseRecordingFrame() before the client calls
-     * disableMsgType(CAMERA_MSG_VIDEO_FRAME). After the client calls
-     * disableMsgType(CAMERA_MSG_VIDEO_FRAME), it is camera hal's responsibility
-     * to manage the life-cycle of the video recording frames, and the client must
-     * not modify/access any video recording frames.
-     */
-    virtual status_t    startRecording() = 0;
-
-    /**
-     * Stop a previously started recording.
-     */
-    virtual void        stopRecording() = 0;
-
-    /**
-     * Returns true if recording is enabled.
-     */
-    virtual bool        recordingEnabled() = 0;
-
-    /**
-     * Release a record frame previously returned by CAMERA_MSG_VIDEO_FRAME.
-     *
-     * It is camera hal client's responsibility to release video recording
-     * frames sent out by the camera hal before the camera hal receives
-     * a call to disableMsgType(CAMERA_MSG_VIDEO_FRAME). After it receives
-     * the call to disableMsgType(CAMERA_MSG_VIDEO_FRAME), it is camera hal's
-     * responsibility of managing the life-cycle of the video recording
-     * frames.
-     */
-    virtual void        releaseRecordingFrame(const sp<IMemory>& mem) = 0;
-
-    /**
-     * Start auto focus, the notification callback routine is called
-     * with CAMERA_MSG_FOCUS once when focusing is complete. autoFocus()
-     * will be called again if another auto focus is needed.
-     */
-    virtual status_t    autoFocus() = 0;
-
-    /**
-     * Cancels auto-focus function. If the auto-focus is still in progress,
-     * this function will cancel it. Whether the auto-focus is in progress
-     * or not, this function will return the focus position to the default.
-     * If the camera does not support auto-focus, this is a no-op.
-     */
-    virtual status_t    cancelAutoFocus() = 0;
-
-    /**
-     * Take a picture.
-     */
-    virtual status_t    takePicture() = 0;
-
-    /**
-     * Cancel a picture that was started with takePicture.  Calling this
-     * method when no picture is being taken is a no-op.
-     */
-    virtual status_t    cancelPicture() = 0;
-
-    /**
-     * Set the camera parameters. This returns BAD_VALUE if any parameter is
-     * invalid or not supported. */
-    virtual status_t    setParameters(const CameraParameters& params) = 0;
-
-    /** Return the camera parameters. */
-    virtual CameraParameters  getParameters() const = 0;
-
-    /**
-     * Send command to camera driver.
-     */
-    virtual status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) = 0;
-
-    /**
-     * Release the hardware resources owned by this object.  Note that this is
-     * *not* done in the destructor.
-     */
-    virtual void release() = 0;
-
-    /**
-     * Dump state of the camera hardware
-     */
-    virtual status_t dump(int fd, const Vector<String16>& args) const = 0;
-};
-
-/**
- * The functions need to be provided by the camera HAL.
- *
- * If getNumberOfCameras() returns N, the valid cameraId for getCameraInfo()
- * and openCameraHardware() is 0 to N-1.
- */
-extern "C" int HAL_getNumberOfCameras();
-extern "C" void HAL_getCameraInfo(int cameraId, struct CameraInfo* cameraInfo);
-/* HAL should return NULL if it fails to open camera hardware. */
-extern "C" sp<CameraHardwareInterface> HAL_openCameraHardware(int cameraId);
-
-};  // namespace android
-
-#endif
diff --git a/include/gui/SurfaceTextureClient.h b/include/gui/SurfaceTextureClient.h
index fe9b049..c77bc4c 100644
--- a/include/gui/SurfaceTextureClient.h
+++ b/include/gui/SurfaceTextureClient.h
@@ -45,20 +45,20 @@
     SurfaceTextureClient(const SurfaceTextureClient& rhs);
 
     // ANativeWindow hooks
-    static int cancelBuffer(ANativeWindow* window, android_native_buffer_t* buffer);
-    static int dequeueBuffer(ANativeWindow* window, android_native_buffer_t** buffer);
-    static int lockBuffer(ANativeWindow* window, android_native_buffer_t* buffer);
+    static int cancelBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer);
+    static int dequeueBuffer(ANativeWindow* window, ANativeWindowBuffer** buffer);
+    static int lockBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer);
     static int perform(ANativeWindow* window, int operation, ...);
-    static int query(ANativeWindow* window, int what, int* value);
-    static int queueBuffer(ANativeWindow* window, android_native_buffer_t* buffer);
+    static int query(const ANativeWindow* window, int what, int* value);
+    static int queueBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer);
     static int setSwapInterval(ANativeWindow* window, int interval);
 
-    int cancelBuffer(android_native_buffer_t* buffer);
-    int dequeueBuffer(android_native_buffer_t** buffer);
-    int lockBuffer(android_native_buffer_t* buffer);
+    int cancelBuffer(ANativeWindowBuffer* buffer);
+    int dequeueBuffer(ANativeWindowBuffer** buffer);
+    int lockBuffer(ANativeWindowBuffer* buffer);
     int perform(int operation, va_list args);
-    int query(int what, int* value);
-    int queueBuffer(android_native_buffer_t* buffer);
+    int query(int what, int* value) const;
+    int queueBuffer(ANativeWindowBuffer* buffer);
     int setSwapInterval(int interval);
 
     int dispatchConnect(va_list args);
diff --git a/include/media/mediametadataretriever.h b/include/media/mediametadataretriever.h
index 3e343e0..28f305d 100644
--- a/include/media/mediametadataretriever.h
+++ b/include/media/mediametadataretriever.h
@@ -52,6 +52,7 @@
     METADATA_KEY_VIDEO_WIDTH     = 18,
     METADATA_KEY_VIDEO_HEIGHT    = 19,
     METADATA_KEY_BITRATE         = 20,
+    METADATA_KEY_TIMED_TEXT_LANGUAGES      = 21,
 
     // Add more here...
 };
diff --git a/include/media/mediaplayer.h b/include/media/mediaplayer.h
index 241626c..cfa4cfd 100644
--- a/include/media/mediaplayer.h
+++ b/include/media/mediaplayer.h
@@ -125,6 +125,9 @@
     MEDIA_PLAYER_PLAYBACK_COMPLETE  = 1 << 7
 };
 
+enum media_set_parameter_keys {
+    KEY_PARAMETER_TIMED_TEXT_TRACK_INDEX = 1000,
+};
 // ----------------------------------------------------------------------------
 // ref-counted object for callbacks
 class MediaPlayerListener: virtual public RefBase
diff --git a/include/media/stagefright/HardwareAPI.h b/include/media/stagefright/HardwareAPI.h
index d1ecaaf..946a0aa 100644
--- a/include/media/stagefright/HardwareAPI.h
+++ b/include/media/stagefright/HardwareAPI.h
@@ -84,7 +84,7 @@
     OMX_U32 nPortIndex;
     OMX_PTR pAppPrivate;
     OMX_BUFFERHEADERTYPE **bufferHeader;
-    const sp<android_native_buffer_t>& nativeBuffer;
+    const sp<ANativeWindowBuffer>& nativeBuffer;
 };
 
 // A pointer to this struct is passed to OMX_GetParameter when the extension
diff --git a/include/media/stagefright/MediaDefs.h b/include/media/stagefright/MediaDefs.h
index 6a21627..5e471c1 100644
--- a/include/media/stagefright/MediaDefs.h
+++ b/include/media/stagefright/MediaDefs.h
@@ -49,6 +49,8 @@
 
 extern const char *MEDIA_MIMETYPE_CONTAINER_WVM;
 
+extern const char *MEDIA_MIMETYPE_TEXT_3GPP;
+
 }  // namespace android
 
 #endif  // MEDIA_DEFS_H_
diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h
index f7f2235..4044c5d 100644
--- a/include/media/stagefright/MetaData.h
+++ b/include/media/stagefright/MetaData.h
@@ -114,6 +114,9 @@
 
     // An indication that a video buffer has been rendered.
     kKeyRendered          = 'rend',  // bool (int32_t)
+
+    // The language code for this media
+    kKeyMediaLanguage     = 'lang',  // cstring
 };
 
 enum {
diff --git a/include/surfaceflinger/Surface.h b/include/surfaceflinger/Surface.h
index 3923e61..ab30f45 100644
--- a/include/surfaceflinger/Surface.h
+++ b/include/surfaceflinger/Surface.h
@@ -202,18 +202,18 @@
      *  ANativeWindow hooks
      */
     static int setSwapInterval(ANativeWindow* window, int interval);
-    static int dequeueBuffer(ANativeWindow* window, android_native_buffer_t** buffer);
-    static int cancelBuffer(ANativeWindow* window, android_native_buffer_t* buffer);
-    static int lockBuffer(ANativeWindow* window, android_native_buffer_t* buffer);
-    static int queueBuffer(ANativeWindow* window, android_native_buffer_t* buffer);
-    static int query(ANativeWindow* window, int what, int* value);
+    static int dequeueBuffer(ANativeWindow* window, ANativeWindowBuffer** buffer);
+    static int cancelBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer);
+    static int lockBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer);
+    static int queueBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer);
+    static int query(const ANativeWindow* window, int what, int* value);
     static int perform(ANativeWindow* window, int operation, ...);
 
-    int dequeueBuffer(android_native_buffer_t** buffer);
-    int lockBuffer(android_native_buffer_t* buffer);
-    int queueBuffer(android_native_buffer_t* buffer);
-    int cancelBuffer(android_native_buffer_t* buffer);
-    int query(int what, int* value);
+    int dequeueBuffer(ANativeWindowBuffer** buffer);
+    int lockBuffer(ANativeWindowBuffer* buffer);
+    int queueBuffer(ANativeWindowBuffer* buffer);
+    int cancelBuffer(ANativeWindowBuffer* buffer);
+    int query(int what, int* value) const;
     int perform(int operation, va_list args);
 
     void dispatch_setUsage(va_list args);
diff --git a/include/ui/FramebufferNativeWindow.h b/include/ui/FramebufferNativeWindow.h
index 16117ad..302d012 100644
--- a/include/ui/FramebufferNativeWindow.h
+++ b/include/ui/FramebufferNativeWindow.h
@@ -67,10 +67,10 @@
     friend class LightRefBase<FramebufferNativeWindow>;    
     ~FramebufferNativeWindow(); // this class cannot be overloaded
     static int setSwapInterval(ANativeWindow* window, int interval);
-    static int dequeueBuffer(ANativeWindow* window, android_native_buffer_t** buffer);
-    static int lockBuffer(ANativeWindow* window, android_native_buffer_t* buffer);
-    static int queueBuffer(ANativeWindow* window, android_native_buffer_t* buffer);
-    static int query(ANativeWindow* window, int what, int* value);
+    static int dequeueBuffer(ANativeWindow* window, ANativeWindowBuffer** buffer);
+    static int lockBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer);
+    static int queueBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer);
+    static int query(const ANativeWindow* window, int what, int* value);
     static int perform(ANativeWindow* window, int operation, ...);
     
     framebuffer_device_t* fbDev;
diff --git a/include/ui/GraphicBuffer.h b/include/ui/GraphicBuffer.h
index 02d6f8f..370253a 100644
--- a/include/ui/GraphicBuffer.h
+++ b/include/ui/GraphicBuffer.h
@@ -26,7 +26,7 @@
 #include <utils/Flattenable.h>
 #include <pixelflinger/pixelflinger.h>
 
-struct android_native_buffer_t;
+struct ANativeWindowBuffer;
 
 namespace android {
 
@@ -38,7 +38,7 @@
 
 class GraphicBuffer
     : public EGLNativeBase<
-        android_native_buffer_t, 
+        ANativeWindowBuffer,
         GraphicBuffer, 
         LightRefBase<GraphicBuffer> >, public Flattenable
 {
@@ -74,8 +74,8 @@
     GraphicBuffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t usage,
             uint32_t stride, native_handle_t* handle, bool keepOwnership);
 
-    // create a buffer from an existing android_native_buffer_t
-    GraphicBuffer(android_native_buffer_t* buffer, bool keepOwnership);
+    // create a buffer from an existing ANativeWindowBuffer
+    GraphicBuffer(ANativeWindowBuffer* buffer, bool keepOwnership);
 
     // return status
     status_t initCheck() const;
@@ -94,7 +94,7 @@
     status_t lock(GGLSurface* surface, uint32_t usage);
     status_t unlock();
 
-    android_native_buffer_t* getNativeBuffer() const;
+    ANativeWindowBuffer* getNativeBuffer() const;
     
     void setIndex(int index);
     int getIndex() const;
@@ -149,7 +149,7 @@
 
     // If we're wrapping another buffer then this reference will make sure it
     // doesn't get freed.
-    sp<android_native_buffer_t> mWrappedBuffer;
+    sp<ANativeWindowBuffer> mWrappedBuffer;
 };
 
 }; // namespace android
diff --git a/include/ui/android_native_buffer.h b/include/ui/android_native_buffer.h
index 402843e..b6e1db4 100644
--- a/include/ui/android_native_buffer.h
+++ b/include/ui/android_native_buffer.h
@@ -19,53 +19,4 @@
 
 #include <ui/egl/android_natives.h>
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*****************************************************************************/
-
-typedef struct android_native_buffer_t
-{
-#ifdef __cplusplus
-    android_native_buffer_t() { 
-        common.magic = ANDROID_NATIVE_BUFFER_MAGIC;
-        common.version = sizeof(android_native_buffer_t);
-        memset(common.reserved, 0, sizeof(common.reserved));
-    }
-
-    // Implement the methods that sp<android_native_buffer_t> expects so that it
-    // can be used to automatically refcount android_native_buffer_t's.
-    void incStrong(const void* id) const {
-        common.incRef(const_cast<android_native_base_t*>(&common));
-    }
-    void decStrong(const void* id) const {
-        common.decRef(const_cast<android_native_base_t*>(&common));
-    }
-#endif
-
-    struct android_native_base_t common;
-
-    int width;
-    int height;
-    int stride;
-    int format;
-    int usage;
-    
-    void* reserved[2];
-
-    buffer_handle_t handle;
-
-    void* reserved_proc[8];
-} android_native_buffer_t;
-
-
-/*****************************************************************************/
-
-#ifdef __cplusplus
-}
-#endif
-
-/*****************************************************************************/
-
 #endif /* ANDROID_ANDROID_NATIVES_PRIV_H */
diff --git a/include/ui/egl/android_natives.h b/include/ui/egl/android_natives.h
index 0a6e4fb..9ac50a5 100644
--- a/include/ui/egl/android_natives.h
+++ b/include/ui/egl/android_natives.h
@@ -21,400 +21,9 @@
 #include <string.h>
 
 #include <hardware/gralloc.h>
-
+#include <system/window.h>
+// FIXME: remove this header, it's for legacy use.  native_window is pulled from frameworks/base/native/include/android/
 #include <android/native_window.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*****************************************************************************/
-
-#define ANDROID_NATIVE_MAKE_CONSTANT(a,b,c,d) \
-    (((unsigned)(a)<<24)|((unsigned)(b)<<16)|((unsigned)(c)<<8)|(unsigned)(d))
-
-#define ANDROID_NATIVE_WINDOW_MAGIC \
-    ANDROID_NATIVE_MAKE_CONSTANT('_','w','n','d')
-
-#define ANDROID_NATIVE_BUFFER_MAGIC \
-    ANDROID_NATIVE_MAKE_CONSTANT('_','b','f','r')
-
-// ---------------------------------------------------------------------------
-
-struct android_native_buffer_t;
-
-typedef struct android_native_rect_t
-{
-    int32_t left;
-    int32_t top;
-    int32_t right;
-    int32_t bottom;
-} android_native_rect_t;
-
-// ---------------------------------------------------------------------------
-
-typedef struct android_native_base_t
-{
-    /* a magic value defined by the actual EGL native type */
-    int magic;
-
-    /* the sizeof() of the actual EGL native type */
-    int version;
-
-    void* reserved[4];
-
-    /* reference-counting interface */
-    void (*incRef)(struct android_native_base_t* base);
-    void (*decRef)(struct android_native_base_t* base);
-} android_native_base_t;
-
-// ---------------------------------------------------------------------------
-
-/* attributes queriable with query() */
-enum {
-    NATIVE_WINDOW_WIDTH     = 0,
-    NATIVE_WINDOW_HEIGHT,
-    NATIVE_WINDOW_FORMAT,
-
-    /* The minimum number of buffers that must remain un-dequeued after a buffer
-     * has been queued.  This value applies only if set_buffer_count was used to
-     * override the number of buffers and if a buffer has since been queued.
-     * Users of the set_buffer_count ANativeWindow method should query this
-     * value before calling set_buffer_count.  If it is necessary to have N
-     * buffers simultaneously dequeued as part of the steady-state operation,
-     * and this query returns M then N+M buffers should be requested via
-     * native_window_set_buffer_count.
-     *
-     * Note that this value does NOT apply until a single buffer has been
-     * queued.  In particular this means that it is possible to:
-     *
-     * 1. Query M = min undequeued buffers
-     * 2. Set the buffer count to N + M
-     * 3. Dequeue all N + M buffers
-     * 4. Cancel M buffers
-     * 5. Queue, dequeue, queue, dequeue, ad infinitum
-     */
-    NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
-
-    /* Check whether queueBuffer operations on the ANativeWindow send the buffer
-     * to the window compositor.  The query sets the returned 'value' argument
-     * to 1 if the ANativeWindow DOES send queued buffers directly to the window
-     * compositor and 0 if the buffers do not go directly to the window
-     * compositor.
-     *
-     * This can be used to determine whether protected buffer content should be
-     * sent to the ANativeWindow.  Note, however, that a result of 1 does NOT
-     * indicate that queued buffers will be protected from applications or users
-     * capturing their contents.  If that behavior is desired then some other
-     * mechanism (e.g. the GRALLOC_USAGE_PROTECTED flag) should be used in
-     * conjunction with this query.
-     */
-    NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
-
-    /* Get the concrete type of a ANativeWindow.  See below for the list of
-     * possible return values.
-     *
-     * This query should not be used outside the Android framework and will
-     * likely be removed in the near future.
-     */
-    NATIVE_WINDOW_CONCRETE_TYPE,
-};
-
-/* valid operations for the (*perform)() hook */
-enum {
-    NATIVE_WINDOW_SET_USAGE  = 0,
-    NATIVE_WINDOW_CONNECT,
-    NATIVE_WINDOW_DISCONNECT,
-    NATIVE_WINDOW_SET_CROP,
-    NATIVE_WINDOW_SET_BUFFER_COUNT,
-    NATIVE_WINDOW_SET_BUFFERS_GEOMETRY,
-    NATIVE_WINDOW_SET_BUFFERS_TRANSFORM,
-    NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP,
-};
-
-/* parameter for NATIVE_WINDOW_[DIS]CONNECT */
-enum {
-    NATIVE_WINDOW_API_EGL = 1
-};
-
-/* parameter for NATIVE_WINDOW_SET_BUFFERS_TRANSFORM */
-enum {
-    /* flip source image horizontally */
-    NATIVE_WINDOW_TRANSFORM_FLIP_H = HAL_TRANSFORM_FLIP_H ,
-    /* flip source image vertically */
-    NATIVE_WINDOW_TRANSFORM_FLIP_V = HAL_TRANSFORM_FLIP_V,
-    /* rotate source image 90 degrees clock-wise */
-    NATIVE_WINDOW_TRANSFORM_ROT_90 = HAL_TRANSFORM_ROT_90,
-    /* rotate source image 180 degrees */
-    NATIVE_WINDOW_TRANSFORM_ROT_180 = HAL_TRANSFORM_ROT_180,
-    /* rotate source image 270 degrees clock-wise */
-    NATIVE_WINDOW_TRANSFORM_ROT_270 = HAL_TRANSFORM_ROT_270,
-};
-
-/* values returned by the NATIVE_WINDOW_CONCRETE_TYPE query */
-enum {
-    NATIVE_WINDOW_FRAMEBUFFER,                  // FramebufferNativeWindow
-    NATIVE_WINDOW_SURFACE,                      // Surface
-    NATIVE_WINDOW_SURFACE_TEXTURE_CLIENT,       // SurfaceTextureClient
-};
-
-/* parameter for NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP
- *
- * Special timestamp value to indicate that timestamps should be auto-generated
- * by the native window when queueBuffer is called.  This is equal to INT64_MIN,
- * defined directly to avoid problems with C99/C++ inclusion of stdint.h.
- */
-const int64_t NATIVE_WINDOW_TIMESTAMP_AUTO = (-9223372036854775807LL-1);
-
-struct ANativeWindow
-{
-#ifdef __cplusplus
-    ANativeWindow()
-        : flags(0), minSwapInterval(0), maxSwapInterval(0), xdpi(0), ydpi(0)
-    {
-        common.magic = ANDROID_NATIVE_WINDOW_MAGIC;
-        common.version = sizeof(ANativeWindow);
-        memset(common.reserved, 0, sizeof(common.reserved));
-    }
-
-    // Implement the methods that sp<ANativeWindow> expects so that it
-    // can be used to automatically refcount ANativeWindow's.
-    void incStrong(const void* id) const {
-        common.incRef(const_cast<android_native_base_t*>(&common));
-    }
-    void decStrong(const void* id) const {
-        common.decRef(const_cast<android_native_base_t*>(&common));
-    }
-#endif
-    
-    struct android_native_base_t common;
-
-    /* flags describing some attributes of this surface or its updater */
-    const uint32_t flags;
-    
-    /* min swap interval supported by this updated */
-    const int   minSwapInterval;
-
-    /* max swap interval supported by this updated */
-    const int   maxSwapInterval;
-
-    /* horizontal and vertical resolution in DPI */
-    const float xdpi;
-    const float ydpi;
-
-    /* Some storage reserved for the OEM's driver. */
-    intptr_t    oem[4];
-        
-
-    /*
-     * Set the swap interval for this surface.
-     * 
-     * Returns 0 on success or -errno on error.
-     */
-    int     (*setSwapInterval)(struct ANativeWindow* window,
-                int interval);
-    
-    /*
-     * hook called by EGL to acquire a buffer. After this call, the buffer
-     * is not locked, so its content cannot be modified.
-     * this call may block if no buffers are available.
-     * 
-     * Returns 0 on success or -errno on error.
-     */
-    int     (*dequeueBuffer)(struct ANativeWindow* window,
-                struct android_native_buffer_t** buffer);
-
-    /*
-     * hook called by EGL to lock a buffer. This MUST be called before modifying
-     * the content of a buffer. The buffer must have been acquired with 
-     * dequeueBuffer first.
-     * 
-     * Returns 0 on success or -errno on error.
-     */
-    int     (*lockBuffer)(struct ANativeWindow* window,
-                struct android_native_buffer_t* buffer);
-   /*
-    * hook called by EGL when modifications to the render buffer are done. 
-    * This unlocks and post the buffer.
-    * 
-    * Buffers MUST be queued in the same order than they were dequeued.
-    * 
-    * Returns 0 on success or -errno on error.
-    */
-    int     (*queueBuffer)(struct ANativeWindow* window,
-                struct android_native_buffer_t* buffer);
-
-    /*
-     * hook used to retrieve information about the native window.
-     * 
-     * Returns 0 on success or -errno on error.
-     */
-    int     (*query)(struct ANativeWindow* window,
-                int what, int* value);
-    
-    /*
-     * hook used to perform various operations on the surface.
-     * (*perform)() is a generic mechanism to add functionality to
-     * ANativeWindow while keeping backward binary compatibility.
-     * 
-     * This hook should not be called directly, instead use the helper functions
-     * defined below.
-     * 
-     *  (*perform)() returns -ENOENT if the 'what' parameter is not supported
-     *  by the surface's implementation.
-     *
-     * The valid operations are:
-     *     NATIVE_WINDOW_SET_USAGE
-     *     NATIVE_WINDOW_CONNECT
-     *     NATIVE_WINDOW_DISCONNECT
-     *     NATIVE_WINDOW_SET_CROP
-     *     NATIVE_WINDOW_SET_BUFFER_COUNT
-     *     NATIVE_WINDOW_SET_BUFFERS_GEOMETRY
-     *     NATIVE_WINDOW_SET_BUFFERS_TRANSFORM
-     *     NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP
-     *
-     */
-    
-    int     (*perform)(struct ANativeWindow* window,
-                int operation, ... );
-    
-    /*
-     * hook used to cancel a buffer that has been dequeued.
-     * No synchronization is performed between dequeue() and cancel(), so
-     * either external synchronization is needed, or these functions must be
-     * called from the same thread.
-     */
-    int     (*cancelBuffer)(struct ANativeWindow* window,
-                struct android_native_buffer_t* buffer);
-
-
-    void* reserved_proc[2];
-};
-
-// Backwards compatibility...  please switch to ANativeWindow.
-typedef struct ANativeWindow android_native_window_t;
-
-/*
- *  native_window_set_usage(..., usage)
- *  Sets the intended usage flags for the next buffers
- *  acquired with (*lockBuffer)() and on.
- *  By default (if this function is never called), a usage of
- *      GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE
- *  is assumed.
- *  Calling this function will usually cause following buffers to be
- *  reallocated.
- */
-
-static inline int native_window_set_usage(
-        ANativeWindow* window, int usage)
-{
-    return window->perform(window, NATIVE_WINDOW_SET_USAGE, usage);
-}
-
-/*
- * native_window_connect(..., NATIVE_WINDOW_API_EGL)
- * Must be called by EGL when the window is made current.
- * Returns -EINVAL if for some reason the window cannot be connected, which
- * can happen if it's connected to some other API.
- */
-static inline int native_window_connect(
-        ANativeWindow* window, int api)
-{
-    return window->perform(window, NATIVE_WINDOW_CONNECT, api);
-}
-
-/*
- * native_window_disconnect(..., NATIVE_WINDOW_API_EGL)
- * Must be called by EGL when the window is made not current.
- * An error is returned if for instance the window wasn't connected in the
- * first place.
- */
-static inline int native_window_disconnect(
-        ANativeWindow* window, int api)
-{
-    return window->perform(window, NATIVE_WINDOW_DISCONNECT, api);
-}
-
-/*
- * native_window_set_crop(..., crop)
- * Sets which region of the next queued buffers needs to be considered.
- * A buffer's crop region is scaled to match the surface's size.
- *
- * The specified crop region applies to all buffers queued after it is called.
- *
- * if 'crop' is NULL, subsequently queued buffers won't be cropped.
- *
- * An error is returned if for instance the crop region is invalid,
- * out of the buffer's bound or if the window is invalid.
- */
-static inline int native_window_set_crop(
-        ANativeWindow* window,
-        android_native_rect_t const * crop)
-{
-    return window->perform(window, NATIVE_WINDOW_SET_CROP, crop);
-}
-
-/*
- * native_window_set_buffer_count(..., count)
- * Sets the number of buffers associated with this native window.
- */
-static inline int native_window_set_buffer_count(
-        ANativeWindow* window,
-        size_t bufferCount)
-{
-    return window->perform(window, NATIVE_WINDOW_SET_BUFFER_COUNT, bufferCount);
-}
-
-/*
- * native_window_set_buffers_geometry(..., int w, int h, int format)
- * All buffers dequeued after this call will have the geometry specified.
- * In particular, all buffers will have a fixed-size, independent form the
- * native-window size. They will be appropriately scaled to the window-size
- * upon composition.
- *
- * If all parameters are 0, the normal behavior is restored. That is,
- * dequeued buffers following this call will be sized to the window's size.
- *
- * Calling this function will reset the window crop to a NULL value, which
- * disables cropping of the buffers.
- */
-static inline int native_window_set_buffers_geometry(
-        ANativeWindow* window,
-        int w, int h, int format)
-{
-    return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_GEOMETRY,
-            w, h, format);
-}
-
-/*
- * native_window_set_buffers_transform(..., int transform)
- * All buffers queued after this call will be displayed transformed according
- * to the transform parameter specified.
- */
-static inline int native_window_set_buffers_transform(
-        ANativeWindow* window,
-        int transform)
-{
-    return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_TRANSFORM,
-            transform);
-}
-
-/*
- * native_window_set_buffers_timestamp(..., int64_t timestamp)
- * All buffers queued after this call will be associated with the timestamp
- * parameter specified. If the timestamp is set to NATIVE_WINDOW_TIMESTAMP_AUTO
- * (the default), timestamps will be generated automatically when queueBuffer is
- * called. The timestamp is measured in nanoseconds, and must be monotonically
- * increasing.
- */
-static inline int native_window_set_buffers_timestamp(
-        ANativeWindow* window,
-        int64_t timestamp)
-{
-    return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP,
-            timestamp);
-}
-
 // ---------------------------------------------------------------------------
 
 /* FIXME: this is legacy for pixmaps */
@@ -437,13 +46,6 @@
 /*****************************************************************************/
 
 #ifdef __cplusplus
-}
-#endif
-
-
-/*****************************************************************************/
-
-#ifdef __cplusplus
 
 #include <utils/RefBase.h>
 
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 44d9b4b..0c5767b 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -513,32 +513,32 @@
 }
 
 int Surface::dequeueBuffer(ANativeWindow* window, 
-        android_native_buffer_t** buffer) {
+        ANativeWindowBuffer** buffer) {
     Surface* self = getSelf(window);
     return self->dequeueBuffer(buffer);
 }
 
 int Surface::cancelBuffer(ANativeWindow* window,
-        android_native_buffer_t* buffer) {
+        ANativeWindowBuffer* buffer) {
     Surface* self = getSelf(window);
     return self->cancelBuffer(buffer);
 }
 
 int Surface::lockBuffer(ANativeWindow* window, 
-        android_native_buffer_t* buffer) {
+        ANativeWindowBuffer* buffer) {
     Surface* self = getSelf(window);
     return self->lockBuffer(buffer);
 }
 
 int Surface::queueBuffer(ANativeWindow* window, 
-        android_native_buffer_t* buffer) {
+        ANativeWindowBuffer* buffer) {
     Surface* self = getSelf(window);
     return self->queueBuffer(buffer);
 }
 
-int Surface::query(ANativeWindow* window, 
+int Surface::query(const ANativeWindow* window,
         int what, int* value) {
-    Surface* self = getSelf(window);
+    const Surface* self = getSelf(window);
     return self->query(what, value);
 }
 
@@ -570,7 +570,7 @@
     return newNeewBuffer;
 }
 
-int Surface::dequeueBuffer(android_native_buffer_t** buffer)
+int Surface::dequeueBuffer(ANativeWindowBuffer** buffer)
 {
     status_t err = validate();
     if (err != NO_ERROR)
@@ -624,7 +624,7 @@
     return err;
 }
 
-int Surface::cancelBuffer(android_native_buffer_t* buffer)
+int Surface::cancelBuffer(ANativeWindowBuffer* buffer)
 {
     status_t err = validate(true);
     switch (err) {
@@ -651,7 +651,7 @@
 }
 
 
-int Surface::lockBuffer(android_native_buffer_t* buffer)
+int Surface::lockBuffer(ANativeWindowBuffer* buffer)
 {
     status_t err = validate();
     if (err != NO_ERROR)
@@ -670,7 +670,7 @@
     return err;
 }
 
-int Surface::queueBuffer(android_native_buffer_t* buffer)
+int Surface::queueBuffer(ANativeWindowBuffer* buffer)
 {
     status_t err = validate();
     if (err != NO_ERROR)
@@ -697,7 +697,7 @@
     return err;
 }
 
-int Surface::query(int what, int* value)
+int Surface::query(int what, int* value) const
 {
     switch (what) {
     case NATIVE_WINDOW_WIDTH:
@@ -969,7 +969,7 @@
     // we're intending to do software rendering from this point
     setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
 
-    android_native_buffer_t* out;
+    ANativeWindowBuffer* out;
     status_t err = dequeueBuffer(&out);
     LOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err));
     if (err == NO_ERROR) {
@@ -1063,7 +1063,7 @@
     if (idx < 0) {
         // The buffer doesn't have an index set.  See if the handle the same as
         // one of the buffers for which we do know the index.  This can happen
-        // e.g. if GraphicBuffer is used to wrap an android_native_buffer_t that
+        // e.g. if GraphicBuffer is used to wrap an ANativeWindowBuffer that
         // was dequeued from an ANativeWindow.
         for (size_t i = 0; i < mBuffers.size(); i++) {
             if (mBuffers[i] != 0 && buffer->handle == mBuffers[i]->handle) {
diff --git a/libs/gui/SurfaceTextureClient.cpp b/libs/gui/SurfaceTextureClient.cpp
index f4b2416..ec6da43 100644
--- a/libs/gui/SurfaceTextureClient.cpp
+++ b/libs/gui/SurfaceTextureClient.cpp
@@ -53,31 +53,32 @@
 }
 
 int SurfaceTextureClient::dequeueBuffer(ANativeWindow* window,
-        android_native_buffer_t** buffer) {
+        ANativeWindowBuffer** buffer) {
     SurfaceTextureClient* c = getSelf(window);
     return c->dequeueBuffer(buffer);
 }
 
 int SurfaceTextureClient::cancelBuffer(ANativeWindow* window,
-        android_native_buffer_t* buffer) {
+        ANativeWindowBuffer* buffer) {
     SurfaceTextureClient* c = getSelf(window);
     return c->cancelBuffer(buffer);
 }
 
 int SurfaceTextureClient::lockBuffer(ANativeWindow* window,
-        android_native_buffer_t* buffer) {
+        ANativeWindowBuffer* buffer) {
     SurfaceTextureClient* c = getSelf(window);
     return c->lockBuffer(buffer);
 }
 
 int SurfaceTextureClient::queueBuffer(ANativeWindow* window,
-        android_native_buffer_t* buffer) {
+        ANativeWindowBuffer* buffer) {
     SurfaceTextureClient* c = getSelf(window);
     return c->queueBuffer(buffer);
 }
 
-int SurfaceTextureClient::query(ANativeWindow* window, int what, int* value) {
-    SurfaceTextureClient* c = getSelf(window);
+int SurfaceTextureClient::query(const ANativeWindow* window,
+                                int what, int* value) {
+    const SurfaceTextureClient* c = getSelf(window);
     return c->query(what, value);
 }
 
@@ -160,7 +161,7 @@
     return BAD_VALUE;
 }
 
-int SurfaceTextureClient::query(int what, int* value) {
+int SurfaceTextureClient::query(int what, int* value) const {
     LOGV("SurfaceTextureClient::query");
     Mutex::Autolock lock(mMutex);
     switch (what) {
diff --git a/libs/gui/tests/SurfaceTextureClient_test.cpp b/libs/gui/tests/SurfaceTextureClient_test.cpp
index db781de..753e933 100644
--- a/libs/gui/tests/SurfaceTextureClient_test.cpp
+++ b/libs/gui/tests/SurfaceTextureClient_test.cpp
@@ -113,7 +113,7 @@
 
 TEST_F(SurfaceTextureClientTest, DefaultGeometryValues) {
     sp<ANativeWindow> anw(mSTC);
-    android_native_buffer_t* buf;
+    ANativeWindowBuffer* buf;
     ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf));
     EXPECT_EQ(1, buf->width);
     EXPECT_EQ(1, buf->height);
@@ -123,7 +123,7 @@
 
 TEST_F(SurfaceTextureClientTest, BufferGeometryCanBeSet) {
     sp<ANativeWindow> anw(mSTC);
-    android_native_buffer_t* buf;
+    ANativeWindowBuffer* buf;
     EXPECT_EQ(OK, native_window_set_buffers_geometry(anw.get(), 16, 8, PIXEL_FORMAT_RGB_565));
     ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf));
     EXPECT_EQ(16, buf->width);
@@ -134,7 +134,7 @@
 
 TEST_F(SurfaceTextureClientTest, BufferGeometryDefaultSizeSetFormat) {
     sp<ANativeWindow> anw(mSTC);
-    android_native_buffer_t* buf;
+    ANativeWindowBuffer* buf;
     EXPECT_EQ(OK, native_window_set_buffers_geometry(anw.get(), 0, 0, PIXEL_FORMAT_RGB_565));
     ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf));
     EXPECT_EQ(1, buf->width);
@@ -145,7 +145,7 @@
 
 TEST_F(SurfaceTextureClientTest, BufferGeometrySetSizeDefaultFormat) {
     sp<ANativeWindow> anw(mSTC);
-    android_native_buffer_t* buf;
+    ANativeWindowBuffer* buf;
     EXPECT_EQ(OK, native_window_set_buffers_geometry(anw.get(), 16, 8, 0));
     ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf));
     EXPECT_EQ(16, buf->width);
@@ -156,7 +156,7 @@
 
 TEST_F(SurfaceTextureClientTest, BufferGeometrySizeCanBeUnset) {
     sp<ANativeWindow> anw(mSTC);
-    android_native_buffer_t* buf;
+    ANativeWindowBuffer* buf;
     EXPECT_EQ(OK, native_window_set_buffers_geometry(anw.get(), 16, 8, 0));
     ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf));
     EXPECT_EQ(16, buf->width);
@@ -173,7 +173,7 @@
 
 TEST_F(SurfaceTextureClientTest, BufferGeometrySizeCanBeChangedWithoutFormat) {
     sp<ANativeWindow> anw(mSTC);
-    android_native_buffer_t* buf;
+    ANativeWindowBuffer* buf;
     EXPECT_EQ(OK, native_window_set_buffers_geometry(anw.get(), 0, 0, PIXEL_FORMAT_RGB_565));
     ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf));
     EXPECT_EQ(1, buf->width);
@@ -191,7 +191,7 @@
 TEST_F(SurfaceTextureClientTest, SurfaceTextureSetDefaultSize) {
     sp<ANativeWindow> anw(mSTC);
     sp<SurfaceTexture> st(mST);
-    android_native_buffer_t* buf;
+    ANativeWindowBuffer* buf;
     EXPECT_EQ(OK, st->setDefaultBufferSize(16, 8));
     ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf));
     EXPECT_EQ(16, buf->width);
@@ -203,7 +203,7 @@
 TEST_F(SurfaceTextureClientTest, SurfaceTextureSetDefaultSizeAfterDequeue) {
     sp<ANativeWindow> anw(mSTC);
     sp<SurfaceTexture> st(mST);
-    android_native_buffer_t* buf[2];
+    ANativeWindowBuffer* buf[2];
     ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
     ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[1]));
     EXPECT_NE(buf[0], buf[1]);
@@ -224,7 +224,7 @@
 TEST_F(SurfaceTextureClientTest, SurfaceTextureSetDefaultSizeVsGeometry) {
     sp<ANativeWindow> anw(mSTC);
     sp<SurfaceTexture> st(mST);
-    android_native_buffer_t* buf[2];
+    ANativeWindowBuffer* buf[2];
     EXPECT_EQ(OK, st->setDefaultBufferSize(16, 8));
     ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[0]));
     ASSERT_EQ(OK, anw->dequeueBuffer(anw.get(), &buf[1]));
diff --git a/libs/gui/tests/SurfaceTexture_test.cpp b/libs/gui/tests/SurfaceTexture_test.cpp
index 6c71343..8747ba5 100644
--- a/libs/gui/tests/SurfaceTexture_test.cpp
+++ b/libs/gui/tests/SurfaceTexture_test.cpp
@@ -476,7 +476,7 @@
     ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
             GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
 
-    android_native_buffer_t* anb;
+    ANativeWindowBuffer* anb;
     ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
     ASSERT_TRUE(anb != NULL);
 
@@ -524,7 +524,7 @@
     ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
             GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
 
-    android_native_buffer_t* anb;
+    ANativeWindowBuffer* anb;
     ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
     ASSERT_TRUE(anb != NULL);
 
@@ -583,7 +583,7 @@
 
         ASSERT_EQ(NO_ERROR, native_window_set_crop(mANW.get(), &crop));
 
-        android_native_buffer_t* anb;
+        ANativeWindowBuffer* anb;
         ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
         ASSERT_TRUE(anb != NULL);
 
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 440a48b..35c8640 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -93,7 +93,7 @@
     ASSERT_EQ(NO_ERROR, native_window_set_usage(anw.get(),
             GRALLOC_USAGE_PROTECTED));
     ASSERT_EQ(NO_ERROR, native_window_set_buffer_count(anw.get(), 3));
-    android_native_buffer_t* buf = 0;
+    ANativeWindowBuffer* buf = 0;
     for (int i = 0; i < 4; i++) {
         // Loop to make sure SurfaceFlinger has retired a protected buffer.
         ASSERT_EQ(NO_ERROR, anw->dequeueBuffer(anw.get(), &buf));
diff --git a/libs/rs/rsg_generator.c b/libs/rs/rsg_generator.c
index 0e914fc..1d8b9b5 100644
--- a/libs/rs/rsg_generator.c
+++ b/libs/rs/rsg_generator.c
@@ -157,8 +157,7 @@
 static int hasInlineDataPointers(const ApiEntry * api) {
     int ret = 0;
     int ct;
-    // Temporarly disable inbanding while we sort though the bugs.
-    if (1|| api->sync || api->ret.typeName[0]) {
+    if (api->sync || api->ret.typeName[0]) {
         return 0;
     }
     for (ct=0; ct < api->paramCount; ct++) {
@@ -229,7 +228,7 @@
             fprintf(f, ");\n");
         } else {
             fprintf(f, "    ThreadIO *io = &((Context *)rsc)->mIO;\n");
-            fprintf(f, "    uint32_t size = sizeof(RS_CMD_%s);\n", api->name);
+            fprintf(f, "    const uint32_t size = sizeof(RS_CMD_%s);\n", api->name);
             if (hasInlineDataPointers(api)) {
                 fprintf(f, "    uint32_t dataSize = 0;\n");
                 for (ct2=0; ct2 < api->paramCount; ct2++) {
@@ -242,10 +241,15 @@
 
             //fprintf(f, "    LOGE(\"add command %s\\n\");\n", api->name);
             if (hasInlineDataPointers(api)) {
-                fprintf(f, "    RS_CMD_%s *cmd = static_cast<RS_CMD_%s *>(io->mToCore.reserve(dataSize + sizeof(RS_CMD_%s)));\n", api->name, api->name, api->name);
+                fprintf(f, "    RS_CMD_%s *cmd = NULL;\n", api->name);
+                fprintf(f, "    if (dataSize < 1024) {;\n");
+                fprintf(f, "        cmd = static_cast<RS_CMD_%s *>(io->mToCore.reserve(dataSize + size));\n", api->name);
+                fprintf(f, "    } else {\n");
+                fprintf(f, "        cmd = static_cast<RS_CMD_%s *>(io->mToCore.reserve(size));\n", api->name);
+                fprintf(f, "    }\n");
                 fprintf(f, "    uint8_t *payload = (uint8_t *)&cmd[1];\n");
             } else {
-                fprintf(f, "    RS_CMD_%s *cmd = static_cast<RS_CMD_%s *>(io->mToCore.reserve(sizeof(RS_CMD_%s)));\n", api->name, api->name, api->name);
+                fprintf(f, "    RS_CMD_%s *cmd = static_cast<RS_CMD_%s *>(io->mToCore.reserve(size));\n", api->name, api->name);
             }
 
             for (ct2=0; ct2 < api->paramCount; ct2++) {
diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp
index dc223f9..4393504 100644
--- a/libs/ui/FramebufferNativeWindow.cpp
+++ b/libs/ui/FramebufferNativeWindow.cpp
@@ -47,16 +47,16 @@
 
 class NativeBuffer 
     : public EGLNativeBase<
-        android_native_buffer_t, 
+        ANativeWindowBuffer, 
         NativeBuffer, 
         LightRefBase<NativeBuffer> >
 {
 public:
     NativeBuffer(int w, int h, int f, int u) : BASE() {
-        android_native_buffer_t::width  = w;
-        android_native_buffer_t::height = h;
-        android_native_buffer_t::format = f;
-        android_native_buffer_t::usage  = u;
+        ANativeWindowBuffer::width  = w;
+        ANativeWindowBuffer::height = h;
+        ANativeWindowBuffer::format = f;
+        ANativeWindowBuffer::usage  = u;
     }
 private:
     friend class LightRefBase<NativeBuffer>;    
@@ -201,7 +201,7 @@
 }
 
 int FramebufferNativeWindow::dequeueBuffer(ANativeWindow* window, 
-        android_native_buffer_t** buffer)
+        ANativeWindowBuffer** buffer)
 {
     FramebufferNativeWindow* self = getSelf(window);
     Mutex::Autolock _l(self->mutex);
@@ -229,7 +229,7 @@
 }
 
 int FramebufferNativeWindow::lockBuffer(ANativeWindow* window, 
-        android_native_buffer_t* buffer)
+        ANativeWindowBuffer* buffer)
 {
     FramebufferNativeWindow* self = getSelf(window);
     Mutex::Autolock _l(self->mutex);
@@ -249,7 +249,7 @@
 }
 
 int FramebufferNativeWindow::queueBuffer(ANativeWindow* window, 
-        android_native_buffer_t* buffer)
+        ANativeWindowBuffer* buffer)
 {
     FramebufferNativeWindow* self = getSelf(window);
     Mutex::Autolock _l(self->mutex);
@@ -270,10 +270,10 @@
     return res;
 }
 
-int FramebufferNativeWindow::query(ANativeWindow* window,
+int FramebufferNativeWindow::query(const ANativeWindow* window,
         int what, int* value) 
 {
-    FramebufferNativeWindow* self = getSelf(window);
+    const FramebufferNativeWindow* self = getSelf(window);
     Mutex::Autolock _l(self->mutex);
     framebuffer_device_t* fb = self->fbDev;
     switch (what) {
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index 97312a6..54a3ffa 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -33,7 +33,7 @@
 namespace android {
 
 // ===========================================================================
-// Buffer and implementation of android_native_buffer_t
+// Buffer and implementation of ANativeWindowBuffer
 // ===========================================================================
 
 GraphicBuffer::GraphicBuffer()
@@ -77,7 +77,7 @@
     handle = inHandle;
 }
 
-GraphicBuffer::GraphicBuffer(android_native_buffer_t* buffer, bool keepOwnership)
+GraphicBuffer::GraphicBuffer(ANativeWindowBuffer* buffer, bool keepOwnership)
     : BASE(), mOwner(keepOwnership ? ownHandle : ownNone),
       mBufferMapper(GraphicBufferMapper::get()),
       mInitCheck(NO_ERROR), mIndex(-1), mWrappedBuffer(buffer)
@@ -119,9 +119,9 @@
     GraphicBufferAllocator::dumpToSystemLog();
 }
 
-android_native_buffer_t* GraphicBuffer::getNativeBuffer() const
+ANativeWindowBuffer* GraphicBuffer::getNativeBuffer() const
 {
-    return static_cast<android_native_buffer_t*>(
+    return static_cast<ANativeWindowBuffer*>(
             const_cast<GraphicBuffer*>(this));
 }
 
diff --git a/media/java/android/media/MediaMetadataRetriever.java b/media/java/android/media/MediaMetadataRetriever.java
index 60085b5..5f7f36f 100644
--- a/media/java/android/media/MediaMetadataRetriever.java
+++ b/media/java/android/media/MediaMetadataRetriever.java
@@ -432,5 +432,12 @@
      * This key retrieves the average bitrate (in bits/sec), if available.
      */
     public static final int METADATA_KEY_BITRATE         = 20;
+    /**
+     * This key retrieves the language code of text tracks, if available.
+     * If multiple text tracks present, the return value will look like:
+     * "eng:chi"
+     * @hide
+     */
+    public static final int METADATA_KEY_TIMED_TEXT_LANGUAGES      = 21;
     // Add more here...
 }
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index b914169..3f799cf 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -1227,6 +1227,15 @@
      */
     public native void attachAuxEffect(int effectId);
 
+    /* Do not change these values without updating their counterparts
+     * in include/media/mediaplayer.h!
+     */
+    /**
+     * Key used in setParameter method.
+     * Indicates the index of the timed text track to be enabled/disabled
+     */
+    private static final int KEY_PARAMETER_TIMED_TEXT_TRACK_INDEX = 1000;
+
     /**
      * Sets the parameter indicated by key.
      * @param key key indicates the parameter to be set.
@@ -1360,6 +1369,36 @@
     private native final void native_finalize();
 
     /**
+     * @param index The index of the text track to be turned on.
+     * @return true if the text track is enabled successfully.
+     * {@hide}
+     */
+    public boolean enableTimedTextTrackIndex(int index) {
+        if (index < 0) {
+            return false;
+        }
+        return setParameter(KEY_PARAMETER_TIMED_TEXT_TRACK_INDEX, index);
+    }
+
+    /**
+     * Enables the first timed text track if any.
+     * @return true if the text track is enabled successfully
+     * {@hide}
+     */
+    public boolean enableTimedText() {
+        return enableTimedTextTrackIndex(0);
+    }
+
+    /**
+     * Disables timed text display.
+     * @return true if the text track is disabled successfully.
+     * {@hide}
+     */
+    public boolean disableTimedText() {
+        return setParameter(KEY_PARAMETER_TIMED_TEXT_TRACK_INDEX, -1);
+    }
+
+    /**
      * @param reply Parcel with audio/video duration info for battery
                     tracking usage
      * @return The status code.
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 9928f44..e52f6d1 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -505,7 +505,7 @@
 
     // Dequeue buffers and send them to OMX
     for (OMX_U32 i = 0; i < def.nBufferCountActual; i++) {
-        android_native_buffer_t *buf;
+        ANativeWindowBuffer *buf;
         err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf);
         if (err != 0) {
             LOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
@@ -574,7 +574,7 @@
 }
 
 ACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
-    android_native_buffer_t *buf;
+    ANativeWindowBuffer *buf;
     CHECK_EQ(mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf), 0);
 
     for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 2f3e1410..6c7176c 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -48,6 +48,7 @@
         ThrottledSource.cpp               \
         TimeSource.cpp                    \
         TimedEventQueue.cpp               \
+        TimedTextPlayer.cpp               \
         Utils.cpp                         \
         VBRISeeker.cpp                    \
         WAVExtractor.cpp                  \
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 974efa7..cccd0b7 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -28,6 +28,7 @@
 #include "include/NuCachedSource2.h"
 #include "include/ThrottledSource.h"
 #include "include/MPEG2TSExtractor.h"
+#include "include/TimedTextPlayer.h"
 
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
@@ -185,7 +186,8 @@
       mExtractorFlags(0),
       mVideoBuffer(NULL),
       mDecryptHandle(NULL),
-      mLastVideoTimeUs(-1) {
+      mLastVideoTimeUs(-1),
+      mTextPlayer(NULL) {
     CHECK_EQ(mClient.connect(), (status_t)OK);
 
     DataSource::RegisterDefaultSniffers();
@@ -381,10 +383,8 @@
                     mFlags |= AUTO_LOOPING;
                 }
             }
-        }
-
-        if (haveAudio && haveVideo) {
-            break;
+        } else if (!strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP)) {
+            addTextSource(extractor->getTrack(i));
         }
     }
 
@@ -469,6 +469,11 @@
     delete mAudioPlayer;
     mAudioPlayer = NULL;
 
+    if (mTextPlayer != NULL) {
+        delete mTextPlayer;
+        mTextPlayer = NULL;
+    }
+
     mVideoRenderer.clear();
 
     if (mRTSPController != NULL) {
@@ -971,6 +976,11 @@
         mFlags &= ~AUDIO_RUNNING;
     }
 
+    if (mFlags & TEXTPLAYER_STARTED) {
+        mTextPlayer->pause();
+        mFlags &= ~TEXT_RUNNING;
+    }
+
     mFlags &= ~PLAYING;
 
     if (mDecryptHandle != NULL) {
@@ -1119,6 +1129,32 @@
     return OK;
 }
 
+status_t AwesomePlayer::setTimedTextTrackIndex(int32_t index) {
+    if (mTextPlayer != NULL) {
+        if (index >= 0) { // to turn on a text track
+            status_t err = mTextPlayer->setTimedTextTrackIndex(index);
+            if (err != OK) {
+                return err;
+            }
+
+            mFlags |= TEXT_RUNNING;
+            mFlags |= TEXTPLAYER_STARTED;
+            return OK;
+        } else { // to turn off the text track display
+            if (mFlags  & TEXT_RUNNING) {
+                mFlags &= ~TEXT_RUNNING;
+            }
+            if (mFlags  & TEXTPLAYER_STARTED) {
+                mFlags &= ~TEXTPLAYER_STARTED;
+            }
+
+            return mTextPlayer->setTimedTextTrackIndex(index);
+        }
+    } else {
+        return INVALID_OPERATION;
+    }
+}
+
 // static
 void AwesomePlayer::OnRTSPSeekDoneWrapper(void *cookie) {
     static_cast<AwesomePlayer *>(cookie)->onRTSPSeekDone();
@@ -1155,6 +1191,10 @@
 
     seekAudioIfNecessary_l();
 
+    if (mFlags & TEXTPLAYER_STARTED) {
+        mTextPlayer->seekTo(mSeekTimeUs);
+    }
+
     if (!(mFlags & PLAYING)) {
         LOGV("seeking while paused, sending SEEK_COMPLETE notification"
              " immediately.");
@@ -1193,6 +1233,16 @@
     mAudioTrack = source;
 }
 
+void AwesomePlayer::addTextSource(sp<MediaSource> source) {
+    CHECK(source != NULL);
+
+    if (mTextPlayer == NULL) {
+        mTextPlayer = new TimedTextPlayer(this, mListener, &mQueue);
+    }
+
+    mTextPlayer->addTextSource(source);
+}
+
 status_t AwesomePlayer::initAudioDecoder() {
     sp<MetaData> meta = mAudioTrack->getFormat();
 
@@ -1472,6 +1522,11 @@
         }
     }
 
+    if ((mFlags & TEXTPLAYER_STARTED) && !(mFlags & (TEXT_RUNNING | SEEK_PREVIEW))) {
+        mTextPlayer->resume();
+        mFlags |= TEXT_RUNNING;
+    }
+
     TimeSource *ts = (mFlags & AUDIO_AT_EOS) ? &mSystemTimeSource : mTimeSource;
 
     if (mFlags & FIRST_FRAME) {
@@ -1906,7 +1961,10 @@
 }
 
 status_t AwesomePlayer::setParameter(int key, const Parcel &request) {
-    return OK;
+    if (key == KEY_PARAMETER_TIMED_TEXT_TRACK_INDEX) {
+        return setTimedTextTrackIndex(request.readInt32());
+    }
+    return ERROR_UNSUPPORTED;
 }
 
 status_t AwesomePlayer::getParameter(int key, Parcel *reply) {
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 8787214..c79d02e 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -19,6 +19,8 @@
 
 #include "include/MPEG4Extractor.h"
 #include "include/SampleTable.h"
+#include "include/ESDS.h"
+#include "include/TimedTextPlayer.h"
 
 #include <arpa/inet.h>
 
@@ -29,7 +31,6 @@
 
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/DataSource.h>
-#include "include/ESDS.h"
 #include <media/stagefright/MediaBuffer.h>
 #include <media/stagefright/MediaBufferGroup.h>
 #include <media/stagefright/MediaDefs.h>
@@ -832,6 +833,33 @@
             mLastTrack->meta->setInt64(
                     kKeyDuration, (duration * 1000000) / mLastTrack->timescale);
 
+            uint8_t lang[2];
+            off64_t lang_offset;
+            if (version == 1) {
+                lang_offset = timescale_offset + 4 + 8;
+            } else if (version == 0) {
+                lang_offset = timescale_offset + 4 + 4;
+            } else {
+                return ERROR_IO;
+            }
+
+            if (mDataSource->readAt(lang_offset, &lang, sizeof(lang))
+                    < (ssize_t)sizeof(lang)) {
+                return ERROR_IO;
+            }
+
+            // To get the ISO-639-2/T three character language code
+            // 1 bit pad followed by 3 5-bits characters. Each character
+            // is packed as the difference between its ASCII value and 0x60.
+            char lang_code[4];
+            lang_code[0] = ((lang[0] >> 2) & 0x1f) + 0x60;
+            lang_code[1] = ((lang[0] & 0x3) << 3 | (lang[1] >> 5)) + 0x60;
+            lang_code[2] = (lang[1] & 0x1f) + 0x60;
+            lang_code[3] = '\0';
+
+            mLastTrack->meta->setCString(
+                    kKeyMediaLanguage, lang_code);
+
             *offset += chunk_size;
             break;
         }
@@ -1295,6 +1323,14 @@
             return parseDrmSINF(offset, data_offset);
         }
 
+        case FOURCC('t', 'x', '3', 'g'):
+        {
+            mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_TEXT_3GPP);
+
+            *offset += chunk_size;
+            break;
+        }
+
         default:
         {
             *offset += chunk_size;
diff --git a/media/libstagefright/MediaDefs.cpp b/media/libstagefright/MediaDefs.cpp
index 8ca6ee8..8cd08bc 100644
--- a/media/libstagefright/MediaDefs.cpp
+++ b/media/libstagefright/MediaDefs.cpp
@@ -47,4 +47,6 @@
 
 const char *MEDIA_MIMETYPE_CONTAINER_WVM = "video/wvm";
 
+const char *MEDIA_MIMETYPE_TEXT_3GPP = "text/3gpp-tt";
+
 }  // namespace android
diff --git a/media/libstagefright/NuCachedSource2.cpp b/media/libstagefright/NuCachedSource2.cpp
index dc86885..81f2e47 100644
--- a/media/libstagefright/NuCachedSource2.cpp
+++ b/media/libstagefright/NuCachedSource2.cpp
@@ -450,6 +450,11 @@
         }
 
         size_t avail = mCache->totalSize() - delta;
+
+        if (avail > size) {
+            avail = size;
+        }
+
         mCache->copy(delta, data, avail);
 
         return avail;
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 06352f4..78d13b2 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -1830,7 +1830,7 @@
 
     // Dequeue buffers and send them to OMX
     for (OMX_U32 i = 0; i < def.nBufferCountActual; i++) {
-        android_native_buffer_t* buf;
+        ANativeWindowBuffer* buf;
         err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf);
         if (err != 0) {
             LOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
@@ -1900,7 +1900,7 @@
 
 OMXCodec::BufferInfo* OMXCodec::dequeueBufferFromNativeWindow() {
     // Dequeue the next buffer from the native window.
-    android_native_buffer_t* buf;
+    ANativeWindowBuffer* buf;
     int err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf);
     if (err != 0) {
       CODEC_LOGE("dequeueBuffer failed w/ error 0x%08x", err);
diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp
index 7621f2c..4c3dc47 100644
--- a/media/libstagefright/StagefrightMetadataRetriever.cpp
+++ b/media/libstagefright/StagefrightMetadataRetriever.cpp
@@ -27,6 +27,7 @@
 #include <media/stagefright/MediaExtractor.h>
 #include <media/stagefright/MetaData.h>
 #include <media/stagefright/OMXCodec.h>
+#include <media/stagefright/MediaDefs.h>
 
 namespace android {
 
@@ -429,6 +430,7 @@
 
     // The overall duration is the duration of the longest track.
     int64_t maxDurationUs = 0;
+    String8 timedTextLang;
     for (size_t i = 0; i < numTracks; ++i) {
         sp<MetaData> trackMeta = mExtractor->getTrackMetaData(i);
 
@@ -452,10 +454,22 @@
 
                 CHECK(trackMeta->findInt32(kKeyWidth, &videoWidth));
                 CHECK(trackMeta->findInt32(kKeyHeight, &videoHeight));
+            } else if (!strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP)) {
+                const char *lang;
+                trackMeta->findCString(kKeyMediaLanguage, &lang);
+                timedTextLang.append(String8(lang));
+                timedTextLang.append(String8(":"));
             }
         }
     }
 
+    // To save the language codes for all timed text tracks
+    // If multiple text tracks present, the format will look
+    // like "eng:chi"
+    if (!timedTextLang.isEmpty()) {
+        mMetaData.add(METADATA_KEY_TIMED_TEXT_LANGUAGES, timedTextLang);
+    }
+
     // The duration value is a string representing the duration in ms.
     sprintf(tmp, "%lld", (maxDurationUs + 500) / 1000);
     mMetaData.add(METADATA_KEY_DURATION, String8(tmp));
diff --git a/media/libstagefright/TimedTextPlayer.cpp b/media/libstagefright/TimedTextPlayer.cpp
new file mode 100644
index 0000000..1ac22cb
--- /dev/null
+++ b/media/libstagefright/TimedTextPlayer.cpp
@@ -0,0 +1,252 @@
+ /*
+ * 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_NDEBUG 0
+#define LOG_TAG "TimedTextPlayer"
+#include <utils/Log.h>
+
+#include <binder/IPCThreadState.h>
+#include <media/stagefright/MediaDebug.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/MediaSource.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/MediaBuffer.h>
+#include <media/stagefright/Utils.h>
+#include "include/AwesomePlayer.h"
+#include "include/TimedTextPlayer.h"
+
+namespace android {
+
+struct TimedTextEvent : public TimedEventQueue::Event {
+    TimedTextEvent(
+            TimedTextPlayer *player,
+            void (TimedTextPlayer::*method)())
+        : mPlayer(player),
+          mMethod(method) {
+    }
+
+protected:
+    virtual ~TimedTextEvent() {}
+
+    virtual void fire(TimedEventQueue *queue, int64_t /* now_us */) {
+        (mPlayer->*mMethod)();
+    }
+
+private:
+    TimedTextPlayer *mPlayer;
+    void (TimedTextPlayer::*mMethod)();
+
+    TimedTextEvent(const TimedTextEvent &);
+    TimedTextEvent &operator=(const TimedTextEvent &);
+};
+
+TimedTextPlayer::TimedTextPlayer(
+        AwesomePlayer *observer,
+        const wp<MediaPlayerBase> &listener,
+        TimedEventQueue *queue)
+    : mSource(NULL),
+      mSeekTimeUs(0),
+      mStarted(false),
+      mTextEventPending(false),
+      mQueue(queue),
+      mListener(listener),
+      mObserver(observer),
+      mTextBuffer(NULL) {
+    mTextEvent = new TimedTextEvent(this, &TimedTextPlayer::onTextEvent);
+}
+
+TimedTextPlayer::~TimedTextPlayer() {
+    if (mStarted) {
+        reset();
+    }
+
+    mTextTrackVector.clear();
+}
+
+status_t TimedTextPlayer::start(uint8_t index) {
+    CHECK(!mStarted);
+
+    if (index >= mTextTrackVector.size()) {
+        LOGE("Incorrect text track index");
+        return BAD_VALUE;
+    }
+
+    mSource = mTextTrackVector.itemAt(index);
+
+    status_t err = mSource->start();
+
+    if (err != OK) {
+        return err;
+    }
+
+    int64_t positionUs;
+    mObserver->getPosition(&positionUs);
+    seekTo(positionUs);
+
+    postTextEvent();
+
+    mStarted = true;
+
+    return OK;
+}
+
+void TimedTextPlayer::pause() {
+    CHECK(mStarted);
+
+    cancelTextEvent();
+}
+
+void TimedTextPlayer::resume() {
+    CHECK(mStarted);
+
+    postTextEvent();
+}
+
+void TimedTextPlayer::reset() {
+    CHECK(mStarted);
+
+    // send an empty text to clear the screen
+    notifyListener(MEDIA_TIMED_TEXT);
+
+    cancelTextEvent();
+
+    mSeeking = false;
+    mStarted = false;
+
+    if (mTextBuffer != NULL) {
+        mTextBuffer->release();
+        mTextBuffer = NULL;
+    }
+
+    if (mSource != NULL) {
+        mSource->stop();
+        mSource.clear();
+        mSource = NULL;
+    }
+}
+
+status_t TimedTextPlayer::seekTo(int64_t time_us) {
+    Mutex::Autolock autoLock(mLock);
+
+    mSeeking = true;
+    mSeekTimeUs = time_us;
+
+    return OK;
+}
+
+status_t TimedTextPlayer::setTimedTextTrackIndex(int32_t index) {
+    if (index >= (int)(mTextTrackVector.size())) {
+        return BAD_VALUE;
+    }
+
+    if (mStarted) {
+        reset();
+    }
+
+    if (index >= 0) {
+        return start(index);
+    }
+    return OK;
+}
+
+void TimedTextPlayer::onTextEvent() {
+    Mutex::Autolock autoLock(mLock);
+
+    if (!mTextEventPending) {
+        return;
+    }
+    mTextEventPending = false;
+
+    MediaSource::ReadOptions options;
+    if (mSeeking) {
+        options.setSeekTo(mSeekTimeUs,
+                MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
+        mSeeking = false;
+
+        if (mTextBuffer != NULL) {
+            mTextBuffer->release();
+            mTextBuffer = NULL;
+        }
+
+        notifyListener(MEDIA_TIMED_TEXT); //empty text to clear the screen
+    }
+
+    if (mTextBuffer != NULL) {
+        uint8_t *tmp = (uint8_t *)(mTextBuffer->data());
+        size_t len = (*tmp) << 8 | (*(tmp + 1));
+
+        notifyListener(MEDIA_TIMED_TEXT,
+                       tmp + 2,
+                       len);
+
+        mTextBuffer->release();
+        mTextBuffer = NULL;
+
+    }
+
+    if (mSource->read(&mTextBuffer, &options) != OK) {
+        return;
+    }
+
+    int64_t positionUs, timeUs;
+    mObserver->getPosition(&positionUs);
+    mTextBuffer->meta_data()->findInt64(kKeyTime, &timeUs);
+
+    //send the text now
+    if (timeUs <= positionUs + 100000ll) {
+        postTextEvent();
+    } else {
+        postTextEvent(timeUs - positionUs - 100000ll);
+    }
+}
+
+void TimedTextPlayer::postTextEvent(int64_t delayUs) {
+    if (mTextEventPending) {
+        return;
+    }
+
+    mTextEventPending = true;
+    mQueue->postEventWithDelay(mTextEvent, delayUs < 0 ? 10000 : delayUs);
+}
+
+void TimedTextPlayer::cancelTextEvent() {
+    mQueue->cancelEvent(mTextEvent->eventID());
+    mTextEventPending = false;
+}
+
+void TimedTextPlayer::addTextSource(sp<MediaSource> source) {
+    mTextTrackVector.add(source);
+}
+
+void TimedTextPlayer::notifyListener(
+        int msg, const void *data, size_t size) {
+    if (mListener != NULL) {
+        sp<MediaPlayerBase> listener = mListener.promote();
+
+        if (listener != NULL) {
+            if (size > 0) {
+                mData.freeData();
+                mData.write(data, size);
+
+                listener->sendEvent(msg, 0, 0, &mData);
+            } else { // send an empty timed text to clear the screen
+                listener->sendEvent(msg);
+            }
+        }
+    }
+}
+}
diff --git a/media/libstagefright/colorconversion/SoftwareRenderer.cpp b/media/libstagefright/colorconversion/SoftwareRenderer.cpp
index 31afc43..3b13476 100644
--- a/media/libstagefright/colorconversion/SoftwareRenderer.cpp
+++ b/media/libstagefright/colorconversion/SoftwareRenderer.cpp
@@ -108,7 +108,7 @@
 
 void SoftwareRenderer::render(
         const void *data, size_t size, void *platformPrivate) {
-    android_native_buffer_t *buf;
+    ANativeWindowBuffer *buf;
     int err;
     if ((err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf)) != 0) {
         LOGW("Surface::dequeueBuffer returned error %d", err);
diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h
index 2c17d92..fd3ddf7 100644
--- a/media/libstagefright/include/AwesomePlayer.h
+++ b/media/libstagefright/include/AwesomePlayer.h
@@ -44,6 +44,8 @@
 class DrmManagerClinet;
 class DecryptHandle;
 
+class TimedTextPlayer;
+
 struct AwesomeRenderer : public RefBase {
     AwesomeRenderer() {}
 
@@ -99,36 +101,41 @@
     void postAudioEOS(int64_t delayUs = 0ll);
     void postAudioSeekComplete();
 
+    status_t setTimedTextTrackIndex(int32_t index);
+
 private:
     friend struct AwesomeEvent;
     friend struct PreviewPlayer;
 
     enum {
-        PLAYING             = 1,
-        LOOPING             = 2,
-        FIRST_FRAME         = 4,
-        PREPARING           = 8,
-        PREPARED            = 16,
-        AT_EOS              = 32,
-        PREPARE_CANCELLED   = 64,
-        CACHE_UNDERRUN      = 128,
-        AUDIO_AT_EOS        = 256,
-        VIDEO_AT_EOS        = 512,
-        AUTO_LOOPING        = 1024,
+        PLAYING             = 0x01,
+        LOOPING             = 0x02,
+        FIRST_FRAME         = 0x04,
+        PREPARING           = 0x08,
+        PREPARED            = 0x10,
+        AT_EOS              = 0x20,
+        PREPARE_CANCELLED   = 0x40,
+        CACHE_UNDERRUN      = 0x80,
+        AUDIO_AT_EOS        = 0x0100,
+        VIDEO_AT_EOS        = 0x0200,
+        AUTO_LOOPING        = 0x0400,
 
         // We are basically done preparing but are currently buffering
         // sufficient data to begin playback and finish the preparation phase
         // for good.
-        PREPARING_CONNECTED = 2048,
+        PREPARING_CONNECTED = 0x0800,
 
         // We're triggering a single video event to display the first frame
         // after the seekpoint.
-        SEEK_PREVIEW        = 4096,
+        SEEK_PREVIEW        = 0x1000,
 
-        AUDIO_RUNNING       = 8192,
-        AUDIOPLAYER_STARTED = 16384,
+        AUDIO_RUNNING       = 0x2000,
+        AUDIOPLAYER_STARTED = 0x4000,
 
-        INCOGNITO           = 32768,
+        INCOGNITO           = 0x8000,
+
+        TEXT_RUNNING        = 0x10000,
+        TEXTPLAYER_STARTED  = 0x20000,
     };
 
     mutable Mutex mLock;
@@ -222,6 +229,7 @@
     sp<DecryptHandle> mDecryptHandle;
 
     int64_t mLastVideoTimeUs;
+    TimedTextPlayer *mTextPlayer;
 
     status_t setDataSource_l(
             const char *uri,
@@ -244,6 +252,8 @@
     void setVideoSource(sp<MediaSource> source);
     status_t initVideoDecoder(uint32_t flags = 0);
 
+    void addTextSource(sp<MediaSource> source);
+
     void onStreamDone();
 
     void notifyListener_l(int msg, int ext1 = 0, int ext2 = 0);
diff --git a/media/libstagefright/include/TimedTextPlayer.h b/media/libstagefright/include/TimedTextPlayer.h
new file mode 100644
index 0000000..ac41b4f
--- /dev/null
+++ b/media/libstagefright/include/TimedTextPlayer.h
@@ -0,0 +1,91 @@
+/*
+ * 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 TIMEDTEXT_PLAYER_H_
+
+#define TIMEDTEXT_PLAYER_H_
+
+#include <media/MediaPlayerInterface.h>
+#include <media/stagefright/foundation/ABase.h>
+
+#include "include/TimedEventQueue.h"
+
+namespace android {
+
+class MediaSource;
+class AwesomePlayer;
+class MediaBuffer;
+
+class TimedTextPlayer {
+public:
+    TimedTextPlayer(AwesomePlayer *observer,
+                    const wp<MediaPlayerBase> &listener,
+                    TimedEventQueue *queue);
+
+    virtual ~TimedTextPlayer();
+
+    // index: the index of the text track which will
+    // be turned on
+    status_t start(uint8_t index);
+
+    void pause();
+
+    void resume();
+
+    status_t seekTo(int64_t time_us);
+
+    void addTextSource(sp<MediaSource> source);
+
+    status_t setTimedTextTrackIndex(int32_t index);
+
+private:
+    Mutex mLock;
+
+    sp<MediaSource> mSource;
+
+    bool mSeeking;
+    int64_t mSeekTimeUs;
+
+    bool mStarted;
+
+    sp<TimedEventQueue::Event> mTextEvent;
+    bool mTextEventPending;
+
+    TimedEventQueue *mQueue;
+
+    wp<MediaPlayerBase> mListener;
+    AwesomePlayer *mObserver;
+
+    MediaBuffer *mTextBuffer;
+    Parcel mData;
+
+    Vector<sp<MediaSource> > mTextTrackVector;
+
+    void reset();
+
+    void onTextEvent();
+    void postTextEvent(int64_t delayUs = -1);
+    void cancelTextEvent();
+
+    void notifyListener(
+            int msg, const void *data = NULL, size_t size = 0);
+
+    DISALLOW_EVIL_CONSTRUCTORS(TimedTextPlayer);
+};
+
+}  // namespace android
+
+#endif  // TIMEDTEXT_PLAYER_H_
diff --git a/media/libstagefright/matroska/MatroskaExtractor.cpp b/media/libstagefright/matroska/MatroskaExtractor.cpp
index 64266b8..e1b9991 100644
--- a/media/libstagefright/matroska/MatroskaExtractor.cpp
+++ b/media/libstagefright/matroska/MatroskaExtractor.cpp
@@ -591,7 +591,8 @@
         // AudioSpecificInfo (with size prefix) follows
     };
 
-    CHECK(asiSize < 128);
+    // Make sure all sizes can be coded in a single byte.
+    CHECK(asiSize + 22 - 2 < 128);
     size_t esdsSize = sizeof(kStaticESDS) + asiSize + 1;
     uint8_t *esds = new uint8_t[esdsSize];
     memcpy(esds, kStaticESDS, sizeof(kStaticESDS));
@@ -599,6 +600,11 @@
     *ptr++ = asiSize;
     memcpy(ptr, asi, asiSize);
 
+    // Increment by codecPrivateSize less 2 bytes that are accounted for
+    // already in lengths of 22/17
+    esds[1] += asiSize - 2;
+    esds[6] += asiSize - 2;
+
     meta->setData(kKeyESDS, 0, esds, esdsSize);
 
     delete[] esds;
diff --git a/opengl/include/EGL/eglext.h b/opengl/include/EGL/eglext.h
index 1ffcd56..1123e16 100644
--- a/opengl/include/EGL/eglext.h
+++ b/opengl/include/EGL/eglext.h
@@ -225,7 +225,7 @@
 
 #ifndef EGL_ANDROID_image_native_buffer
 #define EGL_ANDROID_image_native_buffer 1
-struct android_native_buffer_t;
+struct ANativeWindowBuffer;
 #define EGL_NATIVE_BUFFER_ANDROID       0x3140  /* eglCreateImageKHR target */
 #endif
 
diff --git a/opengl/libagl/TextureObjectManager.cpp b/opengl/libagl/TextureObjectManager.cpp
index bbb82fc..022de09 100644
--- a/opengl/libagl/TextureObjectManager.cpp
+++ b/opengl/libagl/TextureObjectManager.cpp
@@ -145,7 +145,7 @@
     return NO_ERROR;
 }
 
-status_t EGLTextureObject::setImage(android_native_buffer_t* native_buffer)
+status_t EGLTextureObject::setImage(ANativeWindowBuffer* native_buffer)
 {
     GGLSurface sur;
     sur.version = sizeof(GGLSurface);
diff --git a/opengl/libagl/TextureObjectManager.h b/opengl/libagl/TextureObjectManager.h
index 70e3bef..de9e03e 100644
--- a/opengl/libagl/TextureObjectManager.h
+++ b/opengl/libagl/TextureObjectManager.h
@@ -48,7 +48,7 @@
                    ~EGLTextureObject();
 
     status_t    setSurface(GGLSurface const* s);
-    status_t    setImage(android_native_buffer_t* buffer);
+    status_t    setImage(ANativeWindowBuffer* buffer);
     void        setImageBits(void* vaddr) { surface.data = (GGLubyte*)vaddr; }
 
     status_t            reallocate(GLint level,
@@ -80,7 +80,7 @@
     GLint               crop_rect[4];
     GLint               generate_mipmap;
     GLint               direct;
-    android_native_buffer_t* buffer;
+    ANativeWindowBuffer* buffer;
 };
 
 // ----------------------------------------------------------------------------
diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp
index 97e913ba..0d03361 100644
--- a/opengl/libagl/egl.cpp
+++ b/opengl/libagl/egl.cpp
@@ -230,11 +230,11 @@
     virtual     EGLBoolean  setSwapRectangle(EGLint l, EGLint t, EGLint w, EGLint h);
     
 private:
-    status_t lock(android_native_buffer_t* buf, int usage, void** vaddr);
-    status_t unlock(android_native_buffer_t* buf);
+    status_t lock(ANativeWindowBuffer* buf, int usage, void** vaddr);
+    status_t unlock(ANativeWindowBuffer* buf);
     ANativeWindow*   nativeWindow;
-    android_native_buffer_t*   buffer;
-    android_native_buffer_t*   previousBuffer;
+    ANativeWindowBuffer*   buffer;
+    ANativeWindowBuffer*   previousBuffer;
     gralloc_module_t const*    module;
     int width;
     int height;
@@ -322,8 +322,8 @@
     };
     
     void copyBlt(
-            android_native_buffer_t* dst, void* dst_vaddr,
-            android_native_buffer_t* src, void const* src_vaddr,
+            ANativeWindowBuffer* dst, void* dst_vaddr,
+            ANativeWindowBuffer* src, void const* src_vaddr,
             const Region& clip);
 
     Rect dirtyRegion;
@@ -415,7 +415,7 @@
 }
 
 status_t egl_window_surface_v2_t::lock(
-        android_native_buffer_t* buf, int usage, void** vaddr)
+        ANativeWindowBuffer* buf, int usage, void** vaddr)
 {
     int err;
 
@@ -425,7 +425,7 @@
     return err;
 }
 
-status_t egl_window_surface_v2_t::unlock(android_native_buffer_t* buf)
+status_t egl_window_surface_v2_t::unlock(ANativeWindowBuffer* buf)
 {
     if (!buf) return BAD_VALUE;
     int err = NO_ERROR;
@@ -436,8 +436,8 @@
 }
 
 void egl_window_surface_v2_t::copyBlt(
-        android_native_buffer_t* dst, void* dst_vaddr,
-        android_native_buffer_t* src, void const* src_vaddr,
+        ANativeWindowBuffer* dst, void* dst_vaddr,
+        ANativeWindowBuffer* src, void const* src_vaddr,
         const Region& clip)
 {
     // NOTE: dst and src must be the same format
@@ -2003,12 +2003,12 @@
         return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
     }
 
-    android_native_buffer_t* native_buffer = (android_native_buffer_t*)buffer;
+    ANativeWindowBuffer* native_buffer = (ANativeWindowBuffer*)buffer;
 
     if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC)
         return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
 
-    if (native_buffer->common.version != sizeof(android_native_buffer_t))
+    if (native_buffer->common.version != sizeof(ANativeWindowBuffer))
         return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
 
     switch (native_buffer->format) {
@@ -2034,12 +2034,12 @@
         return setError(EGL_BAD_DISPLAY, EGL_FALSE);
     }
 
-    android_native_buffer_t* native_buffer = (android_native_buffer_t*)img;
+    ANativeWindowBuffer* native_buffer = (ANativeWindowBuffer*)img;
 
     if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC)
         return setError(EGL_BAD_PARAMETER, EGL_FALSE);
 
-    if (native_buffer->common.version != sizeof(android_native_buffer_t))
+    if (native_buffer->common.version != sizeof(ANativeWindowBuffer))
         return setError(EGL_BAD_PARAMETER, EGL_FALSE);
 
     native_buffer->common.decRef(&native_buffer->common);
diff --git a/opengl/libagl/texture.cpp b/opengl/libagl/texture.cpp
index eb96895..8eb17c4 100644
--- a/opengl/libagl/texture.cpp
+++ b/opengl/libagl/texture.cpp
@@ -126,7 +126,7 @@
     for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
         if (c->rasterizer.state.texture[i].enable) {
             texture_unit_t& u(c->textures.tmu[i]);
-            android_native_buffer_t* native_buffer = u.texture->buffer;
+            ANativeWindowBuffer* native_buffer = u.texture->buffer;
             if (native_buffer) {
                 c->rasterizer.procs.activeTexture(c, i);
                 hw_module_t const* pModule;
@@ -154,7 +154,7 @@
     for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
         if (c->rasterizer.state.texture[i].enable) {
             texture_unit_t& u(c->textures.tmu[i]);
-            android_native_buffer_t* native_buffer = u.texture->buffer;
+            ANativeWindowBuffer* native_buffer = u.texture->buffer;
             if (native_buffer) {
                 c->rasterizer.procs.activeTexture(c, i);
                 hw_module_t const* pModule;
@@ -1615,12 +1615,12 @@
         return;
     }
 
-    android_native_buffer_t* native_buffer = (android_native_buffer_t*)image;
+    ANativeWindowBuffer* native_buffer = (ANativeWindowBuffer*)image;
     if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) {
         ogles_error(c, GL_INVALID_VALUE);
         return;
     }
-    if (native_buffer->common.version != sizeof(android_native_buffer_t)) {
+    if (native_buffer->common.version != sizeof(ANativeWindowBuffer)) {
         ogles_error(c, GL_INVALID_VALUE);
         return;
     }
@@ -1643,12 +1643,12 @@
         return;
     }
 
-    android_native_buffer_t* native_buffer = (android_native_buffer_t*)image;
+    ANativeWindowBuffer* native_buffer = (ANativeWindowBuffer*)image;
     if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) {
         ogles_error(c, GL_INVALID_VALUE);
         return;
     }
-    if (native_buffer->common.version != sizeof(android_native_buffer_t)) {
+    if (native_buffer->common.version != sizeof(ANativeWindowBuffer)) {
         ogles_error(c, GL_INVALID_VALUE);
         return;
     }
diff --git a/opengl/libagl2/src/egl.cpp b/opengl/libagl2/src/egl.cpp
index ec5889d..0d02ce6 100644
--- a/opengl/libagl2/src/egl.cpp
+++ b/opengl/libagl2/src/egl.cpp
@@ -211,11 +211,11 @@
     virtual     EGLBoolean  setSwapRectangle(EGLint l, EGLint t, EGLint w, EGLint h);
 
 private:
-    status_t lock(android_native_buffer_t* buf, int usage, void** vaddr);
-    status_t unlock(android_native_buffer_t* buf);
+    status_t lock(ANativeWindowBuffer* buf, int usage, void** vaddr);
+    status_t unlock(ANativeWindowBuffer* buf);
     ANativeWindow*   nativeWindow;
-    android_native_buffer_t*   buffer;
-    android_native_buffer_t*   previousBuffer;
+    ANativeWindowBuffer*   buffer;
+    ANativeWindowBuffer*   previousBuffer;
     gralloc_module_t const*    module;
     int width;
     int height;
@@ -307,8 +307,8 @@
     };
 
     void copyBlt(
-            android_native_buffer_t* dst, void* dst_vaddr,
-            android_native_buffer_t* src, void const* src_vaddr,
+            ANativeWindowBuffer* dst, void* dst_vaddr,
+            ANativeWindowBuffer* src, void const* src_vaddr,
             const Region& clip);
 
     Rect dirtyRegion;
@@ -407,7 +407,7 @@
 }
 
 status_t egl_window_surface_v2_t::lock(
-        android_native_buffer_t* buf, int usage, void** vaddr)
+        ANativeWindowBuffer* buf, int usage, void** vaddr)
 {
     int err;
 
@@ -417,7 +417,7 @@
     return err;
 }
 
-status_t egl_window_surface_v2_t::unlock(android_native_buffer_t* buf)
+status_t egl_window_surface_v2_t::unlock(ANativeWindowBuffer* buf)
 {
     if (!buf) return BAD_VALUE;
     int err = NO_ERROR;
@@ -428,8 +428,8 @@
 }
 
 void egl_window_surface_v2_t::copyBlt(
-        android_native_buffer_t* dst, void* dst_vaddr,
-        android_native_buffer_t* src, void const* src_vaddr,
+        ANativeWindowBuffer* dst, void* dst_vaddr,
+        ANativeWindowBuffer* src, void const* src_vaddr,
         const Region& clip)
 {
     // NOTE: dst and src must be the same format
@@ -2105,12 +2105,12 @@
         return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
     }
 
-    android_native_buffer_t* native_buffer = (android_native_buffer_t*)buffer;
+    ANativeWindowBuffer* native_buffer = (ANativeWindowBuffer*)buffer;
 
     if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC)
         return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
 
-    if (native_buffer->common.version != sizeof(android_native_buffer_t))
+    if (native_buffer->common.version != sizeof(ANativeWindowBuffer))
         return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
 
     switch (native_buffer->format) {
@@ -2136,12 +2136,12 @@
         return setError(EGL_BAD_DISPLAY, EGL_FALSE);
     }
 
-    android_native_buffer_t* native_buffer = (android_native_buffer_t*)img;
+    ANativeWindowBuffer* native_buffer = (ANativeWindowBuffer*)img;
 
     if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC)
         return setError(EGL_BAD_PARAMETER, EGL_FALSE);
 
-    if (native_buffer->common.version != sizeof(android_native_buffer_t))
+    if (native_buffer->common.version != sizeof(ANativeWindowBuffer))
         return setError(EGL_BAD_PARAMETER, EGL_FALSE);
 
     native_buffer->common.decRef(&native_buffer->common);
diff --git a/packages/SystemUI/res/drawable-hdpi/status_bar_background.9.png b/packages/SystemUI/res/drawable-hdpi/status_bar_background.9.png
deleted file mode 100644
index a4be298..0000000
--- a/packages/SystemUI/res/drawable-hdpi/status_bar_background.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/status_bar_close_on.9.png b/packages/SystemUI/res/drawable-hdpi/status_bar_close_on.9.png
new file mode 100644
index 0000000..87d1944
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/status_bar_close_on.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/status_bar_veto_normal.png b/packages/SystemUI/res/drawable-hdpi/status_bar_veto_normal.png
new file mode 100644
index 0000000..3b7c9c7
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/status_bar_veto_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/status_bar_veto_pressed.png b/packages/SystemUI/res/drawable-hdpi/status_bar_veto_pressed.png
new file mode 100644
index 0000000..653acbb
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/status_bar_veto_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/statusbar_background.9.png b/packages/SystemUI/res/drawable-hdpi/statusbar_background.9.png
new file mode 100644
index 0000000..a933833
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/statusbar_background.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/status_bar_background.9.png b/packages/SystemUI/res/drawable-mdpi/status_bar_background.9.png
deleted file mode 100644
index eb7c1a4..0000000
--- a/packages/SystemUI/res/drawable-mdpi/status_bar_background.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/statusbar_background.9.png b/packages/SystemUI/res/drawable-mdpi/statusbar_background.9.png
new file mode 100644
index 0000000..6c588f7
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/statusbar_background.9.png
Binary files differ
diff --git a/packages/SystemUI/res/layout/navigation_bar.xml b/packages/SystemUI/res/layout/navigation_bar.xml
new file mode 100644
index 0000000..eba4480
--- /dev/null
+++ b/packages/SystemUI/res/layout/navigation_bar.xml
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* apps/common/assets/default/default/skins/StatusBar.xml
+**
+** Copyright 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.
+*/
+-->
+
+<com.android.systemui.statusbar.phone.NavigationBarView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
+    android:layout_height="match_parent"
+    android:layout_width="match_parent"
+    >
+
+    <LinearLayout android:id="@+id/rot0"
+        android:layout_height="match_parent"
+        android:layout_width="match_parent"
+        android:paddingLeft="8dip"
+        android:paddingRight="8dip"
+        android:background="#FF000000"
+        android:orientation="horizontal"
+        >
+
+        <!-- navigation controls -->
+        <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:src="@drawable/ic_sysbar_back"
+            systemui:keyCode="4"
+            android:layout_weight="1"
+            />
+        <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:src="@drawable/ic_sysbar_home"
+            systemui:keyCode="3"
+            android:layout_weight="1"
+            />
+        <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:src="@drawable/ic_sysbar_menu"
+            systemui:keyCode="82"
+            android:layout_weight="1"
+            />
+    </LinearLayout>
+
+    <LinearLayout android:id="@+id/rot90"
+        android:layout_height="match_parent"
+        android:layout_width="match_parent"
+        android:background="#FF000000"
+        android:orientation="vertical"
+        android:visibility="gone"
+        >
+
+        <!-- navigation controls -->
+        <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:src="@drawable/ic_sysbar_menu"
+            systemui:keyCode="82"
+            android:layout_weight="1"
+            />
+        <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:src="@drawable/ic_sysbar_home"
+            systemui:keyCode="3"
+            android:layout_weight="1"
+            />
+        <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:src="@drawable/ic_sysbar_back"
+            systemui:keyCode="4"
+            android:layout_weight="1"
+            />
+    </LinearLayout>
+
+    <LinearLayout android:id="@+id/rot270"
+        android:layout_height="match_parent"
+        android:layout_width="match_parent"
+        android:background="#FF000000"
+        android:orientation="vertical"
+        android:visibility="gone"
+        >
+
+        <!-- navigation controls -->
+        <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:src="@drawable/ic_sysbar_back"
+            systemui:keyCode="4"
+            android:layout_weight="1"
+            />
+        <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:src="@drawable/ic_sysbar_home"
+            systemui:keyCode="3"
+            android:layout_weight="1"
+            />
+        <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:src="@drawable/ic_sysbar_menu"
+            systemui:keyCode="82"
+            android:layout_weight="1"
+            />
+    </LinearLayout>
+</com.android.systemui.statusbar.phone.NavigationBarView>
diff --git a/packages/SystemUI/res/layout/status_bar_notification_row.xml b/packages/SystemUI/res/layout/status_bar_notification_row.xml
index 88d9739..8e456b2 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_row.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_row.xml
@@ -1,24 +1,45 @@
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="65sp"
-    android:orientation="vertical"
+    android:layout_height="65dp"
     >
 
+    <ImageButton
+        android:id="@+id/veto"
+        android:layout_width="48dp"
+        android:layout_height="match_parent"
+        android:layout_centerVertical="true"
+        android:layout_alignParentRight="true"
+        android:src="@drawable/status_bar_veto"
+        android:scaleType="center"
+        android:background="@null"
+        android:paddingRight="8dp"
+        android:paddingLeft="8dp"
+        />
+
+    <ImageView
+        android:id="@+id/large_icon"
+        android:layout_width="@android:dimen/notification_large_icon_width"
+        android:layout_height="@android:dimen/notification_large_icon_height"
+        android:layout_alignParentTop="true"
+        android:layout_alignParentLeft="true"
+        android:scaleType="center"
+        />
+
     <com.android.systemui.statusbar.LatestItemView android:id="@+id/content"
-            android:layout_width="match_parent"
-            android:layout_height="64sp"
-            android:background="@android:drawable/status_bar_item_background"
-            android:focusable="true"
-            android:clickable="true"
-            android:paddingRight="6sp"
-            >
-    </com.android.systemui.statusbar.LatestItemView>
+        android:layout_width="match_parent"
+        android:layout_height="64dp"
+        android:layout_alignParentTop="true"
+        android:layout_toRightOf="@id/large_icon"
+        android:layout_toLeftOf="@id/veto"
+        android:focusable="true"
+        android:clickable="true"
+        />
 
     <View
         android:layout_width="match_parent"
-        android:layout_height="1sp"
-        android:background="@android:drawable/divider_horizontal_bright"
+        android:layout_height="1dp"
+        android:layout_alignParentBottom="true"
+        android:background="@android:drawable/divider_horizontal_dark"
         />
 
-</LinearLayout>
-
+</RelativeLayout>
diff --git a/packages/SystemUI/res/layout/status_bar_tracking.xml b/packages/SystemUI/res/layout/status_bar_tracking.xml
index a0ddab5..baa45c5 100644
--- a/packages/SystemUI/res/layout/status_bar_tracking.xml
+++ b/packages/SystemUI/res/layout/status_bar_tracking.xml
@@ -26,11 +26,12 @@
     android:paddingRight="0px"
     >
 
-    <com.android.systemui.statusbar.phone.TrackingPatternView
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_weight="1"
-        />
+    <View
+         android:layout_width="match_parent"
+         android:layout_height="wrap_content"
+         android:layout_weight="1"
+         android:background="#ff000000"
+         />
 
     <com.android.systemui.statusbar.phone.CloseDragHandle android:id="@+id/close"
         android:layout_width="match_parent"
@@ -42,7 +43,7 @@
             android:layout_height="wrap_content"
             android:layout_gravity="bottom"
             android:scaleType="fitXY"
-            android:src="@drawable/shade_handlebar"
+            android:src="@drawable/status_bar_close_on"
             />
 
     </com.android.systemui.statusbar.phone.CloseDragHandle>
diff --git a/packages/SystemUI/res/values-land/dimens.xml b/packages/SystemUI/res/values-land/dimens.xml
new file mode 100644
index 0000000..bcc8da1
--- /dev/null
+++ b/packages/SystemUI/res/values-land/dimens.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * 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.
+*/
+-->
+<resources>
+    <!-- thickness (width) of the navigation bar on phones that require it -->
+    <dimen name="navigation_bar_size">42dp</dimen>
+</resources>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 964e69b..9341693 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -20,4 +20,5 @@
     <drawable name="notification_number_text_color">#ffffffff</drawable>
     <drawable name="notification_item_background_color">#ff000000</drawable>
     <drawable name="ticker_background_color">#ff1d1d1d</drawable>
+    <drawable name="status_bar_background">#000000</drawable>
 </resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 88cd43c..a2577cb 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -31,5 +31,7 @@
     <!-- Width of scrollable area in recents -->
     <dimen name="status_bar_recents_width">356dp</dimen>
 
+    <!-- thickness (height) of the navigation bar on phones that require it -->
+    <dimen name="navigation_bar_size">42dp</dimen>
 </resources>
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
new file mode 100644
index 0000000..ec169e5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2008 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.systemui.statusbar.phone;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.Display;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.Surface;
+import android.view.WindowManager;
+import android.widget.LinearLayout;
+import android.content.res.Configuration;
+
+import com.android.systemui.R;
+
+public class NavigationBarView extends LinearLayout {
+    final Display mDisplay;
+    View[] mRotatedViews = new View[4];
+
+    public NavigationBarView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        mDisplay = ((WindowManager)context.getSystemService(
+                Context.WINDOW_SERVICE)).getDefaultDisplay();
+    }
+
+    public void onFinishInflate() {
+        mRotatedViews[Surface.ROTATION_0] = 
+        mRotatedViews[Surface.ROTATION_180] = findViewById(R.id.rot0);
+
+        mRotatedViews[Surface.ROTATION_90] = findViewById(R.id.rot90);
+        
+        mRotatedViews[Surface.ROTATION_270] = findViewById(R.id.rot270);
+    }
+
+    public void reorient() {
+        final int rot = mDisplay.getRotation();
+        for (int i=0; i<4; i++) {
+            mRotatedViews[i].setVisibility(View.GONE);
+        }
+        mRotatedViews[rot].setVisibility(View.VISIBLE);
+
+        android.util.Log.d("NavigationBarView", "reorient(): rot=" + mDisplay.getRotation());
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 1e46246..b4adde6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -45,6 +45,7 @@
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
+import android.view.Surface;
 import android.view.VelocityTracker;
 import android.view.View;
 import android.view.ViewGroup;
@@ -141,6 +142,9 @@
     // for immersive activities
     private View mIntruderAlertView;
 
+    // on-screen navigation buttons
+    private NavigationBarView mNavigationBarView;
+
     // the tracker view
     TrackingView mTrackingView;
     WindowManager.LayoutParams mTrackingParams;
@@ -199,7 +203,9 @@
 
         super.start();
 
-        addIntruderView();
+        addNavigationBar();
+
+        //addIntruderView();
 
         // Lastly, call to the icon policy to install/update all the icons.
         mIconPolicy = new PhoneStatusBarPolicy(mContext);
@@ -223,6 +229,9 @@
         mIntruderAlertView.setVisibility(View.GONE);
         mIntruderAlertView.setClickable(true);
 
+        mNavigationBarView = 
+            (NavigationBarView) View.inflate(context, R.layout.navigation_bar, null);
+
         PhoneStatusBarView sb = (PhoneStatusBarView)View.inflate(context,
                 R.layout.status_bar, null);
         sb.mService = this;
@@ -292,6 +301,58 @@
         return res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
     }
 
+    // For small-screen devices (read: phones) that lack hardware navigation buttons
+    private void addNavigationBar() {
+        mNavigationBarView.reorient();
+        WindowManagerImpl.getDefault().addView(
+                mNavigationBarView, getNavigationBarLayoutParams());
+    }
+
+    private void repositionNavigationBar() {
+        mNavigationBarView.reorient();
+        WindowManagerImpl.getDefault().updateViewLayout(
+                mNavigationBarView, getNavigationBarLayoutParams());
+    }
+
+    private WindowManager.LayoutParams getNavigationBarLayoutParams() {
+        final int rotation = mDisplay.getRotation();
+        final boolean sideways = 
+            (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270);
+
+        final Resources res = mContext.getResources();
+        final int size = res.getDimensionPixelSize(R.dimen.navigation_bar_size);
+
+        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
+                sideways ? size : ViewGroup.LayoutParams.MATCH_PARENT,
+                sideways ? ViewGroup.LayoutParams.MATCH_PARENT : size,
+                WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
+                    0
+                    | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+                    | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
+                    | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
+                    | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
+                PixelFormat.TRANSLUCENT);
+
+        lp.setTitle("NavigationBar");
+        switch (rotation) {
+            case Surface.ROTATION_90:
+                // device has been turned 90deg counter-clockwise
+                lp.gravity = Gravity.RIGHT | Gravity.FILL_VERTICAL;
+                break;
+            case Surface.ROTATION_270:
+                // device has been turned 90deg clockwise
+                lp.gravity = Gravity.LEFT | Gravity.FILL_VERTICAL;
+                break;
+            default:
+                lp.gravity = Gravity.BOTTOM | Gravity.FILL_HORIZONTAL;
+                break;
+        }
+        lp.windowAnimations = 0;
+
+        return lp;
+    }
+
     private void addIntruderView() {
         final int height = getStatusBarHeight();
 
@@ -511,6 +572,38 @@
                 Context.LAYOUT_INFLATER_SERVICE);
         View row = inflater.inflate(R.layout.status_bar_notification_row, parent, false);
 
+        // wire up the veto button
+        View vetoButton = row.findViewById(R.id.veto);
+        if (notification.isClearable()) {
+            final String _pkg = notification.pkg;
+            final String _tag = notification.tag;
+            final int _id = notification.id;
+            vetoButton.setOnClickListener(new View.OnClickListener() {
+                    public void onClick(View v) {
+                        try {
+                            mBarService.onNotificationClear(_pkg, _tag, _id);
+                        } catch (RemoteException ex) {
+                            // system process is dead if we're here.
+                        }
+                    }
+                });
+        } else {
+            if ((notification.notification.flags & Notification.FLAG_ONGOING_EVENT) == 0) {
+                vetoButton.setVisibility(View.INVISIBLE);
+            } else {
+                vetoButton.setVisibility(View.GONE);
+            }
+        }
+
+        // the large icon
+        ImageView largeIcon = (ImageView)row.findViewById(R.id.large_icon);
+        if (notification.notification.largeIcon != null) {
+            largeIcon.setImageBitmap(notification.notification.largeIcon);
+        } else {
+            largeIcon.getLayoutParams().width = 0;
+            largeIcon.setVisibility(View.INVISIBLE);
+        }
+
         // bind the click event to the content area
         ViewGroup content = (ViewGroup)row.findViewById(R.id.content);
         content.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
@@ -1497,6 +1590,7 @@
                 animateCollapse();
             }
             else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) {
+                repositionNavigationBar();
                 updateResources();
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/HeightReceiver.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/HeightReceiver.java
index 90c9568..9924faa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/HeightReceiver.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/HeightReceiver.java
@@ -77,7 +77,9 @@
         if (plugged) {
             final DisplayMetrics metrics = new DisplayMetrics();
             mWindowManager.getDefaultDisplay().getMetrics(metrics);
-            height = metrics.heightPixels - 720;
+            //Slog.i(TAG, "setPlugged: display metrics=" + metrics);
+            final int shortSide = Math.min(metrics.widthPixels, metrics.heightPixels);
+            height = shortSide - 720;
         }
 
         final int minHeight
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index d22d760..d997109 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -1524,6 +1524,7 @@
             }
 
             st.onRestoreInstanceState(icicles.get(curFeatureId));
+            invalidatePanelMenu(curFeatureId);
         }
 
         /*
@@ -1962,8 +1963,13 @@
                 mContextMenu.clearAll();
             }
 
-            mContextMenuHelper = mContextMenu.show(originalView, originalView.getWindowToken());
-            return mContextMenuHelper != null;
+            final MenuDialogHelper helper = mContextMenu.show(originalView,
+                    originalView.getWindowToken());
+            if (helper != null) {
+                helper.setPresenterCallback(mContextMenuCallback);
+            }
+            mContextMenuHelper = helper;
+            return helper != null;
         }
 
         @Override
@@ -2592,6 +2598,7 @@
                         final ActionBarContainer splitView = (ActionBarContainer) findViewById(
                                 com.android.internal.R.id.split_action_bar);
                         if (splitView != null) {
+                            splitView.setVisibility(View.VISIBLE);
                             mActionBar.setSplitActionBar(splitActionBar);
                             mActionBar.setSplitView(splitView);
 
@@ -3109,9 +3116,8 @@
              * The first time the menu is being shown after restoring, the
              * Activity.onCreateOptionsMenu should be called. But, if it is the
              * same instance then menu != null and we won't call that method.
-             * So, clear this.  Also clear any cached views.
+             * We clear any cached views here. The caller should invalidatePanelMenu.
              */
-            menu = null;
             createdPanelView = null;
             shownPanelView = null;
             decorView = null;
@@ -3170,7 +3176,7 @@
      * <li> Calls back to the callback's onMenuItemSelected when an item is
      * selected.
      */
-    private final class DialogMenuCallback implements MenuBuilder.Callback {
+    private final class DialogMenuCallback implements MenuBuilder.Callback, MenuPresenter.Callback {
         private int mFeatureId;
         private MenuDialogHelper mSubMenuHelper;
 
@@ -3179,6 +3185,10 @@
         }
 
         public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
+            if (menu.getRootMenu() != menu) {
+                onCloseSubMenu(menu);
+            }
+
             if (allMenusAreClosing) {
                 Callback callback = getCallback();
                 if (callback != null && !isDestroyed()) {
@@ -3197,7 +3207,7 @@
             }
         }
 
-        public void onCloseSubMenu(SubMenuBuilder menu) {
+        public void onCloseSubMenu(MenuBuilder menu) {
             Callback callback = getCallback();
             if (callback != null && !isDestroyed()) {
                 callback.onPanelClosed(mFeatureId, menu.getRootMenu());
@@ -3213,7 +3223,7 @@
         public void onMenuModeChange(MenuBuilder menu) {
         }
 
-        public boolean onSubMenuSelected(SubMenuBuilder subMenu) {
+        public boolean onOpenSubMenu(MenuBuilder subMenu) {
             // Set a simple callback for the submenu
             subMenu.setCallback(this);
 
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index a37ccc7..8a29419 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -111,6 +111,7 @@
 import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
 import static android.view.WindowManager.LayoutParams.TYPE_POINTER;
+import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
 import android.view.WindowManagerImpl;
 import android.view.WindowManagerPolicy;
 import android.view.KeyCharacterMap.FallbackAction;
@@ -175,14 +176,16 @@
     // responsible for power management when displayed.
     static final int KEYGUARD_LAYER = 15;
     static final int KEYGUARD_DIALOG_LAYER = 16;
+    // the navigation bar, if available, shows atop most things
+    static final int NAVIGATION_BAR_LAYER = 17;
     // the drag layer: input for drag-and-drop is associated with this window,
     // which sits above all other focusable windows
-    static final int DRAG_LAYER = 17;
+    static final int DRAG_LAYER = 18;
     // things in here CAN NOT take focus, but are shown on top of everything else.
-    static final int SYSTEM_OVERLAY_LAYER = 18;
-    static final int SECURE_SYSTEM_OVERLAY_LAYER = 19;
+    static final int SYSTEM_OVERLAY_LAYER = 19;
+    static final int SECURE_SYSTEM_OVERLAY_LAYER = 20;
     // the (mouse) pointer layer
-    static final int POINTER_LAYER = 20;
+    static final int POINTER_LAYER = 21;
 
     static final int APPLICATION_MEDIA_SUBLAYER = -2;
     static final int APPLICATION_MEDIA_OVERLAY_SUBLAYER = -1;
@@ -228,6 +231,8 @@
     WindowState mStatusBar = null;
     boolean mStatusBarCanHide;
     final ArrayList<WindowState> mStatusBarPanels = new ArrayList<WindowState>();
+    WindowState mNavigationBar = null;
+
     WindowState mKeyguard = null;
     KeyguardViewMediator mKeyguardMediator;
     GlobalActions mGlobalActions;
@@ -1037,6 +1042,8 @@
             return DRAG_LAYER;
         case TYPE_POINTER:
             return POINTER_LAYER;
+        case TYPE_NAVIGATION_BAR:
+            return NAVIGATION_BAR_LAYER;
         }
         Log.e(TAG, "Unknown window type: " + type);
         return APPLICATION_LAYER;
@@ -1214,6 +1221,13 @@
                         com.android.internal.R.bool.config_statusBarCanHide);
 
                 break;
+            case TYPE_NAVIGATION_BAR:
+                mContext.enforceCallingOrSelfPermission(
+                        android.Manifest.permission.STATUS_BAR_SERVICE,
+                        "PhoneWindowManager");
+                mNavigationBar = win;
+                if (DEBUG_LAYOUT) Log.i(TAG, "NAVIGATION BAR: " + mNavigationBar);
+                break;
             case TYPE_STATUS_BAR_PANEL:
                 mContext.enforceCallingOrSelfPermission(
                         android.Manifest.permission.STATUS_BAR_SERVICE,
@@ -1240,9 +1254,10 @@
     public void removeWindowLw(WindowState win) {
         if (mStatusBar == win) {
             mStatusBar = null;
-        }
-        else if (mKeyguard == win) {
+        } else if (mKeyguard == win) {
             mKeyguard = null;
+        } else if (mNavigationBar == win) {
+            mNavigationBar = null;
         } else {
             mStatusBarPanels.remove(win);
         }
@@ -1609,17 +1624,48 @@
         mDockBottom = mContentBottom = mCurBottom = displayHeight;
         mDockLayer = 0x10000000;
 
+        // start with the current dock rect, which will be (0,0,displayWidth,displayHeight)
+        final Rect pf = mTmpParentFrame;
+        final Rect df = mTmpDisplayFrame;
+        final Rect vf = mTmpVisibleFrame;
+        pf.left = df.left = vf.left = mDockLeft;
+        pf.top = df.top = vf.top = mDockTop;
+        pf.right = df.right = vf.right = mDockRight;
+        pf.bottom = df.bottom = vf.bottom = mDockBottom;
+
         // decide where the status bar goes ahead of time
         if (mStatusBar != null) {
-            final Rect pf = mTmpParentFrame;
-            final Rect df = mTmpDisplayFrame;
-            final Rect vf = mTmpVisibleFrame;
-            pf.left = df.left = vf.left = 0;
-            pf.top = df.top = vf.top = 0;
-            pf.right = df.right = vf.right = displayWidth;
-            pf.bottom = df.bottom = vf.bottom = displayHeight;
-            
+            Rect navr = null;
+            if (mNavigationBar != null) {
+                mNavigationBar.computeFrameLw(pf, df, vf, vf);
+                if (mNavigationBar.isVisibleLw()) {
+                    navr = mNavigationBar.getFrameLw();
+
+                    if (navr.top == 0) {
+                        // Navigation bar is vertical
+                        if (mDockLeft == navr.left) {
+                            mDockLeft = navr.right;
+                        } else if (mDockRight == navr.right) {
+                            mDockRight = navr.left;
+                        }
+                    } else {
+                        // Navigation bar horizontal, at bottom
+                        if (mDockBottom == navr.bottom) {
+                            mDockBottom = navr.top;
+                        }
+                    }
+                }
+            }
+            if (DEBUG_LAYOUT) Log.i(TAG, "mNavigationBar frame: " + navr);
+
+            // apply navigation bar insets
+            pf.left = df.left = vf.left = mDockLeft;
+            pf.top = df.top = vf.top = mDockTop;
+            pf.right = df.right = vf.right = mDockRight;
+            pf.bottom = df.bottom = vf.bottom = mDockBottom;
+
             mStatusBar.computeFrameLw(pf, df, vf, vf);
+
             if (mStatusBar.isVisibleLw()) {
                 // If the status bar is hidden, we don't want to cause
                 // windows behind it to scroll.
@@ -1630,14 +1676,18 @@
                     // status bar is visible.
                     if (mDockTop == r.top) mDockTop = r.bottom;
                     else if (mDockBottom == r.bottom) mDockBottom = r.top;
+                    
                     mContentTop = mCurTop = mDockTop;
                     mContentBottom = mCurBottom = mDockBottom;
-                    if (DEBUG_LAYOUT) Log.v(TAG, "Status bar: mDockTop=" + mDockTop
-                            + " mContentTop=" + mContentTop
-                            + " mCurTop=" + mCurTop
-                            + " mDockBottom=" + mDockBottom
-                            + " mContentBottom=" + mContentBottom
-                            + " mCurBottom=" + mCurBottom);
+                    mContentLeft = mCurLeft = mDockLeft;
+                    mContentRight = mCurRight = mDockRight;
+
+                    if (DEBUG_LAYOUT) Log.v(TAG, "Status bar: " +
+                        String.format(
+                            "dock=[%d,%d][%d,%d] content=[%d,%d][%d,%d] cur=[%d,%d][%d,%d]",
+                            mDockLeft, mDockTop, mDockRight, mDockBottom,
+                            mContentLeft, mContentTop, mContentRight, mContentBottom,
+                            mCurLeft, mCurTop, mCurRight, mCurBottom));
                 } else {
                     // Status bar can't go away; the part of the screen it
                     // covers does not exist for anything behind it.
@@ -1647,12 +1697,32 @@
                     } else if ((mRestrictedScreenHeight-mRestrictedScreenTop) == r.bottom) {
                         mRestrictedScreenHeight -= (r.bottom-r.top);
                     }
+
+                    if (navr != null) {
+                        if (navr.top == 0) {
+                            // Navigation bar is vertical
+                            if (mRestrictedScreenLeft == navr.left) {
+                                mRestrictedScreenLeft = navr.right;
+                                mRestrictedScreenWidth -= (navr.right - navr.left);
+                            } else if ((mRestrictedScreenLeft+mRestrictedScreenWidth) == navr.right) {
+                                mRestrictedScreenWidth -= (navr.right - navr.left);
+                            }
+                        } else {
+                            // Navigation bar horizontal, at bottom
+                            if ((mRestrictedScreenHeight-mRestrictedScreenTop) == r.bottom) {
+                                mRestrictedScreenHeight -= (navr.bottom-navr.top);
+                            }
+                        }
+                    }
+
                     mContentTop = mCurTop = mDockTop = mRestrictedScreenTop;
                     mContentBottom = mCurBottom = mDockBottom
                             = mRestrictedScreenTop + mRestrictedScreenHeight;
-                    if (DEBUG_LAYOUT) Log.v(TAG, "Status bar: mRestrictedScreenTop="
-                            + mRestrictedScreenTop
-                            + " mRestrictedScreenHeight=" + mRestrictedScreenHeight);
+                    if (DEBUG_LAYOUT) Log.v(TAG, "Status bar: restricted screen area: ("
+                            + mRestrictedScreenLeft + ","
+                            + mRestrictedScreenTop + ","
+                            + (mRestrictedScreenLeft + mRestrictedScreenWidth) + ","
+                            + (mRestrictedScreenTop + mRestrictedScreenHeight) + ")");
                 }
             }
         }
@@ -1722,6 +1792,8 @@
         final Rect cf = mTmpContentFrame;
         final Rect vf = mTmpVisibleFrame;
         
+        final boolean hasNavBar = (mNavigationBar != null && mNavigationBar.isVisibleLw());
+
         if (attrs.type == TYPE_INPUT_METHOD) {
             pf.left = df.left = cf.left = vf.left = mDockLeft;
             pf.top = df.top = cf.top = vf.top = mDockTop;
@@ -1735,6 +1807,9 @@
 
             if ((fl & (FLAG_LAYOUT_IN_SCREEN | FLAG_FULLSCREEN | FLAG_LAYOUT_INSET_DECOR))
                     == (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR)) {
+                if (DEBUG_LAYOUT)
+                    Log.v(TAG, "layoutWindowLw(" + attrs.getTitle() 
+                            + "): IN_SCREEN, INSET_DECOR, !FULLSCREEN");
                 // This is the case for a normal activity window: we want it
                 // to cover all of the screen space, and it can take care of
                 // moving its contents to account for screen decorations that
@@ -1744,15 +1819,26 @@
                     // frame is the same as the one we are attached to.
                     setAttachedWindowFrames(win, fl, sim, attached, true, pf, df, cf, vf);
                 } else {
-                    if (attrs.type == TYPE_STATUS_BAR_PANEL) {
+                    if (attrs.type == TYPE_STATUS_BAR_PANEL
+                            || attrs.type == TYPE_STATUS_BAR_SUB_PANEL) {
                         // Status bar panels are the only windows who can go on top of
                         // the status bar.  They are protected by the STATUS_BAR_SERVICE
                         // permission, so they have the same privileges as the status
                         // bar itself.
-                        pf.left = df.left = mUnrestrictedScreenLeft;
+                        //
+                        // However, they should still dodge the navigation bar if it exists. A
+                        // straightforward way to do this is to only allow the status bar panels to
+                        // extend to the extrema of the allowable region for the IME dock.
+
+                        pf.left = df.left = hasNavBar ? mDockLeft : mUnrestrictedScreenLeft;
                         pf.top = df.top = mUnrestrictedScreenTop;
-                        pf.right = df.right = mUnrestrictedScreenLeft+mUnrestrictedScreenWidth;
-                        pf.bottom = df.bottom = mUnrestrictedScreenTop+mUnrestrictedScreenHeight;
+                        pf.right = df.right = hasNavBar
+                                            ? mDockRight
+                                            : mUnrestrictedScreenLeft+mUnrestrictedScreenWidth;
+                        pf.bottom = df.bottom = hasNavBar
+                                              ? mDockBottom
+                                              : mUnrestrictedScreenTop+mUnrestrictedScreenHeight;
+
                     } else {
                         pf.left = df.left = mRestrictedScreenLeft;
                         pf.top = df.top = mRestrictedScreenTop;
@@ -1780,15 +1866,21 @@
                     }
                 }
             } else if ((fl & FLAG_LAYOUT_IN_SCREEN) != 0) {
+                if (DEBUG_LAYOUT)
+                    Log.v(TAG, "layoutWindowLw(" + attrs.getTitle() + "): IN_SCREEN");
                 // A window that has requested to fill the entire screen just
                 // gets everything, period.
-                if (attrs.type == TYPE_STATUS_BAR_PANEL) {
-                    pf.left = df.left = cf.left = mUnrestrictedScreenLeft;
+                if (attrs.type == TYPE_STATUS_BAR_PANEL
+                        || attrs.type == TYPE_STATUS_BAR_SUB_PANEL) {
+                    pf.left = df.left = cf.left = hasNavBar ? mDockLeft : mUnrestrictedScreenLeft;
                     pf.top = df.top = cf.top = mUnrestrictedScreenTop;
-                    pf.right = df.right = cf.right
-                            = mUnrestrictedScreenLeft+mUnrestrictedScreenWidth;
-                    pf.bottom = df.bottom = cf.bottom
-                            = mUnrestrictedScreenTop+mUnrestrictedScreenHeight;
+                    pf.right = df.right = cf.right = hasNavBar
+                                        ? mDockRight
+                                        : mUnrestrictedScreenLeft+mUnrestrictedScreenWidth;
+                    pf.bottom = df.bottom = cf.bottom = hasNavBar
+                                          ? mDockBottom
+                                          : mUnrestrictedScreenTop+mUnrestrictedScreenHeight;
+
                 } else {
                     pf.left = df.left = cf.left = mRestrictedScreenLeft;
                     pf.top = df.top = cf.top = mRestrictedScreenTop;
@@ -1805,10 +1897,14 @@
                     vf.set(cf);
                 }
             } else if (attached != null) {
+                if (DEBUG_LAYOUT)
+                    Log.v(TAG, "layoutWindowLw(" + attrs.getTitle() + "): attached to " + attached);
                 // A child window should be placed inside of the same visible
                 // frame that its parent had.
                 setAttachedWindowFrames(win, fl, adjust, attached, false, pf, df, cf, vf);
             } else {
+                if (DEBUG_LAYOUT)
+                    Log.v(TAG, "layoutWindowLw(" + attrs.getTitle() + "): normal window");
                 // Otherwise, a normal window must be placed inside the content
                 // of all screen decorations.
                 pf.left = mContentLeft;
@@ -1844,6 +1940,8 @@
 
         if (DEBUG_LAYOUT) Log.v(TAG, "Compute frame " + attrs.getTitle()
                 + ": sim=#" + Integer.toHexString(sim)
+                + " attach=" + attached + " type=" + attrs.type 
+                + String.format(" flags=0x%08x", fl)
                 + " pf=" + pf.toShortString() + " df=" + df.toShortString()
                 + " cf=" + cf.toShortString() + " vf=" + vf.toShortString());
         
diff --git a/services/camera/libcameraservice/Android.mk b/services/camera/libcameraservice/Android.mk
index 14f1e8b..e35435e 100644
--- a/services/camera/libcameraservice/Android.mk
+++ b/services/camera/libcameraservice/Android.mk
@@ -1,38 +1,5 @@
 LOCAL_PATH:= $(call my-dir)
 
-# Set USE_CAMERA_STUB if you don't want to use the hardware camera.
-
-# force these builds to use camera stub only
-ifneq ($(filter sooner generic sim,$(TARGET_DEVICE)),)
-  USE_CAMERA_STUB:=true
-endif
-
-ifeq ($(USE_CAMERA_STUB),)
-  USE_CAMERA_STUB:=false
-endif
-
-ifeq ($(USE_CAMERA_STUB),true)
-#
-# libcamerastub
-#
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:=               \
-    CameraHardwareStub.cpp      \
-    FakeCamera.cpp
-
-LOCAL_MODULE:= libcamerastub
-
-ifeq ($(TARGET_SIMULATOR),true)
-LOCAL_CFLAGS += -DSINGLE_PROCESS
-endif
-
-LOCAL_SHARED_LIBRARIES:= libui
-
-include $(BUILD_STATIC_LIBRARY)
-endif # USE_CAMERA_STUB
-
 #
 # libcameraservice
 #
@@ -49,18 +16,9 @@
     libcutils \
     libmedia \
     libcamera_client \
-    libgui
+    libgui \
+    libhardware
 
 LOCAL_MODULE:= libcameraservice
 
-ifeq ($(TARGET_SIMULATOR),true)
-LOCAL_CFLAGS += -DSINGLE_PROCESS
-endif
-
-ifeq ($(USE_CAMERA_STUB), true)
-LOCAL_STATIC_LIBRARIES += libcamerastub
-else
-LOCAL_SHARED_LIBRARIES += libcamera 
-endif
-
 include $(BUILD_SHARED_LIBRARY)
diff --git a/services/camera/libcameraservice/CameraHardwareInterface.h b/services/camera/libcameraservice/CameraHardwareInterface.h
new file mode 100644
index 0000000..f9fa30e
--- /dev/null
+++ b/services/camera/libcameraservice/CameraHardwareInterface.h
@@ -0,0 +1,619 @@
+/*
+ * Copyright (C) 2008 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_HARDWARE_CAMERA_HARDWARE_INTERFACE_H
+#define ANDROID_HARDWARE_CAMERA_HARDWARE_INTERFACE_H
+
+#include <binder/IMemory.h>
+#include <binder/MemoryBase.h>
+#include <binder/MemoryHeapBase.h>
+#include <utils/RefBase.h>
+#include <surfaceflinger/ISurface.h>
+#include <ui/android_native_buffer.h>
+#include <ui/GraphicBuffer.h>
+#include <camera/Camera.h>
+#include <camera/CameraParameters.h>
+#include <system/window.h>
+#include <hardware/camera.h>
+
+namespace android {
+
+typedef void (*notify_callback)(int32_t msgType,
+                            int32_t ext1,
+                            int32_t ext2,
+                            void* user);
+
+typedef void (*data_callback)(int32_t msgType,
+                            const sp<IMemory> &dataPtr,
+                            void* user);
+
+typedef void (*data_callback_timestamp)(nsecs_t timestamp,
+                            int32_t msgType,
+                            const sp<IMemory> &dataPtr,
+                            void *user);
+
+/**
+ * CameraHardwareInterface.h defines the interface to the
+ * camera hardware abstraction layer, used for setting and getting
+ * parameters, live previewing, and taking pictures.
+ *
+ * It is a referenced counted interface with RefBase as its base class.
+ * CameraService calls openCameraHardware() to retrieve a strong pointer to the
+ * instance of this interface and may be called multiple times. The
+ * following steps describe a typical sequence:
+ *
+ *   -# After CameraService calls openCameraHardware(), getParameters() and
+ *      setParameters() are used to initialize the camera instance.
+ *      CameraService calls getPreviewHeap() to establish access to the
+ *      preview heap so it can be registered with SurfaceFlinger for
+ *      efficient display updating while in preview mode.
+ *   -# startPreview() is called.  The camera instance then periodically
+ *      sends the message CAMERA_MSG_PREVIEW_FRAME (if enabled) each time
+ *      a new preview frame is available.  If data callback code needs to use
+ *      this memory after returning, it must copy the data.
+ *
+ * Prior to taking a picture, CameraService calls autofocus(). When auto
+ * focusing has completed, the camera instance sends a CAMERA_MSG_FOCUS notification,
+ * which informs the application whether focusing was successful. The camera instance
+ * only sends this message once and it is up  to the application to call autoFocus()
+ * again if refocusing is desired.
+ *
+ * CameraService calls takePicture() to request the camera instance take a
+ * picture. At this point, if a shutter, postview, raw, and/or compressed callback
+ * is desired, the corresponding message must be enabled. As with CAMERA_MSG_PREVIEW_FRAME,
+ * any memory provided in a data callback must be copied if it's needed after returning.
+ */
+
+class CameraHardwareInterface : public virtual RefBase {
+public:
+    CameraHardwareInterface(hw_module_t *module, const char *name)
+    {
+        mDevice = 0;
+        mName = name;
+        LOGI("Opening camera %s, this %p", name, this);
+        int rc = module->methods->open(module, name,
+                                       (hw_device_t **)&mDevice);
+        if (rc != OK)
+            LOGE("Could not open camera %s: %d", name, rc);
+        initHalPreviewWindow();
+    }
+
+    ~CameraHardwareInterface()
+    {
+        LOGI("Destroying camera %s", mName.string());
+        int rc = mDevice->common.close(&mDevice->common);
+        if (rc != OK)
+            LOGE("Could not close camera %s: %d", mName.string(), rc);
+    }
+
+    /** Set the ANativeWindow to which preview frames are sent */
+    status_t setPreviewWindow(const sp<ANativeWindow>& buf)
+    {
+        LOGV("%s(%s) buf %p", __FUNCTION__, mName.string(), buf.get());
+
+        if (mDevice->ops->set_preview_window) {
+            mPreviewWindow = buf;
+            mHalPreviewWindow.user = this;
+            LOGV("%s &mHalPreviewWindow %p mHalPreviewWindow.user %p", __FUNCTION__,
+                    &mHalPreviewWindow, mHalPreviewWindow.user);
+            return mDevice->ops->set_preview_window(mDevice,
+                    buf.get() ? &mHalPreviewWindow.nw : 0);
+        }
+        return INVALID_OPERATION;
+    }
+
+    /** Set the notification and data callbacks */
+    void setCallbacks(notify_callback notify_cb,
+                      data_callback data_cb,
+                      data_callback_timestamp data_cb_timestamp,
+                      void* user)
+    {
+        mNotifyCb = notify_cb;
+        mDataCb = data_cb;
+        mDataCbTimestamp = data_cb_timestamp;
+        mCbUser = user;
+
+        LOGV("%s(%s)", __FUNCTION__, mName.string());
+
+        if (mDevice->ops->set_callbacks) {
+            mDevice->ops->set_callbacks(mDevice,
+                                   __notify_cb,
+                                   __data_cb,
+                                   __data_cb_timestamp,
+                                   __get_memory,
+                                   this);
+        }
+    }
+
+    /**
+     * The following three functions all take a msgtype,
+     * which is a bitmask of the messages defined in
+     * include/ui/Camera.h
+     */
+
+    /**
+     * Enable a message, or set of messages.
+     */
+    void enableMsgType(int32_t msgType)
+    {
+        LOGV("%s(%s)", __FUNCTION__, mName.string());
+        if (mDevice->ops->enable_msg_type)
+            mDevice->ops->enable_msg_type(mDevice, msgType);
+    }
+
+    /**
+     * Disable a message, or a set of messages.
+     *
+     * Once received a call to disableMsgType(CAMERA_MSG_VIDEO_FRAME), camera hal
+     * should not rely on its client to call releaseRecordingFrame() to release
+     * video recording frames sent out by the cameral hal before and after the
+     * disableMsgType(CAMERA_MSG_VIDEO_FRAME) call. Camera hal clients must not
+     * modify/access any video recording frame after calling
+     * disableMsgType(CAMERA_MSG_VIDEO_FRAME).
+     */
+    void disableMsgType(int32_t msgType)
+    {
+        LOGV("%s(%s)", __FUNCTION__, mName.string());
+        if (mDevice->ops->disable_msg_type)
+            mDevice->ops->disable_msg_type(mDevice, msgType);
+    }
+
+    /**
+     * Query whether a message, or a set of messages, is enabled.
+     * Note that this is operates as an AND, if any of the messages
+     * queried are off, this will return false.
+     */
+    int msgTypeEnabled(int32_t msgType)
+    {
+        LOGV("%s(%s)", __FUNCTION__, mName.string());
+        if (mDevice->ops->msg_type_enabled)
+            return mDevice->ops->msg_type_enabled(mDevice, msgType);
+        return false;
+    }
+
+    /**
+     * Start preview mode.
+     */
+    status_t startPreview()
+    {
+        LOGV("%s(%s)", __FUNCTION__, mName.string());
+        if (mDevice->ops->start_preview)
+            return mDevice->ops->start_preview(mDevice);
+        return INVALID_OPERATION;
+    }
+
+    /**
+     * Stop a previously started preview.
+     */
+    void stopPreview()
+    {
+        LOGV("%s(%s)", __FUNCTION__, mName.string());
+        if (mDevice->ops->stop_preview)
+            mDevice->ops->stop_preview(mDevice);
+    }
+
+    /**
+     * Returns true if preview is enabled.
+     */
+    int previewEnabled()
+    {
+        LOGV("%s(%s)", __FUNCTION__, mName.string());
+        if (mDevice->ops->preview_enabled)
+            return mDevice->ops->preview_enabled(mDevice);
+        return false;
+    }
+
+    /**
+     * Request the camera hal to store meta data or real YUV data in
+     * the video buffers send out via CAMERA_MSG_VIDEO_FRRAME for a
+     * recording session. If it is not called, the default camera
+     * hal behavior is to store real YUV data in the video buffers.
+     *
+     * This method should be called before startRecording() in order
+     * to be effective.
+     *
+     * If meta data is stored in the video buffers, it is up to the
+     * receiver of the video buffers to interpret the contents and
+     * to find the actual frame data with the help of the meta data
+     * in the buffer. How this is done is outside of the scope of
+     * this method.
+     *
+     * Some camera hal may not support storing meta data in the video
+     * buffers, but all camera hal should support storing real YUV data
+     * in the video buffers. If the camera hal does not support storing
+     * the meta data in the video buffers when it is requested to do
+     * do, INVALID_OPERATION must be returned. It is very useful for
+     * the camera hal to pass meta data rather than the actual frame
+     * data directly to the video encoder, since the amount of the
+     * uncompressed frame data can be very large if video size is large.
+     *
+     * @param enable if true to instruct the camera hal to store
+     *      meta data in the video buffers; false to instruct
+     *      the camera hal to store real YUV data in the video
+     *      buffers.
+     *
+     * @return OK on success.
+     */
+
+    status_t storeMetaDataInBuffers(int enable)
+    {
+        LOGV("%s(%s)", __FUNCTION__, mName.string());
+        if (mDevice->ops->store_meta_data_in_buffers)
+            return mDevice->ops->store_meta_data_in_buffers(mDevice, enable);
+        return enable ? INVALID_OPERATION: OK;
+    }
+
+    /**
+     * Start record mode. When a record image is available a CAMERA_MSG_VIDEO_FRAME
+     * message is sent with the corresponding frame. Every record frame must be released
+     * by a cameral hal client via releaseRecordingFrame() before the client calls
+     * disableMsgType(CAMERA_MSG_VIDEO_FRAME). After the client calls
+     * disableMsgType(CAMERA_MSG_VIDEO_FRAME), it is camera hal's responsibility
+     * to manage the life-cycle of the video recording frames, and the client must
+     * not modify/access any video recording frames.
+     */
+    status_t startRecording()
+    {
+        LOGV("%s(%s)", __FUNCTION__, mName.string());
+        if (mDevice->ops->start_recording)
+            return mDevice->ops->start_recording(mDevice);
+        return INVALID_OPERATION;
+    }
+
+    /**
+     * Stop a previously started recording.
+     */
+    void stopRecording()
+    {
+        LOGV("%s(%s)", __FUNCTION__, mName.string());
+        if (mDevice->ops->stop_recording)
+            mDevice->ops->stop_recording(mDevice);
+    }
+
+    /**
+     * Returns true if recording is enabled.
+     */
+    int recordingEnabled()
+    {
+        LOGV("%s(%s)", __FUNCTION__, mName.string());
+        if (mDevice->ops->recording_enabled)
+            return mDevice->ops->recording_enabled(mDevice);
+        return false;
+    }
+
+    /**
+     * Release a record frame previously returned by CAMERA_MSG_VIDEO_FRAME.
+     *
+     * It is camera hal client's responsibility to release video recording
+     * frames sent out by the camera hal before the camera hal receives
+     * a call to disableMsgType(CAMERA_MSG_VIDEO_FRAME). After it receives
+     * the call to disableMsgType(CAMERA_MSG_VIDEO_FRAME), it is camera hal's
+     * responsibility of managing the life-cycle of the video recording
+     * frames.
+     */
+    void releaseRecordingFrame(const sp<IMemory>& mem)
+    {
+        LOGV("%s(%s)", __FUNCTION__, mName.string());
+        if (mDevice->ops->release_recording_frame) {
+            ssize_t offset;
+            size_t size;
+            sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
+            void *data = ((uint8_t *)heap->base()) + offset;
+            return mDevice->ops->release_recording_frame(mDevice, data);
+        }
+    }
+
+    /**
+     * Start auto focus, the notification callback routine is called
+     * with CAMERA_MSG_FOCUS once when focusing is complete. autoFocus()
+     * will be called again if another auto focus is needed.
+     */
+    status_t autoFocus()
+    {
+        LOGV("%s(%s)", __FUNCTION__, mName.string());
+        if (mDevice->ops->auto_focus)
+            return mDevice->ops->auto_focus(mDevice);
+        return INVALID_OPERATION;
+    }
+
+    /**
+     * Cancels auto-focus function. If the auto-focus is still in progress,
+     * this function will cancel it. Whether the auto-focus is in progress
+     * or not, this function will return the focus position to the default.
+     * If the camera does not support auto-focus, this is a no-op.
+     */
+    status_t cancelAutoFocus()
+    {
+        LOGV("%s(%s)", __FUNCTION__, mName.string());
+        if (mDevice->ops->cancel_auto_focus)
+            return mDevice->ops->cancel_auto_focus(mDevice);
+        return INVALID_OPERATION;
+    }
+
+    /**
+     * Take a picture.
+     */
+    status_t takePicture()
+    {
+        LOGV("%s(%s)", __FUNCTION__, mName.string());
+        if (mDevice->ops->take_picture)
+            return mDevice->ops->take_picture(mDevice);
+        return INVALID_OPERATION;
+    }
+
+    /**
+     * Cancel a picture that was started with takePicture.  Calling this
+     * method when no picture is being taken is a no-op.
+     */
+    status_t cancelPicture()
+    {
+        LOGV("%s(%s)", __FUNCTION__, mName.string());
+        if (mDevice->ops->cancel_picture)
+            return mDevice->ops->cancel_picture(mDevice);
+        return INVALID_OPERATION;
+    }
+
+    /**
+     * Set the camera parameters. This returns BAD_VALUE if any parameter is
+     * invalid or not supported. */
+    status_t setParameters(const CameraParameters &params)
+    {
+        LOGV("%s(%s)", __FUNCTION__, mName.string());
+        if (mDevice->ops->set_parameters)
+            return mDevice->ops->set_parameters(mDevice,
+                                               params.flatten().string());
+        return INVALID_OPERATION;
+    }
+
+    /** Return the camera parameters. */
+    CameraParameters getParameters() const
+    {
+        LOGV("%s(%s)", __FUNCTION__, mName.string());
+        CameraParameters parms;
+        if (mDevice->ops->get_parameters) {
+            char *temp = mDevice->ops->get_parameters(mDevice);
+            String8 str_parms(temp);
+            free(temp);
+            parms.unflatten(str_parms);
+        }
+        return parms;
+    }
+
+    /**
+     * Send command to camera driver.
+     */
+    status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
+    {
+        LOGV("%s(%s)", __FUNCTION__, mName.string());
+        if (mDevice->ops->send_command)
+            return mDevice->ops->send_command(mDevice, cmd, arg1, arg2);
+        return INVALID_OPERATION;
+    }
+
+    /**
+     * Release the hardware resources owned by this object.  Note that this is
+     * *not* done in the destructor.
+     */
+    void release() {
+        LOGV("%s(%s)", __FUNCTION__, mName.string());
+        if (mDevice->ops->release)
+            mDevice->ops->release(mDevice);
+    }
+
+    /**
+     * Dump state of the camera hardware
+     */
+    status_t dump(int fd, const Vector<String16>& args) const
+    {
+        LOGV("%s(%s)", __FUNCTION__, mName.string());
+        if (mDevice->ops->dump)
+            return mDevice->ops->dump(mDevice, fd);
+        return OK; // It's fine if the HAL doesn't implement dump()
+    }
+
+private:
+    camera_device_t *mDevice;
+    String8 mName;
+
+    static void __notify_cb(int32_t msg_type, int32_t ext1,
+                            int32_t ext2, void *user)
+    {
+        LOGV("%s", __FUNCTION__);
+        CameraHardwareInterface *__this =
+                static_cast<CameraHardwareInterface *>(user);
+        __this->mNotifyCb(msg_type, ext1, ext2, __this->mCbUser);
+    }
+
+    static void __data_cb(int32_t msg_type,
+                          const camera_memory_t *data,
+                          void *user)
+    {
+        LOGV("%s", __FUNCTION__);
+        CameraHardwareInterface *__this =
+                static_cast<CameraHardwareInterface *>(user);
+        sp<CameraHeapMemory> mem(static_cast<CameraHeapMemory *>(data->handle));
+        __this->mDataCb(msg_type, mem, __this->mCbUser);
+    }
+
+    static void __data_cb_timestamp(nsecs_t timestamp, int32_t msg_type,
+                             const camera_memory_t *data,
+                             void *user)
+    {
+        LOGV("%s", __FUNCTION__);
+        CameraHardwareInterface *__this =
+                static_cast<CameraHardwareInterface *>(user);
+        // Start refcounting the heap object from here on.  When the clients
+        // drop all references, it will be destroyed (as well as the enclosed
+        // MemoryHeapBase.
+        sp<CameraHeapMemory> mem(static_cast<CameraHeapMemory *>(data->handle));
+        __this->mDataCbTimestamp(timestamp, msg_type, mem, __this->mCbUser);
+    }
+
+    // This is a utility class that combines a MemoryHeapBase and a MemoryBase
+    // in one.  Since we tend to use them in a one-to-one relationship, this is
+    // handy.
+
+    class CameraHeapMemory : public MemoryBase {
+    public:
+        CameraHeapMemory(size_t size) :
+            MemoryBase(new MemoryHeapBase(size), 0, size)
+        {
+            handle.data = getHeap()->base();
+            handle.size = size;
+            handle.handle = this;
+        }
+
+        camera_memory_t handle;
+    };
+
+    static camera_memory_t* __get_memory(size_t size,
+                                    void *user __attribute__((unused)))
+    {
+        // We allocate the object here, but we do not assign it to a strong
+        // pointer yet.  The HAL will pass it back to us via the data callback
+        // or the data-timestamp callback, and from there on we will wrap it
+        // within a strong pointer.
+
+        CameraHeapMemory *mem = new CameraHeapMemory(size);
+        return &mem->handle;
+    }
+
+    static ANativeWindow *__to_anw(void *user)
+    {
+        CameraHardwareInterface *__this =
+                reinterpret_cast<CameraHardwareInterface *>(user);
+        return __this->mPreviewWindow.get();
+    }
+#define anw(n) __to_anw(((struct camera_preview_window *)n)->user)
+
+    static int __dequeue_buffer(struct preview_stream_ops* w,
+                      buffer_handle_t** buffer)
+    {
+        int rc;
+        ANativeWindow *a = anw(w);
+        ANativeWindowBuffer* anb;
+        rc = a->dequeueBuffer(a, &anb);
+        if (!rc) {
+            rc = a->lockBuffer(a, anb);
+            if (!rc)
+                *buffer = &anb->handle;
+            else
+                a->cancelBuffer(a, anb);
+        }
+        return rc;
+    }
+
+#ifndef container_of
+#define container_of(ptr, type, member) ({                      \
+        const typeof(((type *) 0)->member) *__mptr = (ptr);     \
+        (type *) ((char *) __mptr - (char *)(&((type *)0)->member)); })
+#endif
+
+    static int __enqueue_buffer(struct preview_stream_ops* w,
+                      buffer_handle_t* buffer)
+    {
+        ANativeWindow *a = anw(w);
+        return a->queueBuffer(a,
+                  container_of(buffer, ANativeWindowBuffer, handle));
+    }
+
+    static int __cancel_buffer(struct preview_stream_ops* w,
+                      buffer_handle_t* buffer)
+    {
+        ANativeWindow *a = anw(w);
+        return a->cancelBuffer(a,
+                  container_of(buffer, ANativeWindowBuffer, handle));
+    }
+
+    static int __set_buffer_count(struct preview_stream_ops* w, int count)
+    {
+        ANativeWindow *a = anw(w);
+	return native_window_set_buffer_count(a, count);
+    }
+
+    static int __set_buffers_geometry(struct preview_stream_ops* w,
+                      int width, int height, int format)
+    {
+        ANativeWindow *a = anw(w);
+        return native_window_set_buffers_geometry(a,
+                          width, height, format);
+    }
+
+    static int __set_crop(struct preview_stream_ops *w,
+                      int left, int top, int right, int bottom)
+    {
+        ANativeWindow *a = anw(w);
+        android_native_rect_t crop;
+        crop.left = left;
+        crop.top = top;
+        crop.right = right;
+        crop.bottom = bottom;
+        return native_window_set_crop(a, &crop);
+    }
+
+    static int __set_usage(struct preview_stream_ops* w, int usage)
+    {
+        ANativeWindow *a = anw(w);
+        return native_window_set_usage(a, usage);
+    }
+
+    static int __set_swap_interval(struct preview_stream_ops *w, int interval)
+    {
+        ANativeWindow *a = anw(w);
+        return a->setSwapInterval(a, interval);
+    }
+
+    static int __get_min_undequeued_buffer_count(
+                      const struct preview_stream_ops *w,
+                      int *count)
+    {
+        ANativeWindow *a = anw(w);
+        return a->query(a, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, count);
+    }
+
+    void initHalPreviewWindow()
+    {
+        mHalPreviewWindow.nw.cancel_buffer = __cancel_buffer;
+        mHalPreviewWindow.nw.dequeue_buffer = __dequeue_buffer;
+        mHalPreviewWindow.nw.enqueue_buffer = __enqueue_buffer;
+        mHalPreviewWindow.nw.set_buffer_count = __set_buffer_count;
+        mHalPreviewWindow.nw.set_buffers_geometry = __set_buffers_geometry;
+        mHalPreviewWindow.nw.set_crop = __set_crop;
+        mHalPreviewWindow.nw.set_usage = __set_usage;
+        mHalPreviewWindow.nw.set_swap_interval = __set_swap_interval;
+
+        mHalPreviewWindow.nw.get_min_undequeued_buffer_count =
+                __get_min_undequeued_buffer_count;
+    }
+
+    sp<ANativeWindow>        mPreviewWindow;
+
+    struct camera_preview_window {
+        struct preview_stream_ops nw;
+        void *user;
+    };
+
+    struct camera_preview_window mHalPreviewWindow;
+
+    notify_callback         mNotifyCb;
+    data_callback           mDataCb;
+    data_callback_timestamp mDataCbTimestamp;
+    void *mCbUser;
+};
+
+};  // namespace android
+
+#endif
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index f4859ec..1e8c30b 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -16,6 +16,7 @@
 */
 
 #define LOG_TAG "CameraService"
+//#define LOG_NDEBUG 0
 
 #include <stdio.h>
 #include <sys/types.h>
@@ -37,6 +38,7 @@
 #include <utils/String16.h>
 
 #include "CameraService.h"
+#include "CameraHardwareInterface.h"
 
 namespace android {
 
@@ -69,24 +71,34 @@
 static CameraService *gCameraService;
 
 CameraService::CameraService()
-:mSoundRef(0)
+:mSoundRef(0), mModule(0)
 {
     LOGI("CameraService started (pid=%d)", getpid());
-
-    mNumberOfCameras = HAL_getNumberOfCameras();
-    if (mNumberOfCameras > MAX_CAMERAS) {
-        LOGE("Number of cameras(%d) > MAX_CAMERAS(%d).",
-             mNumberOfCameras, MAX_CAMERAS);
-        mNumberOfCameras = MAX_CAMERAS;
-    }
-
-    for (int i = 0; i < mNumberOfCameras; i++) {
-        setCameraFree(i);
-    }
-
     gCameraService = this;
 }
 
+void CameraService::onFirstRef()
+{
+    BnCameraService::onFirstRef();
+
+    if (hw_get_module(CAMERA_HARDWARE_MODULE_ID,
+                (const hw_module_t **)&mModule) < 0) {
+        LOGE("Could not load camera HAL module");
+        mNumberOfCameras = 0;
+    }
+    else {
+        mNumberOfCameras = mModule->get_number_of_cameras();
+        if (mNumberOfCameras > MAX_CAMERAS) {
+            LOGE("Number of cameras(%d) > MAX_CAMERAS(%d).",
+                    mNumberOfCameras, MAX_CAMERAS);
+            mNumberOfCameras = MAX_CAMERAS;
+        }
+        for (int i = 0; i < mNumberOfCameras; i++) {
+            setCameraFree(i);
+        }
+    }
+}
+
 CameraService::~CameraService() {
     for (int i = 0; i < mNumberOfCameras; i++) {
         if (mBusy[i]) {
@@ -103,12 +115,19 @@
 
 status_t CameraService::getCameraInfo(int cameraId,
                                       struct CameraInfo* cameraInfo) {
+    if (!mModule) {
+        return NO_INIT;
+    }
+
     if (cameraId < 0 || cameraId >= mNumberOfCameras) {
         return BAD_VALUE;
     }
 
-    HAL_getCameraInfo(cameraId, cameraInfo);
-    return OK;
+    struct camera_info info;
+    status_t rc = mModule->get_camera_info(cameraId, &info);
+    cameraInfo->facing = info.facing;
+    cameraInfo->orientation = info.orientation;
+    return rc;
 }
 
 sp<ICamera> CameraService::connect(
@@ -116,6 +135,11 @@
     int callingPid = getCallingPid();
     LOG1("CameraService::connect E (pid %d, id %d)", callingPid, cameraId);
 
+    if (!mModule) {
+        LOGE("Camera HAL module not loaded");
+        return NULL;
+    }
+
     sp<Client> client;
     if (cameraId < 0 || cameraId >= mNumberOfCameras) {
         LOGE("CameraService::connect X (pid %d) rejected (invalid cameraId %d).",
@@ -146,15 +170,19 @@
         return NULL;
     }
 
-    sp<CameraHardwareInterface> hardware = HAL_openCameraHardware(cameraId);
-    if (hardware == NULL) {
-        LOGE("Fail to open camera hardware (id=%d)", cameraId);
+    struct camera_info info;
+    if (mModule->get_camera_info(cameraId, &info) != OK) {
+        LOGE("Invalid camera id %d", cameraId);
         return NULL;
     }
-    CameraInfo info;
-    HAL_getCameraInfo(cameraId, &info);
-    client = new Client(this, cameraClient, hardware, cameraId, info.facing,
-                        callingPid);
+
+    char camera_device_name[10];
+    snprintf(camera_device_name, sizeof(camera_device_name), "%d", cameraId);
+
+    client = new Client(this, cameraClient,
+                new CameraHardwareInterface(&mModule->common,
+                                            camera_device_name),
+                cameraId, info.facing, callingPid);
     mClient[cameraId] = client;
     LOG1("CameraService::connect X");
     return client;
@@ -320,7 +348,7 @@
                   CAMERA_MSG_FOCUS);
 
     // Callback is disabled by default
-    mPreviewCallbackFlag = FRAME_CALLBACK_FLAG_NOOP;
+    mPreviewCallbackFlag = CAMERA_FRAME_CALLBACK_FLAG_NOOP;
     mOrientation = getOrientation(0, mCameraFacing == CAMERA_FACING_FRONT);
     mPlayShutterSound = true;
     cameraService->setCameraBusy(cameraId);
@@ -410,7 +438,7 @@
         return NO_ERROR;
     }
 
-    mPreviewCallbackFlag = FRAME_CALLBACK_FLAG_NOOP;
+    mPreviewCallbackFlag = CAMERA_FRAME_CALLBACK_FLAG_NOOP;
     mClientPid = callingPid;
     mCameraClient = client;
 
@@ -543,7 +571,7 @@
     if (checkPidAndHardware() != NO_ERROR) return;
 
     mPreviewCallbackFlag = callback_flag;
-    if (mPreviewCallbackFlag & FRAME_CALLBACK_FLAG_ENABLE_MASK) {
+    if (mPreviewCallbackFlag & CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) {
         enableMsgType(CAMERA_MSG_PREVIEW_FRAME);
     } else {
         disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
@@ -1009,7 +1037,7 @@
     int flags = mPreviewCallbackFlag;
 
     // is callback enabled?
-    if (!(flags & FRAME_CALLBACK_FLAG_ENABLE_MASK)) {
+    if (!(flags & CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK)) {
         // If the enable bit is off, the copy-out and one-shot bits are ignored
         LOG2("frame callback is disabled");
         mLock.unlock();
@@ -1020,17 +1048,17 @@
     sp<ICameraClient> c = mCameraClient;
 
     // clear callback flags if no client or one-shot mode
-    if (c == 0 || (mPreviewCallbackFlag & FRAME_CALLBACK_FLAG_ONE_SHOT_MASK)) {
+    if (c == 0 || (mPreviewCallbackFlag & CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK)) {
         LOG2("Disable preview callback");
-        mPreviewCallbackFlag &= ~(FRAME_CALLBACK_FLAG_ONE_SHOT_MASK |
-                                  FRAME_CALLBACK_FLAG_COPY_OUT_MASK |
-                                  FRAME_CALLBACK_FLAG_ENABLE_MASK);
+        mPreviewCallbackFlag &= ~(CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK |
+                                  CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK |
+                                  CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK);
         disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
     }
 
     if (c != 0) {
         // Is the received frame copied out or not?
-        if (flags & FRAME_CALLBACK_FLAG_COPY_OUT_MASK) {
+        if (flags & CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK) {
             LOG2("frame is copied");
             copyFrameAndPostCopiedFrame(c, heap, offset, size);
         } else {
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 9a9ab0e..5e2d571 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -19,9 +19,8 @@
 #define ANDROID_SERVERS_CAMERA_CAMERASERVICE_H
 
 #include <binder/BinderService.h>
-
 #include <camera/ICameraService.h>
-#include <camera/CameraHardwareInterface.h>
+#include <hardware/camera.h>
 
 /* This needs to be increased if we can have more cameras */
 #define MAX_CAMERAS 2
@@ -30,6 +29,7 @@
 
 class MemoryHeapBase;
 class MediaPlayer;
+class CameraHardwareInterface;
 
 class CameraService :
     public BinderService<CameraService>,
@@ -53,6 +53,7 @@
     virtual status_t    dump(int fd, const Vector<String16>& args);
     virtual status_t    onTransact(uint32_t code, const Parcel& data,
                                    Parcel* reply, uint32_t flags);
+    virtual void onFirstRef();
 
     enum sound_kind {
         SOUND_SHUTTER = 0,
@@ -199,6 +200,8 @@
         // is found to be disabled. It returns true if mLock is grabbed.
         bool                    lockIfMessageWanted(int32_t msgType);
     };
+
+    camera_module_t *mModule;
 };
 
 } // namespace android
diff --git a/services/camera/tests/CameraServiceTest/CameraServiceTest.cpp b/services/camera/tests/CameraServiceTest/CameraServiceTest.cpp
index 8a228fd..f86ca47 100644
--- a/services/camera/tests/CameraServiceTest/CameraServiceTest.cpp
+++ b/services/camera/tests/CameraServiceTest/CameraServiceTest.cpp
@@ -830,10 +830,10 @@
             ASSERT(c->previewEnabled() == true);
             sleep(2);
             c->stopPreview();
-            if ((v & FRAME_CALLBACK_FLAG_ENABLE_MASK) == 0) {
+            if ((v & CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) == 0) {
                 cc->assertData(CAMERA_MSG_PREVIEW_FRAME, MCameraClient::EQ, 0);
             } else {
-                if ((v & FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) == 0) {
+                if ((v & CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) == 0) {
                     cc->assertData(CAMERA_MSG_PREVIEW_FRAME, MCameraClient::GE, 10);
                 } else {
                     cc->assertData(CAMERA_MSG_PREVIEW_FRAME, MCameraClient::EQ, 1);
@@ -849,7 +849,7 @@
         ASSERT(c->recordingEnabled() == false);
         sp<MSurface> surface = new MSurface();
         ASSERT(c->setPreviewDisplay(surface) == NO_ERROR);
-        c->setPreviewCallbackFlag(FRAME_CALLBACK_FLAG_ENABLE_MASK);
+        c->setPreviewCallbackFlag(CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK);
         cc->setReleaser(c.get());
         c->startRecording();
         ASSERT(c->recordingEnabled() == true);
@@ -870,7 +870,7 @@
 
         CameraParameters param(c->getParameters());
         param.setPreviewSize(w, h);
-        c->setPreviewCallbackFlag(FRAME_CALLBACK_FLAG_ENABLE_MASK);
+        c->setPreviewCallbackFlag(CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK);
         c->setParameters(param.flatten());
 
         c->startPreview();
diff --git a/services/input/InputWindow.h b/services/input/InputWindow.h
index f04fb02..208353d 100644
--- a/services/input/InputWindow.h
+++ b/services/input/InputWindow.h
@@ -119,6 +119,7 @@
         TYPE_DRAG               = FIRST_SYSTEM_WINDOW+16,
         TYPE_STATUS_BAR_SUB_PANEL  = FIRST_SYSTEM_WINDOW+17,
         TYPE_POINTER            = FIRST_SYSTEM_WINDOW+18,
+        TYPE_NAVIGATION_BAR     = FIRST_SYSTEM_WINDOW+19,
         LAST_SYSTEM_WINDOW      = 2999,
     };
 
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 7506f29..e8f0328 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -395,7 +395,7 @@
     if (LIKELY(mTransactionCount == 0)) {
         // if we're in a global transaction, don't do anything.
         const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
-        uint32_t transactionFlags = getTransactionFlags(mask);
+        uint32_t transactionFlags = peekTransactionFlags(mask);
         if (LIKELY(transactionFlags)) {
             handleTransaction(transactionFlags);
         }
@@ -490,7 +490,17 @@
         Mutex::Autolock _l(mStateLock);
         const nsecs_t now = systemTime();
         mDebugInTransaction = now;
+
+        // Here we're guaranteed that some transaction flags are set
+        // so we can call handleTransactionLocked() unconditionally.
+        // We call getTransactionFlags(), which will also clear the flags,
+        // with mStateLock held to guarantee that mCurrentState won't change
+        // until the transaction is commited.
+
+        const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
+        transactionFlags = getTransactionFlags(mask);
         handleTransactionLocked(transactionFlags, ditchedLayers);
+
         mLastTransactionTime = systemTime() - now;
         mDebugInTransaction = 0;
         invalidateHwcGeometry();
@@ -1094,15 +1104,15 @@
 ssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
         const sp<LayerBaseClient>& lbc)
 {
-    Mutex::Autolock _l(mStateLock);
-
     // attach this layer to the client
-    ssize_t name = client->attachLayer(lbc);
+    size_t name = client->attachLayer(lbc);
+
+    Mutex::Autolock _l(mStateLock);
 
     // add this layer to the current state list
     addLayer_l(lbc);
 
-    return name;
+    return ssize_t(name);
 }
 
 status_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
@@ -1153,6 +1163,11 @@
     return NO_ERROR;
 }
 
+uint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags)
+{
+    return android_atomic_release_load(&mTransactionFlags);
+}
+
 uint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
 {
     return android_atomic_and(~flags, &mTransactionFlags) & flags;
@@ -2381,15 +2396,17 @@
     return NO_ERROR;
 }
 
-ssize_t Client::attachLayer(const sp<LayerBaseClient>& layer)
+size_t Client::attachLayer(const sp<LayerBaseClient>& layer)
 {
-    int32_t name = android_atomic_inc(&mNameGenerator);
+    Mutex::Autolock _l(mLock);
+    size_t name = mNameGenerator++;
     mLayers.add(name, layer);
     return name;
 }
 
 void Client::detachLayer(const LayerBaseClient* layer)
 {
+    Mutex::Autolock _l(mLock);
     // we do a linear search here, because this doesn't happen often
     const size_t count = mLayers.size();
     for (size_t i=0 ; i<count ; i++) {
@@ -2399,9 +2416,11 @@
         }
     }
 }
-sp<LayerBaseClient> Client::getLayerUser(int32_t i) const {
+sp<LayerBaseClient> Client::getLayerUser(int32_t i) const
+{
+    Mutex::Autolock _l(mLock);
     sp<LayerBaseClient> lbc;
-    const wp<LayerBaseClient>& layer(mLayers.valueFor(i));
+    wp<LayerBaseClient> layer(mLayers.valueFor(i));
     if (layer != 0) {
         lbc = layer.promote();
         LOGE_IF(lbc==0, "getLayerUser(name=%d) is dead", int(i));
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 1b36d1c..1e16943 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -65,7 +65,7 @@
     status_t initCheck() const;
 
     // protected by SurfaceFlinger::mStateLock
-    ssize_t attachLayer(const sp<LayerBaseClient>& layer);
+    size_t attachLayer(const sp<LayerBaseClient>& layer);
     void detachLayer(const LayerBaseClient* layer);
     sp<LayerBaseClient> getLayerUser(int32_t i) const;
 
@@ -81,9 +81,15 @@
     virtual status_t destroySurface(SurfaceID surfaceId);
     virtual status_t setState(int32_t count, const layer_state_t* states);
 
-    DefaultKeyedVector< size_t, wp<LayerBaseClient> > mLayers;
+    // constant
     sp<SurfaceFlinger> mFlinger;
-    int32_t mNameGenerator;
+
+    // protected by mLock
+    DefaultKeyedVector< size_t, wp<LayerBaseClient> > mLayers;
+    size_t mNameGenerator;
+
+    // thread-safe
+    mutable Mutex mLock;
 };
 
 class UserClient : public BnSurfaceComposerClient
@@ -319,6 +325,7 @@
             status_t    purgatorizeLayer_l(const sp<LayerBase>& layer);
 
             uint32_t    getTransactionFlags(uint32_t flags);
+            uint32_t    peekTransactionFlags(uint32_t flags);
             uint32_t    setTransactionFlags(uint32_t flags);
             void        commitTransaction();
 
diff --git a/services/surfaceflinger/TextureManager.cpp b/services/surfaceflinger/TextureManager.cpp
index 9e24f90..bb63c37 100644
--- a/services/surfaceflinger/TextureManager.cpp
+++ b/services/surfaceflinger/TextureManager.cpp
@@ -144,7 +144,7 @@
     }
 
     // construct an EGL_NATIVE_BUFFER_ANDROID
-    android_native_buffer_t* clientBuf = buffer->getNativeBuffer();
+    ANativeWindowBuffer* clientBuf = buffer->getNativeBuffer();
 
     // create the new EGLImageKHR
     const EGLint attrs[] = {
diff --git a/services/surfaceflinger/tests/surface/surface.cpp b/services/surfaceflinger/tests/surface/surface.cpp
index 67ecf7e..5265f91 100644
--- a/services/surfaceflinger/tests/surface/surface.cpp
+++ b/services/surfaceflinger/tests/surface/surface.cpp
@@ -53,7 +53,7 @@
     printf("window=%p\n", window);
 
     int err = native_window_set_buffer_count(window, 8);
-    android_native_buffer_t* buffer;
+    ANativeWindowBuffer* buffer;
 
     for (int i=0 ; i<8 ; i++) {
         window->dequeueBuffer(window, &buffer);
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/threshold.rs b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/threshold.rs
index f2f9a36..16ebe08 100644
--- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/threshold.rs
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/threshold.rs
@@ -63,7 +63,7 @@
 
 static void copyInput() {
     rs_allocation ain;
-    rsSetObject(&ain,rsGetAllocation(InPixel));
+    ain = rsGetAllocation(InPixel);
     uint32_t dimx = rsAllocationGetDimX(ain);
     uint32_t dimy = rsAllocationGetDimY(ain);
     for (uint32_t y = 0; y < dimy; y++) {
diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs
index 3fc59fc..91bac88 100644
--- a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs
+++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs
@@ -109,11 +109,11 @@
 static void displayFontSamples(int fillNum) {
 
     rs_font fonts[5];
-    rsSetObject(&fonts[0], gFontSans);
-    rsSetObject(&fonts[1], gFontSerif);
-    rsSetObject(&fonts[2], gFontSerifBold);
-    rsSetObject(&fonts[3], gFontSerifBoldItalic);
-    rsSetObject(&fonts[4], gFontSans);
+    fonts[0] = gFontSans;
+    fonts[1] = gFontSerif;
+    fonts[2] = gFontSerifBold;
+    fonts[3] = gFontSerifBoldItalic;
+    fonts[4] = gFontSans;
 
     uint width = gRenderSurfaceW;
     uint height = gRenderSurfaceH;
@@ -140,10 +140,6 @@
             }
         }
     }
-
-    for (int i = 0; i < 5; i ++) {
-        rsClearObject(&fonts[i]);
-    }
 }
 
 static void bindProgramVertexOrtho() {
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/rslist.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/rslist.rs
index aeae13f..d8663fb 100644
--- a/tests/RenderScriptTests/tests/src/com/android/rs/test/rslist.rs
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/rslist.rs
@@ -47,7 +47,7 @@
     rsgBindFont(gFont);
 
     rs_allocation listAlloc;
-    rsSetObject(&listAlloc, rsGetAllocation(gList));
+    listAlloc = rsGetAllocation(gList);
     int allocSize = rsAllocationGetDimX(listAlloc);
 
     int width = rsgGetWidth();
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/rstypes.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/rstypes.rs
index f3bf244..22d9c13 100644
--- a/tests/RenderScriptTests/tests/src/com/android/rs/test/rstypes.rs
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/rstypes.rs
@@ -48,17 +48,17 @@
 
     struct my_struct structTest;
 
-    rsSetObject(&fontTestLocal, fontTest);
+    fontTestLocal = fontTest;
     //allocationTestLocal = allocationTest;
 
-    rsSetObject(&fontTest, fontTestLocal);
+    fontTest = fontTestLocal;
     //allocationTest = allocationTestLocal;
 
     /*for (int i = 0; i < 4; i++) {
-        rsSetObject(&fontTestLocalArray[i], fontTestLocal);
+        fontTestLocalArray[i] = fontTestLocal;
     }*/
 
-    /*rsSetObject(&fontTest, fontTestLocalArray[3]);*/
+    /*fontTest = fontTestLocalArray[3];*/
 
     return failed;
 }