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(θ/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 ¶ms)
+ {
+ 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;
}