Merge changes 9415,9416
* changes:
log opengl-call-with-no-context only once per thread, instead of for each function call
don't crash in Parcel when given a null (and therfore invalid) native_handle_t
diff --git a/core/java/android/bluetooth/BluetoothUuid.java b/core/java/android/bluetooth/BluetoothUuid.java
index f8316a5..1ec7fb38 100644
--- a/core/java/android/bluetooth/BluetoothUuid.java
+++ b/core/java/android/bluetooth/BluetoothUuid.java
@@ -30,14 +30,13 @@
* The following 128 bit values are calculated as:
* uuid * 2^96 + BASE_UUID
*/
- public static final UUID AudioSink = UUID.fromString("0000110A-0000-1000-8000-00805F9B34FB");
- public static final UUID AudioSource = UUID.fromString("0000110B-0000-1000-8000-00805F9B34FB");
+ public static final UUID AudioSink = UUID.fromString("0000110B-0000-1000-8000-00805F9B34FB");
+ public static final UUID AudioSource = UUID.fromString("0000110A-0000-1000-8000-00805F9B34FB");
public static final UUID AdvAudioDist = UUID.fromString("0000110D-0000-1000-8000-00805F9B34FB");
public static final UUID HSP = UUID.fromString("00001108-0000-1000-8000-00805F9B34FB");
- public static final UUID HeadsetHS = UUID.fromString("00001131-0000-1000-8000-00805F9B34FB");
- public static final UUID Handsfree = UUID.fromString("0000111e-0000-1000-8000-00805F9B34FB");
- public static final UUID HandsfreeAudioGateway
- = UUID.fromString("0000111f-0000-1000-8000-00805F9B34FB");
+ public static final UUID Handsfree = UUID.fromString("0000111E-0000-1000-8000-00805F9B34FB");
+ public static final UUID AvrcpController =
+ UUID.fromString("0000110E-0000-1000-8000-00805F9B34FB");
public static boolean isAudioSource(UUID uuid) {
return uuid.equals(AudioSource);
@@ -56,7 +55,10 @@
}
public static boolean isHeadset(UUID uuid) {
- return uuid.equals(HSP) || uuid.equals(HeadsetHS);
+ return uuid.equals(HSP);
+ }
+
+ public static boolean isAvrcpController(UUID uuid) {
+ return uuid.equals(AvrcpController);
}
}
-
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index dc84d1f..d982777 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -402,13 +402,14 @@
boolean authorized = false;
UUID uuid = UUID.fromString(deviceUuid);
- if (mBluetoothService.isEnabled() && BluetoothUuid.isAudioSink(uuid)) {
+ if (mBluetoothService.isEnabled() &&
+ (BluetoothUuid.isAudioSink(uuid) || BluetoothUuid.isAvrcpController(uuid))) {
BluetoothA2dp a2dp = new BluetoothA2dp(mContext);
authorized = a2dp.getSinkPriority(address) > BluetoothA2dp.PRIORITY_OFF;
if (authorized) {
- Log.i(TAG, "Allowing incoming A2DP connection from " + address);
+ Log.i(TAG, "Allowing incoming A2DP / AVRCP connection from " + address);
} else {
- Log.i(TAG, "Rejecting incoming A2DP connection from " + address);
+ Log.i(TAG, "Rejecting incoming A2DP / AVRCP connection from " + address);
}
} else {
Log.i(TAG, "Rejecting incoming " + deviceUuid + " connection from " + address);
diff --git a/core/java/android/webkit/WebTextView.java b/core/java/android/webkit/WebTextView.java
index 7bc154b..f22adb7 100644
--- a/core/java/android/webkit/WebTextView.java
+++ b/core/java/android/webkit/WebTextView.java
@@ -81,6 +81,10 @@
// True if the most recent drag event has caused either the TextView to
// scroll or the web page to scroll. Gets reset after a touch down.
private boolean mScrolled;
+ // Gets set to true when the the IME jumps to the next textfield. When this
+ // happens, the next time the user hits a key it is okay for the focus
+ // pointer to not match the WebTextView's node pointer
+ private boolean mOkayForFocusNotToMatch;
// Array to store the final character added in onTextChanged, so that its
// KeyEvents may be determined.
private char[] mCharacter = new char[1];
@@ -99,7 +103,6 @@
super(context);
mWebView = webView;
mMaxLength = -1;
- setImeOptions(EditorInfo.IME_ACTION_NONE);
}
@Override
@@ -125,8 +128,8 @@
isArrowKey = true;
break;
}
-
- if (!isArrowKey && mWebView.nativeFocusNodePointer() != mNodePointer) {
+ if (!isArrowKey && !mOkayForFocusNotToMatch
+ && mWebView.nativeFocusNodePointer() != mNodePointer) {
mWebView.nativeClearCursor();
// Do not call remove() here, which hides the soft keyboard. If
// the soft keyboard is being displayed, the user will still want
@@ -135,6 +138,9 @@
mWebView.requestFocus();
return mWebView.dispatchKeyEvent(event);
}
+ // After a jump to next textfield and the first key press, the cursor
+ // and focus will once again match, so reset this value.
+ mOkayForFocusNotToMatch = false;
Spannable text = (Spannable) getText();
int oldLength = text.length();
@@ -305,6 +311,36 @@
}
@Override
+ public void onEditorAction(int actionCode) {
+ switch (actionCode) {
+ case EditorInfo.IME_ACTION_NEXT:
+ mWebView.nativeMoveCursorToNextTextInput();
+ // Preemptively rebuild the WebTextView, so that the action will
+ // be set properly.
+ mWebView.rebuildWebTextView();
+ // Since the cursor will no longer be in the same place as the
+ // focus, set the focus controller back to inactive
+ mWebView.setFocusControllerInactive();
+ mOkayForFocusNotToMatch = true;
+ break;
+ case EditorInfo.IME_ACTION_DONE:
+ super.onEditorAction(actionCode);
+ break;
+ case EditorInfo.IME_ACTION_GO:
+ // Send an enter and hide the soft keyboard
+ InputMethodManager.getInstance(mContext)
+ .hideSoftInputFromWindow(getWindowToken(), 0);
+ sendDomEvent(new KeyEvent(KeyEvent.ACTION_DOWN,
+ KeyEvent.KEYCODE_ENTER));
+ sendDomEvent(new KeyEvent(KeyEvent.ACTION_UP,
+ KeyEvent.KEYCODE_ENTER));
+
+ default:
+ break;
+ }
+ }
+
+ @Override
protected void onSelectionChanged(int selStart, int selEnd) {
if (mWebView != null) {
if (DebugFlags.WEB_TEXT_VIEW) {
@@ -659,10 +695,26 @@
public void setSingleLine(boolean single) {
int inputType = EditorInfo.TYPE_CLASS_TEXT
| EditorInfo.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT;
- if (!single) {
+ if (single) {
+ int action = mWebView.nativeTextFieldAction();
+ switch (action) {
+ // Keep in sync with CachedRoot::ImeAction
+ case 0: // NEXT
+ setImeOptions(EditorInfo.IME_ACTION_NEXT);
+ break;
+ case 1: // GO
+ setImeOptions(EditorInfo.IME_ACTION_GO);
+ break;
+ case -1: // FAILURE
+ case 2: // DONE
+ setImeOptions(EditorInfo.IME_ACTION_DONE);
+ break;
+ }
+ } else {
inputType |= EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE
| EditorInfo.TYPE_TEXT_FLAG_CAP_SENTENCES
| EditorInfo.TYPE_TEXT_FLAG_AUTO_CORRECT;
+ setImeOptions(EditorInfo.IME_ACTION_NONE);
}
mSingle = single;
setHorizontallyScrolling(single);
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 05a7806..3b81eed 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -2292,13 +2292,13 @@
// Scale from content to view coordinates, and pin.
// Also called by jni webview.cpp
- private void setContentScrollBy(int cx, int cy, boolean animate) {
+ private boolean setContentScrollBy(int cx, int cy, boolean animate) {
if (mDrawHistory) {
// disallow WebView to change the scroll position as History Picture
// is used in the view system.
// TODO: as we switchOutDrawHistory when trackball or navigation
// keys are hit, this should be safe. Right?
- return;
+ return false;
}
cx = contentToView(cx);
cy = contentToView(cy);
@@ -2315,11 +2315,9 @@
// FIXME: Why do we only scroll horizontally if there is no
// vertical scroll?
// Log.d(LOGTAG, "setContentScrollBy cy=" + cy);
- if (cy == 0 && cx != 0) {
- pinScrollBy(cx, 0, animate, 0);
- }
+ return cy == 0 && cx != 0 && pinScrollBy(cx, 0, animate, 0);
} else {
- pinScrollBy(cx, cy, animate, 0);
+ return pinScrollBy(cx, cy, animate, 0);
}
}
@@ -3123,7 +3121,7 @@
* mWebTextView to have the appropriate properties, such as password,
* multiline, and what text it contains. It also removes it if necessary.
*/
- private void rebuildWebTextView() {
+ /* package */ void rebuildWebTextView() {
// If the WebView does not have focus, do nothing until it gains focus.
if (!hasFocus() && (null == mWebTextView || !mWebTextView.hasFocus())
|| (mTouchMode >= FIRST_SCROLL_ZOOM
@@ -3385,7 +3383,8 @@
} else if (nativeCursorIsTextInput()) {
// This message will put the node in focus, for the DOM's notion
// of focus, and make the focuscontroller active
- mWebViewCore.sendMessage(EventHub.CLICK);
+ mWebViewCore.sendMessage(EventHub.CLICK, nativeCursorFramePointer(),
+ nativeCursorNodePointer());
// This will bring up the WebTextView and put it in focus, for
// our view system's notion of focus
rebuildWebTextView();
@@ -3626,7 +3625,7 @@
* not draw the blinking cursor. It gets set to "active" to draw the cursor
* in WebViewCore.cpp, when the WebCore thread receives key events/clicks.
*/
- private void setFocusControllerInactive() {
+ /* package */ void setFocusControllerInactive() {
// Do not need to also check whether mWebViewCore is null, because
// mNativeClass is only set if mWebViewCore is non null
if (mNativeClass == 0) return;
@@ -3813,6 +3812,8 @@
} else {
mTouchMode = TOUCH_INIT_MODE;
mPreventDrag = mForwardTouchEvents;
+ mWebViewCore.sendMessage(
+ EventHub.UPDATE_FRAME_CACHE_IF_LOADING);
if (mLogEvent && eventTime - mLastTouchUpTime < 1000) {
EventLog.writeEvent(EVENT_LOG_DOUBLE_TAP_DURATION,
(eventTime - mLastTouchUpTime), eventTime);
@@ -3983,6 +3984,7 @@
switch (mTouchMode) {
case TOUCH_DOUBLE_TAP_MODE: // double tap
mPrivateHandler.removeMessages(SWITCH_TO_SHORTPRESS);
+ mTouchMode = TOUCH_DONE_MODE;
doDoubleTap();
break;
case TOUCH_INIT_MODE: // tap
@@ -4680,7 +4682,7 @@
// mLastTouchX and mLastTouchY are the point in the current viewport
int contentX = viewToContent((int) mLastTouchX + mScrollX);
int contentY = viewToContent((int) mLastTouchY + mScrollY);
- int left = nativeGetBlockLeftEdge(contentX, contentY);
+ int left = nativeGetBlockLeftEdge(contentX, contentY, mActualScale);
if (left != NO_LEFTEDGE) {
// add a 5pt padding to the left edge. Re-calculate the zoom
// center so that the new scroll x will be on the left edge.
@@ -5627,6 +5629,7 @@
private native void nativeHideCursor();
private native String nativeImageURI(int x, int y);
private native void nativeInstrumentReport();
+ /* package */ native void nativeMoveCursorToNextTextInput();
// return true if the page has been scrolled
private native boolean nativeMotionUp(int x, int y, int slop);
// returns false if it handled the key
@@ -5644,6 +5647,8 @@
private native void nativeSetFindIsDown();
private native void nativeSetFollowedLink(boolean followed);
private native void nativeSetHeightCanMeasure(boolean measure);
+ // Returns a value corresponding to CachedFrame::ImeAction
+ /* package */ native int nativeTextFieldAction();
private native int nativeTextGeneration();
// Never call this version except by updateCachedTextfield(String) -
// we always want to pass in our generation number.
@@ -5652,5 +5657,5 @@
private native void nativeUpdatePluginReceivesEvents();
// return NO_LEFTEDGE means failure.
private static final int NO_LEFTEDGE = -1;
- private native int nativeGetBlockLeftEdge(int x, int y);
+ private native int nativeGetBlockLeftEdge(int x, int y, float scale);
}
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 8ec8174..2f9e153 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -648,6 +648,7 @@
}
static final String[] HandlerDebugString = {
+ "UPDATE_FRAME_CACHE_IF_LOADING", // = 98
"SCROLL_TEXT_INPUT", // = 99
"LOAD_URL", // = 100;
"STOP_LOADING", // = 101;
@@ -699,6 +700,7 @@
class EventHub {
// Message Ids
+ static final int UPDATE_FRAME_CACHE_IF_LOADING = 98;
static final int SCROLL_TEXT_INPUT = 99;
static final int LOAD_URL = 100;
static final int STOP_LOADING = 101;
@@ -805,10 +807,11 @@
@Override
public void handleMessage(Message msg) {
if (DebugFlags.WEB_VIEW_CORE) {
- Log.v(LOGTAG, (msg.what < SCROLL_TEXT_INPUT || msg.what
+ Log.v(LOGTAG, (msg.what < UPDATE_FRAME_CACHE_IF_LOADING
+ || msg.what
> FREE_MEMORY ? Integer.toString(msg.what)
: HandlerDebugString[msg.what
- - SCROLL_TEXT_INPUT])
+ - UPDATE_FRAME_CACHE_IF_LOADING])
+ " arg1=" + msg.arg1 + " arg2=" + msg.arg2
+ " obj=" + msg.obj);
}
@@ -825,6 +828,10 @@
mNativeClass = 0;
break;
+ case UPDATE_FRAME_CACHE_IF_LOADING:
+ nativeUpdateFrameCacheIfLoading();
+ break;
+
case SCROLL_TEXT_INPUT:
nativeScrollFocusedTextInput(msg.arg1, msg.arg2);
break;
@@ -1938,6 +1945,8 @@
WebView.CLEAR_TEXT_ENTRY).sendToTarget();
}
+ private native void nativeUpdateFrameCacheIfLoading();
+
/**
* Scroll the focused textfield to (x, y) in document space
*/
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index 6a9bcfb..b8f0a7e 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -463,6 +463,7 @@
if (matrix == null && !mMatrix.isIdentity() ||
matrix != null && !mMatrix.equals(matrix)) {
mMatrix.set(matrix);
+ configureBounds();
invalidate();
}
}
diff --git a/core/res/res/layout/preference_dialog.xml b/core/res/res/layout/preference_dialog.xml
new file mode 100644
index 0000000..5cf0f6e
--- /dev/null
+++ b/core/res/res/layout/preference_dialog.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2006 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.
+-->
+
+<!-- Layout used by DialogPreference widgets. This is inflated inside
+ android.R.layout.preference. -->
+<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginRight="4dip"
+ android:layout_gravity="center_vertical"
+ android:background="@drawable/btn_circle"
+ android:src="@drawable/ic_btn_round_more" />
+
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 6df8b0a..4aa4210 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -659,12 +659,12 @@
</style>
<style name="Preference.PreferenceScreen">
- <item name="android:widgetLayout">@android:layout/preferences</item>
</style>
<style name="Preference.DialogPreference">
<item name="android:positiveButtonText">@android:string/ok</item>
<item name="android:negativeButtonText">@android:string/cancel</item>
+ <item name="android:widgetLayout">@android:layout/preference_dialog</item>
</style>
<style name="Preference.DialogPreference.YesNoPreference">
@@ -680,6 +680,7 @@
<item name="android:ringtoneType">ringtone</item>
<item name="android:showSilent">true</item>
<item name="android:showDefault">true</item>
+ <item name="android:widgetLayout">@android:layout/preference_dialog</item>
</style>
<!-- Other Misc Styles -->
diff --git a/docs/html/guide/appendix/api-levels.jd b/docs/html/guide/appendix/api-levels.jd
new file mode 100644
index 0000000..9af0918
--- /dev/null
+++ b/docs/html/guide/appendix/api-levels.jd
@@ -0,0 +1,79 @@
+page.title=Android API Levels
+@jd:body
+
+
+<p>The Android <em>API Level</em> is an integer that indicates a set of APIs available in an Android SDK
+and on a version of the Android platform. Each version of the Android platform supports a specific set
+of APIs, which are always backward-compatible. For example, Android 1.5 supports all APIs available in
+Android 1.0, but the reverse is not true. If an application uses APIs
+available in Android 1.5 that are not available in 1.0, then the application should never be installed
+on an Android 1.0 device, because it will fail due to missing APIs. The API Level ensures this does not happen
+by comparing the minimum API Level required by the applicaiton to the API Level available on the device.</p>
+
+<p>When a new version of Android adds APIs, a new API Level is added to the platform. The new APIs
+are available only to applications that declare a minimum API Level that is equal-to or greater-than
+the API Level in which the APIs were introduced. The API Level required by an application is declared with the
+<code><uses-sdk></code> element inside the Android manifest, like this:</p>
+
+<pre><uses-sdk android:minSdkVersion="3" /></pre>
+
+<p>The value for <code>minSdkVersion</code> is the minimum API Level required by the application.
+If this is not declared, then it is assumed that the application is compatible with all versions and defaults to
+API Level 1. In which case, if the application actually uses APIs introduced with an API Level greater than 1, then
+the application will fail in unpredictable ways when installed on a device that only supports API Level 1
+(such as an Android 1.0 device).
+See the <code><a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html"><uses-sdk></a></code>
+documentation for more about declaring the API Level in your manifest.</p>
+
+<p>For example, the {@link android.appwidget} package was introduced with API Level 3. If your application
+has set <code>minSdkVersion</code> to 1 or 2, then your application cannot use this package,
+even if the device running your application uses a version of Android that supports it.
+In order to use the {@link android.appwidget} package, your application must set <code>minSdkVersion</code>
+to 3 or higher. When the <code>minSdkVersion</code> is set to 3, the application will no longer be able to install
+on a device running a platform version with an API Level less than 3.</p>
+
+<p>Despite the name of the manifest attribute (<code>minSdkVersion</code>), the API Level is not directly
+associated with a specific SDK. For example, the SDK for Android 1.0 uses
+API Level 1 and the SDK for Android 1.1 uses API Level 2. So it may seem that the API Level increases consistently.
+However, it's possible that a subsequent platform
+releases will not introduce new APIs, and thus, the API Level will remain the same. In addition, there are often
+multiple SDK releases for a single platform version (there were three SDK releases for Android 1.5), and
+there's no guarantee that the API Level will remain the same between these. It's possible (but unlikely) that
+a second or third SDK for a given version of the platform will provide new APIs and add a new API Level.
+When you install a new SDK, be sure to read the SDK Contents on the install page, which specifies the API
+Level for each platform available in the SDK. Also see the comparison of
+<a href="#VersionsVsApiLevels">Platform Versions vs. API Levels</a>, below.</p>
+
+<p class="note"><strong>Note:</strong> During "preview" SDK releases, there may not yet be an official platform version
+or API Level number specified. In these cases, a string value equal to the
+current codename will be a valid value for <code>minSdkVersion</code>, instead of an integer. This codename value
+will only be valid while using the preview SDK. When the final SDK is released, you must update your manifest to use
+the official API Level integer.</p>
+
+<h2 id="VersionsVsApiLevels">Platform Versions vs. API Levels</h2>
+
+<p>The following table specifies the <em>maximum</em> API Level supported by each version of the Android platform.</p>
+
+<table>
+ <tr><th>Platform Version</th><th>API Level</th></tr>
+ <tr><td>Android 1.0</td><td>1</td></tr>
+ <tr><td>Android 1.1</td><td>2</td></tr>
+ <tr><td>Android 1.5</td><td>3</td></tr>
+ <tr><td>Android Donut</td><td>Donut</td></tr>
+</table>
+
+
+<h2 id="ViewingTheApiReference">Viewing the API Reference Based on API Level</h2>
+
+<p>The Android API reference includes information that specififies the minimum API Level required for each
+package, class, and member. You can see this information on the right side of each header or label.</p>
+
+<p>By default, the reference documentation shows all APIs available with the latest SDK release.
+This means that the reference assumes you're using the latest API Level and will show you everything available
+with it. If you're developing applications for a version of Android that does not support the latest API Level,
+then you can filter the reference to reveal only the packages, classes, and members available for that API Level.
+When viewing the reference, use the "Filter by API Level" selection box (below the search bar) to pick the API Level
+you'd like to view.</p>
+
+
+
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index 1770a7a..904361f 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -139,6 +139,7 @@
native private void nScriptCSetClearColor(float r, float g, float b, float a);
native private void nScriptCSetClearDepth(float depth);
native private void nScriptCSetClearStencil(int stencil);
+ native private void nScriptCSetTimeZone(byte[] timeZone);
native private void nScriptCAddType(int type);
native private void nScriptCSetRoot(boolean isRoot);
native private void nScriptCSetScript(byte[] script, int offset, int length);
@@ -670,6 +671,15 @@
nScriptCBegin();
}
+ public void scriptCSetTimeZone(String timeZone) {
+ try {
+ byte[] bytes = timeZone.getBytes("UTF-8");
+ nScriptCSetTimeZone(bytes);
+ } catch (java.io.UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
public void scriptCSetClearColor(float r, float g, float b, float a) {
nScriptCSetClearColor(r, g, b, a);
}
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index 6f781a0..a02abca 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -586,7 +586,7 @@
nScriptCSetClearDepth(JNIEnv *_env, jobject _this, jfloat d)
{
RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
- LOG_API("nScriptCSetClearColor, con(%p), depth(%f)", con, d);
+ LOG_API("nScriptCSetClearDepth, con(%p), depth(%f)", con, d);
rsScriptCSetClearDepth(d);
}
@@ -599,6 +599,23 @@
}
static void
+nScriptCSetTimeZone(JNIEnv *_env, jobject _this, jbyteArray timeZone)
+{
+ RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+ LOG_API("nScriptCSetTimeZone, con(%p), timeZone(%s)", con, timeZone);
+
+ jint length = _env->GetArrayLength(timeZone);
+ jbyte* timeZone_ptr;
+ timeZone_ptr = (jbyte *) _env->GetPrimitiveArrayCritical(timeZone, (jboolean *)0);
+
+ rsScriptCSetTimeZone((const char *)timeZone_ptr, length);
+
+ if (timeZone_ptr) {
+ _env->ReleasePrimitiveArrayCritical(timeZone, timeZone_ptr, 0);
+ }
+}
+
+static void
nScriptCAddType(JNIEnv *_env, jobject _this, jint type)
{
RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
@@ -1052,6 +1069,7 @@
{"nScriptCSetClearColor", "(FFFF)V", (void*)nScriptCSetClearColor },
{"nScriptCSetClearDepth", "(F)V", (void*)nScriptCSetClearDepth },
{"nScriptCSetClearStencil", "(I)V", (void*)nScriptCSetClearStencil },
+{"nScriptCSetTimeZone", "([B)V", (void*)nScriptCSetTimeZone },
{"nScriptCAddType", "(I)V", (void*)nScriptCAddType },
{"nScriptCSetRoot", "(Z)V", (void*)nScriptCSetRoot },
{"nScriptCSetScript", "([BII)V", (void*)nScriptCSetScript },
diff --git a/include/media/IOMX.h b/include/media/IOMX.h
index 5c61c50..0010d84 100644
--- a/include/media/IOMX.h
+++ b/include/media/IOMX.h
@@ -23,6 +23,7 @@
#include <utils/String8.h>
#include <OMX_Core.h>
+#include <OMX_Video.h>
#define IOMX_USES_SOCKETS 0
@@ -30,6 +31,8 @@
class IMemory;
class IOMXObserver;
+class IOMXRenderer;
+class ISurface;
class IOMX : public IInterface {
public:
@@ -87,6 +90,13 @@
OMX_U32 range_offset, OMX_U32 range_length,
OMX_U32 flags, OMX_TICKS timestamp) = 0;
#endif
+
+ virtual sp<IOMXRenderer> createRenderer(
+ const sp<ISurface> &surface,
+ const char *componentName,
+ OMX_COLOR_FORMATTYPE colorFormat,
+ size_t encodedWidth, size_t encodedHeight,
+ size_t displayWidth, size_t displayHeight) = 0;
};
struct omx_message {
@@ -155,6 +165,13 @@
virtual void on_message(const omx_message &msg) = 0;
};
+class IOMXRenderer : public IInterface {
+public:
+ DECLARE_META_INTERFACE(OMXRenderer);
+
+ virtual void render(IOMX::buffer_id buffer) = 0;
+};
+
////////////////////////////////////////////////////////////////////////////////
class BnOMX : public BnInterface<IOMX> {
@@ -171,6 +188,13 @@
uint32_t flags = 0);
};
+class BnOMXRenderer : public BnInterface<IOMXRenderer> {
+public:
+ virtual status_t onTransact(
+ uint32_t code, const Parcel &data, Parcel *reply,
+ uint32_t flags = 0);
+};
+
} // namespace android
#endif // ANDROID_IOMX_H_
diff --git a/include/media/stagefright/MediaPlayerImpl.h b/include/media/stagefright/MediaPlayerImpl.h
index c48400c..e96e5e8 100644
--- a/include/media/stagefright/MediaPlayerImpl.h
+++ b/include/media/stagefright/MediaPlayerImpl.h
@@ -28,6 +28,7 @@
namespace android {
class AudioPlayer;
+class IOMXRenderer;
class ISurface;
class MediaExtractor;
class MediaBuffer;
@@ -37,7 +38,6 @@
class OMXDecoder;
class Surface;
class TimeSource;
-class VideoRenderer;
class MediaPlayerImpl {
public:
@@ -93,7 +93,7 @@
sp<Surface> mSurface;
sp<ISurface> mISurface;
- VideoRenderer *mRenderer;
+ sp<IOMXRenderer> mVideoRenderer;
sp<MediaPlayerBase::AudioSink> mAudioSink;
diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h
index 04805da..2d5b8d8 100644
--- a/include/media/stagefright/MetaData.h
+++ b/include/media/stagefright/MetaData.h
@@ -44,6 +44,7 @@
kKeyColorFormat = 'colf',
kKeyPlatformPrivate = 'priv',
kKeyDecoderComponent = 'decC',
+ kKeyBufferID = 'bfID',
};
enum {
diff --git a/include/media/stagefright/SurfaceRenderer.h b/include/media/stagefright/SurfaceRenderer.h
deleted file mode 100644
index 298ab50..0000000
--- a/include/media/stagefright/SurfaceRenderer.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SURFACE_RENDERER_H_
-
-#define SURFACE_RENDERER_H_
-
-#include <media/stagefright/VideoRenderer.h>
-#include <utils/RefBase.h>
-
-namespace android {
-
-class Surface;
-
-class SurfaceRenderer : public VideoRenderer {
-public:
- SurfaceRenderer(
- const sp<Surface> &surface,
- size_t displayWidth, size_t displayHeight,
- size_t decodedWidth, size_t decodedHeight);
-
- virtual ~SurfaceRenderer();
-
- virtual void render(
- const void *data, size_t size, void *platformPrivate);
-
-private:
- sp<Surface> mSurface;
- size_t mDisplayWidth, mDisplayHeight;
- size_t mDecodedWidth, mDecodedHeight;
-
- SurfaceRenderer(const SurfaceRenderer &);
- SurfaceRenderer &operator=(const SurfaceRenderer &);
-};
-
-} // namespace android
-
-#endif // SURFACE_RENDERER_H_
diff --git a/include/ui/Surface.h b/include/ui/Surface.h
index 156d453..5665c1f 100644
--- a/include/ui/Surface.h
+++ b/include/ui/Surface.h
@@ -36,6 +36,7 @@
class BufferMapper;
class Rect;
+class MediaPlayerImpl;
class Surface;
class SurfaceComposerClient;
struct per_client_cblk_t;
@@ -180,6 +181,7 @@
// mediaplayer needs access to ISurface for display
friend class MediaPlayer;
friend class Test;
+ friend class MediaPlayerImpl;
const sp<ISurface>& getISurface() const { return mSurface; }
status_t getBufferLocked(int index);
diff --git a/libs/rs/java/Grass/Android.mk b/libs/rs/java/Grass/Android.mk
new file mode 100644
index 0000000..ce5294e
--- /dev/null
+++ b/libs/rs/java/Grass/Android.mk
@@ -0,0 +1,25 @@
+#
+# Copyright (C) 2009 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+#LOCAL_STATIC_JAVA_LIBRARIES := android.renderscript
+
+LOCAL_PACKAGE_NAME := GrassRS
+
+include $(BUILD_PACKAGE)
diff --git a/libs/rs/java/Grass/AndroidManifest.xml b/libs/rs/java/Grass/AndroidManifest.xml
new file mode 100644
index 0000000..a40f378
--- /dev/null
+++ b/libs/rs/java/Grass/AndroidManifest.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.grass.rs">
+
+ <application android:label="GrassRS">
+
+ <activity
+ android:name="Grass"
+ android:theme="@android:style/Theme.NoTitleBar">
+
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+
+ </activity>
+
+ </application>
+
+</manifest>
diff --git a/libs/rs/java/Grass/res/drawable-hdpi/night.jpg b/libs/rs/java/Grass/res/drawable-hdpi/night.jpg
new file mode 100644
index 0000000..9989abf
--- /dev/null
+++ b/libs/rs/java/Grass/res/drawable-hdpi/night.jpg
Binary files differ
diff --git a/libs/rs/java/Grass/res/drawable-hdpi/sky.jpg b/libs/rs/java/Grass/res/drawable-hdpi/sky.jpg
new file mode 100644
index 0000000..a12fe20
--- /dev/null
+++ b/libs/rs/java/Grass/res/drawable-hdpi/sky.jpg
Binary files differ
diff --git a/libs/rs/java/Grass/res/drawable-hdpi/sunrise.jpg b/libs/rs/java/Grass/res/drawable-hdpi/sunrise.jpg
new file mode 100644
index 0000000..db016b2
--- /dev/null
+++ b/libs/rs/java/Grass/res/drawable-hdpi/sunrise.jpg
Binary files differ
diff --git a/libs/rs/java/Grass/res/drawable-hdpi/sunset.jpg b/libs/rs/java/Grass/res/drawable-hdpi/sunset.jpg
new file mode 100644
index 0000000..49bb0c6
--- /dev/null
+++ b/libs/rs/java/Grass/res/drawable-hdpi/sunset.jpg
Binary files differ
diff --git a/libs/rs/java/Grass/res/raw/grass.c b/libs/rs/java/Grass/res/raw/grass.c
new file mode 100644
index 0000000..b1b89f0
--- /dev/null
+++ b/libs/rs/java/Grass/res/raw/grass.c
@@ -0,0 +1,112 @@
+/*
+ * 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.
+ */
+
+#pragma version(1)
+#pragma stateVertex(default)
+#pragma stateFragment(PFBackground)
+#pragma stateFragmentStore(PFSBackground)
+
+#define WVGA_PORTRAIT_WIDTH 480.0f
+#define WVGA_PORTRAIT_HEIGHT 762.0f
+
+#define RSID_STATE 0
+#define RSID_FRAMECOUNT 0
+
+#define RSID_SKY_TEXTURES 1
+#define RSID_SKY_TEXTURE_NIGHT 0
+#define RSID_SKY_TEXTURE_SUNRISE 1
+#define RSID_SKY_TEXTURE_NOON 2
+#define RSID_SKY_TEXTURE_SUNSET 3
+
+#define MIDNIGHT 0.0f
+#define MORNING 0.375f
+#define AFTERNOON 0.6f
+#define DUSK 0.8f
+
+#define SECONDS_IN_DAY 24.0f * 3600.0f
+
+#define REAL_TIME 0
+
+float time(int frameCount) {
+ if (REAL_TIME) {
+ return (hour() * 3600.0f + minute() * 60.0f + second()) / SECONDS_IN_DAY;
+ }
+ return (frameCount % 180) / 180.0f;
+}
+
+void alpha(float a) {
+ color(1.0f, 1.0f, 1.0f, a);
+}
+
+float norm(float a, float start, float end) {
+ return (a - start) / (end - start);
+}
+
+void drawNight() {
+ bindTexture(NAMED_PFBackground, 0, loadI32(RSID_SKY_TEXTURES, RSID_SKY_TEXTURE_NIGHT));
+ // NOTE: Hacky way to draw the night sky
+ drawRect(WVGA_PORTRAIT_WIDTH - 512.0f, -32.0f, WVGA_PORTRAIT_WIDTH, 1024.0f - 32.0f, 0.0f);
+}
+
+void drawSunrise() {
+ bindTexture(NAMED_PFBackground, 0, loadI32(RSID_SKY_TEXTURES, RSID_SKY_TEXTURE_SUNRISE));
+ drawRect(0.0f, 0.0f, WVGA_PORTRAIT_WIDTH, WVGA_PORTRAIT_HEIGHT, 0.0f);
+}
+
+void drawNoon() {
+ bindTexture(NAMED_PFBackground, 0, loadI32(RSID_SKY_TEXTURES, RSID_SKY_TEXTURE_NOON));
+ drawRect(0.0f, 0.0f, WVGA_PORTRAIT_WIDTH, WVGA_PORTRAIT_HEIGHT, 0.0f);
+}
+
+void drawSunset() {
+ bindTexture(NAMED_PFBackground, 0, loadI32(RSID_SKY_TEXTURES, RSID_SKY_TEXTURE_SUNSET));
+ drawRect(0.0f, 0.0f, WVGA_PORTRAIT_WIDTH, WVGA_PORTRAIT_HEIGHT, 0.0f);
+}
+
+int main(int launchID) {
+ int frameCount = loadI32(RSID_STATE, RSID_FRAMECOUNT);
+ float now = time(frameCount);
+ alpha(1.0f);
+
+ if (now >= MIDNIGHT && now < MORNING) {
+ drawNight();
+ alpha(norm(now, MIDNIGHT, MORNING));
+ drawSunrise();
+ }
+
+ if (now >= MORNING && now < AFTERNOON) {
+ drawSunrise();
+ alpha(norm(now, MORNING, AFTERNOON));
+ drawNoon();
+ }
+
+ if (now >= AFTERNOON && now < DUSK) {
+ drawNoon();
+ alpha(norm(now, AFTERNOON, DUSK));
+ drawSunset();
+ }
+
+ if (now >= DUSK) {
+ drawSunset();
+ alpha(norm(now, DUSK, 1.0f));
+ drawNight();
+ }
+
+ frameCount++;
+ storeI32(RSID_STATE, RSID_FRAMECOUNT, frameCount);
+
+ return 1;
+}
diff --git a/libs/rs/java/Grass/src/com/android/grass/rs/Grass.java b/libs/rs/java/Grass/src/com/android/grass/rs/Grass.java
new file mode 100644
index 0000000..260fcee
--- /dev/null
+++ b/libs/rs/java/Grass/src/com/android/grass/rs/Grass.java
@@ -0,0 +1,46 @@
+/*
+ * 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.grass.rs;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class Grass extends Activity {
+ private GrassView mView;
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ mView = new GrassView(this);
+ setContentView(mView);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mView.onPause();
+
+ Runtime.getRuntime().exit(0);
+ }
+}
diff --git a/libs/rs/java/Grass/src/com/android/grass/rs/GrassRS.java b/libs/rs/java/Grass/src/com/android/grass/rs/GrassRS.java
new file mode 100644
index 0000000..bb13051
--- /dev/null
+++ b/libs/rs/java/Grass/src/com/android/grass/rs/GrassRS.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.grass.rs;
+
+import android.content.res.Resources;
+import android.renderscript.RenderScript;
+import static android.renderscript.RenderScript.ElementPredefined.*;
+import static android.renderscript.RenderScript.SamplerParam.*;
+import static android.renderscript.RenderScript.SamplerValue.*;
+import static android.renderscript.RenderScript.EnvMode.*;
+import static android.renderscript.RenderScript.DepthFunc.*;
+import static android.renderscript.RenderScript.BlendSrcFunc;
+import static android.renderscript.RenderScript.BlendDstFunc;
+
+import java.util.TimeZone;
+
+class GrassRS {
+ private static final int RSID_STATE = 0;
+ private static final int RSID_SKY_TEXTURES = 1;
+ private static final int SKY_TEXTURES_COUNT = 4;
+
+ private Resources mResources;
+ private RenderScript mRS;
+
+ @SuppressWarnings({"FieldCanBeLocal"})
+ private RenderScript.Script mScript;
+ @SuppressWarnings({"FieldCanBeLocal"})
+ private RenderScript.Sampler mSampler;
+ @SuppressWarnings({"FieldCanBeLocal"})
+ private RenderScript.ProgramFragment mPfBackground;
+ @SuppressWarnings({"FieldCanBeLocal"})
+ private RenderScript.ProgramFragmentStore mPfsBackground;
+
+ @SuppressWarnings({"FieldCanBeLocal"})
+ private RenderScript.Allocation mSkyTexturesIDs;
+ @SuppressWarnings({"FieldCanBeLocal"})
+ private RenderScript.Allocation[] mSkyTextures;
+ @SuppressWarnings({"FieldCanBeLocal"})
+ private int[] mSkyBufferIDs;
+ @SuppressWarnings({"FieldCanBeLocal"})
+ private RenderScript.Allocation mState;
+
+ public GrassRS() {
+ }
+
+ public void init(RenderScript rs, Resources res) {
+ mRS = rs;
+ mResources = res;
+ initRS();
+ }
+
+ private void initRS() {
+ createProgramVertex();
+ createProgramFragmentStore();
+ createProgramFragment();
+ createScriptStructures();
+
+ mRS.scriptCBegin();
+ mRS.scriptCSetClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+ mRS.scriptCSetScript(mResources, R.raw.grass);
+ mRS.scriptCSetTimeZone(TimeZone.getDefault().getID());
+ mRS.scriptCSetRoot(true);
+
+ mScript = mRS.scriptCCreate();
+
+ loadSkyTextures();
+ mScript.bindAllocation(mState, RSID_STATE);
+ mScript.bindAllocation(mSkyTexturesIDs, RSID_SKY_TEXTURES);
+
+ mRS.contextBindRootScript(mScript);
+ }
+
+ private void createScriptStructures() {
+ mState = mRS.allocationCreatePredefSized(RenderScript.ElementPredefined.USER_I32, 1);
+ mState.data(new int[1]);
+ }
+
+ private void loadSkyTextures() {
+ mSkyBufferIDs = new int[SKY_TEXTURES_COUNT];
+ mSkyTextures = new RenderScript.Allocation[SKY_TEXTURES_COUNT];
+ mSkyTexturesIDs = mRS.allocationCreatePredefSized(
+ USER_FLOAT, SKY_TEXTURES_COUNT);
+
+ final RenderScript.Allocation[] textures = mSkyTextures;
+ textures[0] = loadTexture(R.drawable.night, "night");
+ textures[1] = loadTexture(R.drawable.sunrise, "sunrise");
+ textures[2] = loadTexture(R.drawable.sky, "sky");
+ textures[3] = loadTexture(R.drawable.sunset, "sunset");
+
+ final int[] bufferIds = mSkyBufferIDs;
+ final int count = textures.length;
+
+ for (int i = 0; i < count; i++) {
+ final RenderScript.Allocation texture = textures[i];
+ texture.uploadToTexture(0);
+ bufferIds[i] = texture.getID();
+ }
+
+ mSkyTexturesIDs.data(bufferIds);
+ }
+
+ private RenderScript.Allocation loadTexture(int id, String name) {
+ RenderScript.Allocation allocation = mRS.allocationCreateFromBitmapResource(mResources, id,
+ RGB_565, false);
+ allocation.setName(name);
+ return allocation;
+ }
+
+ private void createProgramFragment() {
+ mRS.samplerBegin();
+ mRS.samplerSet(FILTER_MIN, LINEAR);
+ mRS.samplerSet(FILTER_MAG, LINEAR);
+ mRS.samplerSet(WRAP_MODE_S, CLAMP);
+ mRS.samplerSet(WRAP_MODE_T, CLAMP);
+ mSampler = mRS.samplerCreate();
+
+ mRS.programFragmentBegin(null, null);
+ mRS.programFragmentSetTexEnable(0, true);
+ mRS.programFragmentSetTexEnvMode(0, REPLACE);
+ mPfBackground = mRS.programFragmentCreate();
+ mPfBackground.setName("PFBackground");
+ mPfBackground.bindSampler(mSampler, 0);
+ }
+
+ private void createProgramFragmentStore() {
+ mRS.programFragmentStoreBegin(null, null);
+ mRS.programFragmentStoreDepthFunc(ALWAYS);
+ mRS.programFragmentStoreBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE_MINUS_SRC_ALPHA);
+ mRS.programFragmentStoreDitherEnable(true);
+ mRS.programFragmentStoreDepthMask(false);
+ mPfsBackground = mRS.programFragmentStoreCreate();
+ mPfsBackground.setName("PFSBackground");
+ }
+
+ private void createProgramVertex() {
+ }
+}
diff --git a/libs/rs/java/Grass/src/com/android/grass/rs/GrassView.java b/libs/rs/java/Grass/src/com/android/grass/rs/GrassView.java
new file mode 100644
index 0000000..a641e1e
--- /dev/null
+++ b/libs/rs/java/Grass/src/com/android/grass/rs/GrassView.java
@@ -0,0 +1,36 @@
+/*
+ * 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.grass.rs;
+
+import android.content.Context;
+import android.renderscript.RSSurfaceView;
+import android.renderscript.RenderScript;
+import android.view.SurfaceHolder;
+
+class GrassView extends RSSurfaceView {
+ public GrassView(Context context) {
+ super(context);
+ }
+
+ public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
+ super.surfaceChanged(holder, format, w, h);
+
+ RenderScript RS = createRenderScript();
+ GrassRS render = new GrassRS();
+ render.init(RS, getResources());
+ }
+}
diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec
index 45e6d1b..d9a6456 100644
--- a/libs/rs/rs.spec
+++ b/libs/rs/rs.spec
@@ -280,6 +280,11 @@
param float a
}
+ScriptCSetTimeZone {
+ param const char * timeZone
+ param uint32_t length
+ }
+
ScriptCSetClearDepth {
param float depth
}
diff --git a/libs/rs/rsScript.h b/libs/rs/rsScript.h
index 7dd2b61..a8e04a6 100644
--- a/libs/rs/rsScript.h
+++ b/libs/rs/rsScript.h
@@ -43,6 +43,9 @@
float mClearDepth;
uint32_t mClearStencil;
+ uint32_t mStartTimeMillis;
+ const char* mTimeZone;
+
ObjectBaseRef<ProgramVertex> mVertex;
ObjectBaseRef<ProgramFragment> mFragment;
//ObjectBaseRef<ProgramRaster> mRaster;
diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp
index 842c836..3b9d27a 100644
--- a/libs/rs/rsScriptC.cpp
+++ b/libs/rs/rsScriptC.cpp
@@ -230,6 +230,12 @@
ss->mEnviroment.mClearColor[3] = a;
}
+void rsi_ScriptCSetTimeZone(Context * rsc, const char * timeZone, uint32_t length)
+{
+ ScriptCState *ss = &rsc->mScriptC;
+ ss->mEnviroment.mTimeZone = timeZone;
+}
+
void rsi_ScriptCSetClearDepth(Context * rsc, float v)
{
ScriptCState *ss = &rsc->mScriptC;
diff --git a/libs/rs/rsScriptC_Lib.cpp b/libs/rs/rsScriptC_Lib.cpp
index 7db3619..21c9753 100644
--- a/libs/rs/rsScriptC_Lib.cpp
+++ b/libs/rs/rsScriptC_Lib.cpp
@@ -24,6 +24,9 @@
#include <GLES/gl.h>
#include <GLES/glext.h>
+#include <time.h>
+#include <cutils/tztime.h>
+
using namespace android;
using namespace android::renderscript;
@@ -126,14 +129,203 @@
// Math routines
//////////////////////////////////////////////////////////////////////////////
+#define PI 3.1415926f
+#define DEG_TO_RAD PI / 180.0f
+#define RAD_TO_DEG 180.0f / PI
+
static float SC_randf(float max)
{
float r = (float)rand();
return r / RAND_MAX * max;
}
+static float SC_randf2(float min, float max)
+{
+ float r = (float)rand();
+ return r / RAND_MAX * (max - min) + min;
+}
+static float SC_clampf(float amount, float low, float high)
+{
+ return amount < low ? low : (amount > high ? high : amount);
+}
+static float SC_maxf(float a, float b)
+{
+ return a > b ? a : b;
+}
+
+static float SC_minf(float a, float b)
+{
+ return a < b ? a : b;
+}
+
+static float SC_sqrf(float v)
+{
+ return v * v;
+}
+
+static float SC_distf2(float x1, float y1, float x2, float y2)
+{
+ float x = x2 - x1;
+ float y = y2 - y1;
+ return sqrtf(x * x + y * y);
+}
+
+static float SC_distf3(float x1, float y1, float z1, float x2, float y2, float z2)
+{
+ float x = x2 - x1;
+ float y = y2 - y1;
+ float z = z2 - z1;
+ return sqrtf(x * x + y * y + z * z);
+}
+
+static float SC_magf2(float a, float b)
+{
+ return sqrtf(a * a + b * b);
+}
+
+static float SC_magf3(float a, float b, float c)
+{
+ return sqrtf(a * a + b * b + c * c);
+}
+
+static float SC_radf(float degrees)
+{
+ return degrees * DEG_TO_RAD;
+}
+
+static float SC_degf(float radians)
+{
+ return radians * RAD_TO_DEG;
+}
+
+static float SC_lerpf(float start, float stop, float amount)
+{
+ return start + (stop - start) * amount;
+}
+
+static float SC_normf(float start, float stop, float value)
+{
+ return (value - start) / (stop - start);
+}
+
+static float SC_mapf(float minStart, float minStop, float maxStart, float maxStop, float value)
+{
+ return maxStart + (maxStart - maxStop) * ((value - minStart) / (minStop - minStart));
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Time routines
+//////////////////////////////////////////////////////////////////////////////
+
+static uint32_t SC_second()
+{
+ GET_TLS();
+
+ time_t rawtime;
+ time(&rawtime);
+
+ if (sc->mEnviroment.mTimeZone) {
+ struct tm timeinfo;
+ localtime_tz(&rawtime, &timeinfo, sc->mEnviroment.mTimeZone);
+ return timeinfo.tm_sec;
+ } else {
+ struct tm *timeinfo;
+ timeinfo = localtime(&rawtime);
+ return timeinfo->tm_sec;
+ }
+}
+
+static uint32_t SC_minute()
+{
+ GET_TLS();
+
+ time_t rawtime;
+ time(&rawtime);
+
+ if (sc->mEnviroment.mTimeZone) {
+ struct tm timeinfo;
+ localtime_tz(&rawtime, &timeinfo, sc->mEnviroment.mTimeZone);
+ return timeinfo.tm_min;
+ } else {
+ struct tm *timeinfo;
+ timeinfo = localtime(&rawtime);
+ return timeinfo->tm_min;
+ }
+}
+
+static uint32_t SC_hour()
+{
+ GET_TLS();
+
+ time_t rawtime;
+ time(&rawtime);
+
+ if (sc->mEnviroment.mTimeZone) {
+ struct tm timeinfo;
+ localtime_tz(&rawtime, &timeinfo, sc->mEnviroment.mTimeZone);
+ return timeinfo.tm_hour;
+ } else {
+ struct tm *timeinfo;
+ timeinfo = localtime(&rawtime);
+ return timeinfo->tm_hour;
+ }
+}
+
+static uint32_t SC_day()
+{
+ GET_TLS();
+
+ time_t rawtime;
+ time(&rawtime);
+
+ if (sc->mEnviroment.mTimeZone) {
+ struct tm timeinfo;
+ localtime_tz(&rawtime, &timeinfo, sc->mEnviroment.mTimeZone);
+ return timeinfo.tm_mday;
+ } else {
+ struct tm *timeinfo;
+ timeinfo = localtime(&rawtime);
+ return timeinfo->tm_mday;
+ }
+}
+
+static uint32_t SC_month()
+{
+ GET_TLS();
+
+ time_t rawtime;
+ time(&rawtime);
+
+ if (sc->mEnviroment.mTimeZone) {
+ struct tm timeinfo;
+ localtime_tz(&rawtime, &timeinfo, sc->mEnviroment.mTimeZone);
+ return timeinfo.tm_mon;
+ } else {
+ struct tm *timeinfo;
+ timeinfo = localtime(&rawtime);
+ return timeinfo->tm_mon;
+ }
+}
+
+static uint32_t SC_year()
+{
+ GET_TLS();
+
+ time_t rawtime;
+ time(&rawtime);
+
+ if (sc->mEnviroment.mTimeZone) {
+ struct tm timeinfo;
+ localtime_tz(&rawtime, &timeinfo, sc->mEnviroment.mTimeZone);
+ return timeinfo.tm_year;
+ } else {
+ struct tm *timeinfo;
+ timeinfo = localtime(&rawtime);
+ return timeinfo->tm_year;
+ }
+}
//////////////////////////////////////////////////////////////////////////////
// Matrix routines
@@ -451,14 +643,72 @@
"float", "(float)" },
{ "cosf", (void *)&cosf,
"float", "(float)" },
+ { "asinf", (void *)&asinf,
+ "float", "(float)" },
+ { "acosf", (void *)&acosf,
+ "float", "(float)" },
+ { "atanf", (void *)&atanf,
+ "float", "(float)" },
+ { "atan2f", (void *)&atan2f,
+ "float", "(floatm float)" },
{ "fabsf", (void *)&fabsf,
"float", "(float)" },
{ "randf", (void *)&SC_randf,
"float", "(float)" },
+ { "randf2", (void *)&SC_randf2,
+ "float", "(float, float)" },
{ "floorf", (void *)&floorf,
"float", "(float)" },
{ "ceilf", (void *)&ceilf,
"float", "(float)" },
+ { "expf", (void *)&expf,
+ "float", "(float)" },
+ { "logf", (void *)&logf,
+ "float", "(float)" },
+ { "powf", (void *)&powf,
+ "float", "(float, float)" },
+ { "maxf", (void *)&SC_maxf,
+ "float", "(float, float)" },
+ { "minf", (void *)&SC_minf,
+ "float", "(float, float)" },
+ { "sqrtf", (void *)&sqrtf,
+ "float", "(float)" },
+ { "sqrf", (void *)&SC_sqrf,
+ "float", "(float)" },
+ { "clampf", (void *)&SC_clampf,
+ "float", "(float, float, float)" },
+ { "distf2", (void *)&SC_distf2,
+ "float", "(float, float, float, float)" },
+ { "distf3", (void *)&SC_distf3,
+ "float", "(float, float, float, float, float, float)" },
+ { "magf2", (void *)&SC_magf2,
+ "float", "(float, float)" },
+ { "magf3", (void *)&SC_magf3,
+ "float", "(float, float, float)" },
+ { "radf", (void *)&SC_radf,
+ "float", "(float)" },
+ { "degf", (void *)&SC_degf,
+ "float", "(float)" },
+ { "lerpf", (void *)&SC_lerpf,
+ "float", "(float, float, float)" },
+ { "normf", (void *)&SC_normf,
+ "float", "(float, float, float)" },
+ { "mapf", (void *)&SC_mapf,
+ "float", "(float, float, float, float, float)" },
+
+ // time
+ { "second", (void *)&SC_second,
+ "int", "()" },
+ { "minute", (void *)&SC_minute,
+ "int", "()" },
+ { "hour", (void *)&SC_hour,
+ "int", "()" },
+ { "day", (void *)&SC_day,
+ "int", "()" },
+ { "month", (void *)&SC_month,
+ "int", "()" },
+ { "year", (void *)&SC_year,
+ "int", "()" },
// matrix
{ "matrixLoadIdentity", (void *)&SC_matrixLoadIdentity,
diff --git a/media/java/android/media/JetPlayer.java b/media/java/android/media/JetPlayer.java
index 2263605..1570db4 100644
--- a/media/java/android/media/JetPlayer.java
+++ b/media/java/android/media/JetPlayer.java
@@ -183,6 +183,7 @@
*/
public void release() {
native_release();
+ singletonRef = null;
}
diff --git a/media/jni/soundpool/SoundPool.cpp b/media/jni/soundpool/SoundPool.cpp
index 0d07abe..b17e31b 100644
--- a/media/jni/soundpool/SoundPool.cpp
+++ b/media/jni/soundpool/SoundPool.cpp
@@ -93,7 +93,7 @@
void SoundPool::addToRestartList(SoundChannel* channel)
{
- Mutex::Autolock lock(&mLock);
+ Mutex::Autolock lock(&mRestartLock);
mRestart.push_back(channel);
mCondition.signal();
}
@@ -106,9 +106,9 @@
int SoundPool::run()
{
- mLock.lock();
+ mRestartLock.lock();
while (!mQuit) {
- mCondition.wait(mLock);
+ mCondition.wait(mRestartLock);
LOGV("awake");
if (mQuit) break;
@@ -125,19 +125,19 @@
mRestart.clear();
mCondition.signal();
- mLock.unlock();
+ mRestartLock.unlock();
LOGV("goodbye");
return 0;
}
void SoundPool::quit()
{
- mLock.lock();
+ mRestartLock.lock();
mQuit = true;
mCondition.signal();
- mCondition.wait(mLock);
+ mCondition.wait(mRestartLock);
LOGV("return from quit");
- mLock.unlock();
+ mRestartLock.unlock();
}
bool SoundPool::startThreads()
@@ -484,11 +484,8 @@
// if not idle, this voice is being stolen
if (mState != IDLE) {
LOGV("channel %d stolen - event queued for channel %d", channelID(), nextChannelID);
- stop_l();
mNextEvent.set(sample, nextChannelID, leftVolume, rightVolume, priority, loop, rate);
-#ifdef USE_SHARED_MEM_BUFFER
- mSoundPool->done(this);
-#endif
+ stop();
return;
}
diff --git a/media/jni/soundpool/SoundPool.h b/media/jni/soundpool/SoundPool.h
index 7802781..ab86e90 100644
--- a/media/jni/soundpool/SoundPool.h
+++ b/media/jni/soundpool/SoundPool.h
@@ -204,6 +204,7 @@
jobject mSoundPoolRef;
Mutex mLock;
+ Mutex mRestartLock;
Condition mCondition;
SoundPoolThread* mDecodeThread;
SoundChannel* mChannelPool;
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index f2a657a..4661af6 100644
--- a/media/libmedia/IOMX.cpp
+++ b/media/libmedia/IOMX.cpp
@@ -5,6 +5,7 @@
#include <binder/IMemory.h>
#include <binder/Parcel.h>
#include <media/IOMX.h>
+#include <ui/ISurface.h>
namespace android {
@@ -23,7 +24,9 @@
OBSERVE_NODE,
FILL_BUFFER,
EMPTY_BUFFER,
+ CREATE_RENDERER,
OBSERVER_ON_MSG,
+ RENDERER_RENDER,
};
static void *readVoidStar(const Parcel *parcel) {
@@ -262,6 +265,28 @@
remote()->transact(EMPTY_BUFFER, data, &reply, IBinder::FLAG_ONEWAY);
}
#endif
+
+ virtual sp<IOMXRenderer> createRenderer(
+ const sp<ISurface> &surface,
+ const char *componentName,
+ OMX_COLOR_FORMATTYPE colorFormat,
+ size_t encodedWidth, size_t encodedHeight,
+ size_t displayWidth, size_t displayHeight) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
+
+ data.writeStrongBinder(surface->asBinder());
+ data.writeCString(componentName);
+ data.writeInt32(colorFormat);
+ data.writeInt32(encodedWidth);
+ data.writeInt32(encodedHeight);
+ data.writeInt32(displayWidth);
+ data.writeInt32(displayHeight);
+
+ remote()->transact(CREATE_RENDERER, data, &reply);
+
+ return interface_cast<IOMXRenderer>(reply.readStrongBinder());
+ }
};
IMPLEMENT_META_INTERFACE(OMX, "android.hardware.IOMX");
@@ -513,6 +538,33 @@
}
#endif
+ case CREATE_RENDERER:
+ {
+ CHECK_INTERFACE(IOMX, data, reply);
+
+ sp<ISurface> isurface =
+ interface_cast<ISurface>(data.readStrongBinder());
+
+ const char *componentName = data.readCString();
+
+ OMX_COLOR_FORMATTYPE colorFormat =
+ static_cast<OMX_COLOR_FORMATTYPE>(data.readInt32());
+
+ size_t encodedWidth = (size_t)data.readInt32();
+ size_t encodedHeight = (size_t)data.readInt32();
+ size_t displayWidth = (size_t)data.readInt32();
+ size_t displayHeight = (size_t)data.readInt32();
+
+ sp<IOMXRenderer> renderer =
+ createRenderer(isurface, componentName, colorFormat,
+ encodedWidth, encodedHeight,
+ displayWidth, displayHeight);
+
+ reply->writeStrongBinder(renderer->asBinder());
+
+ return OK;
+ }
+
default:
return BBinder::onTransact(code, data, reply, flags);
}
@@ -558,4 +610,44 @@
}
}
+////////////////////////////////////////////////////////////////////////////////
+
+class BpOMXRenderer : public BpInterface<IOMXRenderer> {
+public:
+ BpOMXRenderer(const sp<IBinder> &impl)
+ : BpInterface<IOMXRenderer>(impl) {
+ }
+
+ virtual void render(IOMX::buffer_id buffer) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IOMXRenderer::getInterfaceDescriptor());
+ writeVoidStar(buffer, &data);
+
+ // NOTE: Do NOT make this a ONE_WAY call, it must be synchronous
+ // so that the caller knows when to recycle the buffer.
+ remote()->transact(RENDERER_RENDER, data, &reply);
+ }
+};
+
+IMPLEMENT_META_INTERFACE(OMXRenderer, "android.hardware.IOMXRenderer");
+
+status_t BnOMXRenderer::onTransact(
+ uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
+ switch (code) {
+ case RENDERER_RENDER:
+ {
+ CHECK_INTERFACE(IOMXRenderer, data, reply);
+
+ IOMX::buffer_id buffer = readVoidStar(&data);
+
+ render(buffer);
+
+ return NO_ERROR;
+ }
+
+ default:
+ return BBinder::onTransact(code, data, reply, flags);
+ }
+}
+
} // namespace android
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 5be9224..0a44762 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -19,14 +19,10 @@
MediaSource.cpp \
MetaData.cpp \
MmapSource.cpp \
- QComHardwareRenderer.cpp \
SampleTable.cpp \
ShoutcastSource.cpp \
- SoftwareRenderer.cpp \
- SurfaceRenderer.cpp \
TimeSource.cpp \
TimedEventQueue.cpp \
- TIHardwareRenderer.cpp \
Utils.cpp \
AudioPlayer.cpp \
ESDS.cpp \
diff --git a/media/libstagefright/MediaPlayerImpl.cpp b/media/libstagefright/MediaPlayerImpl.cpp
index 04c9a11..341f002 100644
--- a/media/libstagefright/MediaPlayerImpl.cpp
+++ b/media/libstagefright/MediaPlayerImpl.cpp
@@ -35,12 +35,8 @@
#include <media/stagefright/MetaData.h>
#include <media/stagefright/MmapSource.h>
#include <media/stagefright/OMXDecoder.h>
-#include <media/stagefright/QComHardwareRenderer.h>
#include <media/stagefright/ShoutcastSource.h>
-#include <media/stagefright/SoftwareRenderer.h>
-#include <media/stagefright/SurfaceRenderer.h>
#include <media/stagefright/TimeSource.h>
-#include <media/stagefright/TIHardwareRenderer.h>
#include <ui/PixelFormat.h>
#include <ui/Surface.h>
@@ -61,7 +57,6 @@
mDuration(0),
mPlaying(false),
mPaused(false),
- mRenderer(NULL),
mSeeking(false),
mFrameSize(0),
mUseSoftwareColorConversion(false) {
@@ -121,7 +116,6 @@
mDuration(0),
mPlaying(false),
mPaused(false),
- mRenderer(NULL),
mSeeking(false),
mFrameSize(0),
mUseSoftwareColorConversion(false) {
@@ -379,7 +373,7 @@
{
Mutex::Autolock autoLock(mLock);
- if (mRenderer != NULL) {
+ if (mVideoRenderer.get() != NULL) {
sendFrameToISurface(buffer);
}
}
@@ -652,52 +646,26 @@
success = success && meta->findInt32(kKeyHeight, &decodedHeight);
assert(success);
- static const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00;
+ const sp<ISurface> &isurface =
+ mSurface.get() != NULL ? mSurface->getISurface() : mISurface;
- if (mSurface.get() != NULL) {
- LOGW("Using SurfaceRenderer.");
- mRenderer =
- new SurfaceRenderer(
- mSurface, mVideoWidth, mVideoHeight,
- decodedWidth, decodedHeight);
- } else if (format == OMX_QCOM_COLOR_FormatYVU420SemiPlanar
- && !strncmp(component, "OMX.qcom.video.decoder.", 23)) {
- LOGW("Using QComHardwareRenderer.");
- mRenderer =
- new QComHardwareRenderer(
- mISurface, mVideoWidth, mVideoHeight,
- decodedWidth, decodedHeight);
- } else if (format == OMX_COLOR_FormatCbYCrY
- && !strcmp(component, "OMX.TI.Video.Decoder")) {
- LOGW("Using TIHardwareRenderer.");
- mRenderer =
- new TIHardwareRenderer(
- mISurface, mVideoWidth, mVideoHeight,
- decodedWidth, decodedHeight);
- } else {
- LOGW("Using software renderer.");
- mRenderer = new SoftwareRenderer(
- mISurface, mVideoWidth, mVideoHeight,
- decodedWidth, decodedHeight);
- }
+ mVideoRenderer =
+ mClient.interface()->createRenderer(
+ isurface, component,
+ (OMX_COLOR_FORMATTYPE)format,
+ decodedWidth, decodedHeight,
+ mVideoWidth, mVideoHeight);
}
void MediaPlayerImpl::depopulateISurface() {
- delete mRenderer;
- mRenderer = NULL;
+ mVideoRenderer.clear();
}
void MediaPlayerImpl::sendFrameToISurface(MediaBuffer *buffer) {
- void *platformPrivate;
- if (!buffer->meta_data()->findPointer(
- kKeyPlatformPrivate, &platformPrivate)) {
- platformPrivate = NULL;
+ void *id;
+ if (buffer->meta_data()->findPointer(kKeyBufferID, &id)) {
+ mVideoRenderer->render((IOMX::buffer_id)id);
}
-
- mRenderer->render(
- (const uint8_t *)buffer->data() + buffer->range_offset(),
- buffer->range_length(),
- platformPrivate);
}
void MediaPlayerImpl::setAudioSink(
diff --git a/media/libstagefright/OMXDecoder.cpp b/media/libstagefright/OMXDecoder.cpp
index 5e44999..780cd2e 100644
--- a/media/libstagefright/OMXDecoder.cpp
+++ b/media/libstagefright/OMXDecoder.cpp
@@ -154,8 +154,7 @@
if (!strncmp(codec, "OMX.qcom.video.", 15)) {
quirks |= kRequiresLoadedToIdleAfterAllocation;
}
- if (!strcmp(codec, "OMX.TI.AAC.decode")
- || !strcmp(codec, "OMX.TI.MP3.decode")) {
+ if (!strcmp(codec, "OMX.TI.MP3.decode")) {
quirks |= kMeasuresTimeInMilliseconds;
}
@@ -1551,6 +1550,10 @@
kKeyPlatformPrivate,
msg.u.extended_buffer_data.platform_private);
+ media_buffer->meta_data()->setPointer(
+ kKeyBufferID,
+ msg.u.extended_buffer_data.buffer);
+
if (msg.u.extended_buffer_data.flags & OMX_BUFFERFLAG_EOS) {
mErrorCondition = ERROR_END_OF_STREAM;
}
diff --git a/media/libstagefright/SurfaceRenderer.cpp b/media/libstagefright/SurfaceRenderer.cpp
deleted file mode 100644
index e54288d..0000000
--- a/media/libstagefright/SurfaceRenderer.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "SurfaceRenderer"
-#include <utils/Log.h>
-
-#undef NDEBUG
-#include <assert.h>
-
-#include <media/stagefright/SurfaceRenderer.h>
-#include <ui/Surface.h>
-
-namespace android {
-
-SurfaceRenderer::SurfaceRenderer(
- const sp<Surface> &surface,
- size_t displayWidth, size_t displayHeight,
- size_t decodedWidth, size_t decodedHeight)
- : mSurface(surface),
- mDisplayWidth(displayWidth),
- mDisplayHeight(displayHeight),
- mDecodedWidth(decodedWidth),
- mDecodedHeight(decodedHeight) {
-}
-
-SurfaceRenderer::~SurfaceRenderer() {
-}
-
-void SurfaceRenderer::render(
- const void *data, size_t size, void *platformPrivate) {
- Surface::SurfaceInfo info;
- status_t err = mSurface->lock(&info);
- if (err != OK) {
- return;
- }
-
- const uint8_t *src = (const uint8_t *)data;
- uint8_t *dst = (uint8_t *)info.bits;
-
- for (size_t i = 0; i < mDisplayHeight; ++i) {
- memcpy(dst, src, mDisplayWidth);
- src += mDecodedWidth;
- dst += mDisplayWidth;
- }
- src += (mDecodedHeight - mDisplayHeight) * mDecodedWidth;
-
- for (size_t i = 0; i < (mDisplayHeight + 1) / 2; ++i) {
- memcpy(dst, src, (mDisplayWidth + 1) & ~1);
- src += (mDecodedWidth + 1) & ~1;
- dst += (mDisplayWidth + 1) & ~1;
- }
-
- mSurface->unlockAndPost();
-}
-
-} // namespace android
diff --git a/media/libstagefright/omx/Android.mk b/media/libstagefright/omx/Android.mk
index 9c6d475..2e564e9 100644
--- a/media/libstagefright/omx/Android.mk
+++ b/media/libstagefright/omx/Android.mk
@@ -9,13 +9,17 @@
LOCAL_CFLAGS := $(PV_CFLAGS_MINUS_VISIBILITY)
LOCAL_SRC_FILES:= \
- OMX.cpp
+ OMX.cpp \
+ QComHardwareRenderer.cpp \
+ SoftwareRenderer.cpp \
+ TIHardwareRenderer.cpp
-LOCAL_SHARED_LIBRARIES := \
- libbinder \
- libmedia \
- libutils \
- libui \
+LOCAL_SHARED_LIBRARIES := \
+ libbinder \
+ libmedia \
+ libutils \
+ libui \
+ libcutils \
libopencore_common
LOCAL_PRELINK_MODULE:= false
diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp
index daaa741..062afd4 100644
--- a/media/libstagefright/omx/OMX.cpp
+++ b/media/libstagefright/omx/OMX.cpp
@@ -24,9 +24,15 @@
#include <assert.h>
#include "OMX.h"
+#include "OMXRenderer.h"
+
#include "pv_omxcore.h"
#include <binder/IMemory.h>
+#include <media/stagefright/QComHardwareRenderer.h>
+#include <media/stagefright/SoftwareRenderer.h>
+#include <media/stagefright/TIHardwareRenderer.h>
+#include <media/stagefright/VideoRenderer.h>
#include <OMX_Component.h>
@@ -619,5 +625,62 @@
}
#endif
+////////////////////////////////////////////////////////////////////////////////
+
+sp<IOMXRenderer> OMX::createRenderer(
+ const sp<ISurface> &surface,
+ const char *componentName,
+ OMX_COLOR_FORMATTYPE colorFormat,
+ size_t encodedWidth, size_t encodedHeight,
+ size_t displayWidth, size_t displayHeight) {
+ VideoRenderer *impl = NULL;
+
+ static const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00;
+
+ if (colorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar
+ && !strncmp(componentName, "OMX.qcom.video.decoder.", 23)) {
+ LOGW("Using QComHardwareRenderer.");
+ impl =
+ new QComHardwareRenderer(
+ surface,
+ displayWidth, displayHeight,
+ encodedWidth, encodedHeight);
+ } else if (colorFormat == OMX_COLOR_FormatCbYCrY
+ && !strcmp(componentName, "OMX.TI.Video.Decoder")) {
+ LOGW("Using TIHardwareRenderer.");
+ impl =
+ new TIHardwareRenderer(
+ surface,
+ displayWidth, displayHeight,
+ encodedWidth, encodedHeight);
+ } else {
+ LOGW("Using software renderer.");
+ impl = new SoftwareRenderer(
+ surface,
+ displayWidth, displayHeight,
+ encodedWidth, encodedHeight);
+ }
+
+ return new OMXRenderer(impl);
+}
+
+OMXRenderer::OMXRenderer(VideoRenderer *impl)
+ : mImpl(impl) {
+}
+
+OMXRenderer::~OMXRenderer() {
+ delete mImpl;
+ mImpl = NULL;
+}
+
+void OMXRenderer::render(IOMX::buffer_id buffer) {
+ OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer;
+
+ mImpl->render(
+ header->pBuffer + header->nOffset,
+ header->nFilledLen,
+ header->pPlatformPrivate);
+}
+
} // namespace android
diff --git a/media/libstagefright/omx/OMX.h b/media/libstagefright/omx/OMX.h
index ed4e5dd..20430bb 100644
--- a/media/libstagefright/omx/OMX.h
+++ b/media/libstagefright/omx/OMX.h
@@ -79,6 +79,13 @@
OMX_U32 flags, OMX_TICKS timestamp);
#endif
+ virtual sp<IOMXRenderer> createRenderer(
+ const sp<ISurface> &surface,
+ const char *componentName,
+ OMX_COLOR_FORMATTYPE colorFormat,
+ size_t encodedWidth, size_t encodedHeight,
+ size_t displayWidth, size_t displayHeight);
+
private:
static OMX_CALLBACKTYPE kCallbacks;
diff --git a/media/libstagefright/omx/OMXRenderer.h b/media/libstagefright/omx/OMXRenderer.h
new file mode 100644
index 0000000..4d194ce
--- /dev/null
+++ b/media/libstagefright/omx/OMXRenderer.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef OMX_RENDERER_H_
+
+#define OMX_RENDERER_H_
+
+#include <media/IOMX.h>
+
+namespace android {
+
+class VideoRenderer;
+
+class OMXRenderer : public BnOMXRenderer {
+public:
+ // Assumes ownership of "impl".
+ OMXRenderer(VideoRenderer *impl);
+ virtual ~OMXRenderer();
+
+ virtual void render(IOMX::buffer_id buffer);
+
+private:
+ VideoRenderer *mImpl;
+
+ OMXRenderer(const OMXRenderer &);
+ OMXRenderer &operator=(const OMXRenderer &);
+};
+
+} // namespace android
+
+#endif // OMX_RENDERER_H_
diff --git a/media/libstagefright/QComHardwareRenderer.cpp b/media/libstagefright/omx/QComHardwareRenderer.cpp
similarity index 100%
rename from media/libstagefright/QComHardwareRenderer.cpp
rename to media/libstagefright/omx/QComHardwareRenderer.cpp
diff --git a/media/libstagefright/SoftwareRenderer.cpp b/media/libstagefright/omx/SoftwareRenderer.cpp
similarity index 96%
rename from media/libstagefright/SoftwareRenderer.cpp
rename to media/libstagefright/omx/SoftwareRenderer.cpp
index 66b6b07..5483238 100644
--- a/media/libstagefright/SoftwareRenderer.cpp
+++ b/media/libstagefright/omx/SoftwareRenderer.cpp
@@ -61,6 +61,10 @@
void SoftwareRenderer::render(
const void *data, size_t size, void *platformPrivate) {
+ if (size != (mDecodedHeight * mDecodedWidth * 3) / 2) {
+ LOGE("size is %d, expected %d",
+ size, (mDecodedHeight * mDecodedWidth * 3) / 2);
+ }
assert(size >= (mDecodedWidth * mDecodedHeight * 3) / 2);
static const signed kClipMin = -278;
diff --git a/media/libstagefright/TIHardwareRenderer.cpp b/media/libstagefright/omx/TIHardwareRenderer.cpp
similarity index 100%
rename from media/libstagefright/TIHardwareRenderer.cpp
rename to media/libstagefright/omx/TIHardwareRenderer.cpp
diff --git a/telephony/java/com/android/internal/telephony/CommandsInterface.java b/telephony/java/com/android/internal/telephony/CommandsInterface.java
index c52fe06..6ebd8d6 100644
--- a/telephony/java/com/android/internal/telephony/CommandsInterface.java
+++ b/telephony/java/com/android/internal/telephony/CommandsInterface.java
@@ -1300,11 +1300,13 @@
* the username for APN, or NULL
* @param password
* the password for APN, or NULL
+ * @param authType
+ * the PAP / CHAP auth type. Values is one of SETUP_DATA_AUTH_*
* @param result
* Callback message
*/
public void setupDataCall(String radioTechnology, String profile, String apn,
- String user, String password, Message result);
+ String user, String password, String authType, Message result);
/**
* Deactivate packet data connection
diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java
index 52f6526..50bf218 100644
--- a/telephony/java/com/android/internal/telephony/RIL.java
+++ b/telephony/java/com/android/internal/telephony/RIL.java
@@ -1237,10 +1237,17 @@
*/
public void
setupDefaultPDP(String apn, String user, String password, Message result) {
- String radioTechnology = "1"; //0 for CDMA, 1 for GSM/UMTS
+ int radioTechnology;
+ int authType;
String profile = ""; //profile number, NULL for GSM/UMTS
- setupDataCall(radioTechnology, profile, apn, user,
- password, result);
+
+ radioTechnology = RILConstants.SETUP_DATA_TECH_GSM;
+ //TODO(): Add to the APN database, AuthType is set to CHAP/PAP
+ authType = (user != null) ? RILConstants.SETUP_DATA_AUTH_PAP_CHAP
+ : RILConstants.SETUP_DATA_AUTH_NONE;
+
+ setupDataCall(Integer.toString(radioTechnology), profile, apn, user,
+ password, Integer.toString(authType), result);
}
@@ -1259,7 +1266,7 @@
*/
public void
setupDataCall(String radioTechnology, String profile, String apn,
- String user, String password, Message result) {
+ String user, String password, String authType, Message result) {
RILRequest rr
= RILRequest.obtain(RIL_REQUEST_SETUP_DATA_CALL, result);
@@ -1270,15 +1277,12 @@
rr.mp.writeString(apn);
rr.mp.writeString(user);
rr.mp.writeString(password);
- //TODO(): Add to the APN database, AuthType is set to CHAP/PAP
- // 0 => Neither PAP nor CHAP will be performed, 3 => PAP / CHAP will be performed.
- if (user != null)
- rr.mp.writeString("3");
- else
- rr.mp.writeString("0");
+ rr.mp.writeString(authType);
- if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " "
- + apn);
+ if (RILJ_LOGD) riljLog(rr.serialString() + "> "
+ + requestToString(rr.mRequest) + " " + radioTechnology + " "
+ + profile + " " + apn + " " + user + " "
+ + password + " " + authType);
send(rr);
}
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index 0763e63..90a82f9 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -79,6 +79,14 @@
int CDM_TTY_HCO_MODE = 2;
int CDM_TTY_VCO_MODE = 3;
+ /* Setup a packet data connection. See ril.h RIL_REQUEST_SETUP_DATA_CALL */
+ int SETUP_DATA_TECH_CDMA = 0;
+ int SETUP_DATA_TECH_GSM = 1;
+ int SETUP_DATA_AUTH_NONE = 0;
+ int SETUP_DATA_AUTH_PAP = 1;
+ int SETUP_DATA_AUTH_CHAP = 2;
+ int SETUP_DATA_AUTH_PAP_CHAP = 3;
+
/*
cat include/telephony/ril.h | \
egrep '^#define' | \
diff --git a/telephony/java/com/android/internal/telephony/SmsMessageBase.java b/telephony/java/com/android/internal/telephony/SmsMessageBase.java
index 7a15c32..6177c8a 100644
--- a/telephony/java/com/android/internal/telephony/SmsMessageBase.java
+++ b/telephony/java/com/android/internal/telephony/SmsMessageBase.java
@@ -372,16 +372,10 @@
* -or-
* 2. [x@y][ ]/[body]
*/
- String[] parts = messageBody.split("( /)|( )", 3);
- if (parts.length < 2 || parts[0].indexOf('@') == -1) return;
+ String[] parts = messageBody.split("( /)|( )", 2);
+ if (parts.length < 1 || parts[0].indexOf('@') == -1) return;
emailFrom = parts[0];
- if (parts.length == 3) {
- pseudoSubject = parts[1];
- emailBody = parts[2];
- } else {
- pseudoSubject = null;
- emailBody = parts[1];
- }
+ emailBody = parts[1];
isEmail = true;
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
index fef6d3c..4588f36 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
@@ -143,9 +143,10 @@
lastFailTime = -1;
lastFailCause = FailCause.NONE;
receivedDisconnectReq = false;
- phone.mCM.setupDataCall(Integer.toString(RILConstants.CDMA_PHONE),
+ phone.mCM.setupDataCall(Integer.toString(RILConstants.SETUP_DATA_TECH_CDMA),
Integer.toString(RILConstants.DATA_PROFILE_DEFAULT), null, null,
- null, obtainMessage(EVENT_SETUP_DATA_CONNECTION_DONE));
+ null, Integer.toString(RILConstants.SETUP_DATA_AUTH_PAP_CHAP),
+ obtainMessage(EVENT_SETUP_DATA_CONNECTION_DONE));
}
private void tearDownData(Message msg) {
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
index 3ab1f77..1f1f7c1 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
@@ -19,6 +19,7 @@
import android.app.Activity;
import android.app.PendingIntent;
+import android.app.PendingIntent.CanceledException;
import android.content.ContentValues;
import android.content.SharedPreferences;
import android.database.Cursor;
@@ -31,6 +32,7 @@
import android.preference.PreferenceManager;
import android.util.Config;
import android.util.Log;
+import android.telephony.SmsManager;
import com.android.internal.telephony.TelephonyProperties;
import com.android.internal.telephony.CommandsInterface;
@@ -45,6 +47,7 @@
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
+import java.lang.Boolean;
final class CdmaSMSDispatcher extends SMSDispatcher {
@@ -331,6 +334,24 @@
sentIntent, deliveryIntent);
}
+ protected void sendRawPdu(byte[] smsc, byte[] pdu, PendingIntent sentIntent,
+ PendingIntent deliveryIntent) {
+ String inEcm = SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE);
+ if (Boolean.parseBoolean(inEcm)) {
+ if (sentIntent != null) {
+ try {
+ sentIntent.send(SmsManager.RESULT_ERROR_NO_SERVICE);
+ } catch (CanceledException ex) {}
+ }
+ if (Config.LOGD) {
+ Log.d(TAG, "Block SMS in Emergency Callback mode");
+ }
+ return;
+ }
+
+ super.sendRawPdu(smsc, pdu, sentIntent, deliveryIntent);
+ }
+
/** {@inheritDoc} */
protected void sendSms(SmsTracker tracker) {
HashMap map = tracker.mData;
diff --git a/telephony/java/com/android/internal/telephony/gsm/PdpConnection.java b/telephony/java/com/android/internal/telephony/gsm/PdpConnection.java
index 89de867..224419e 100644
--- a/telephony/java/com/android/internal/telephony/gsm/PdpConnection.java
+++ b/telephony/java/com/android/internal/telephony/gsm/PdpConnection.java
@@ -84,9 +84,13 @@
lastFailCause = FailCause.NONE;
receivedDisconnectReq = false;
- phone.mCM.setupDataCall(Integer.toString(RILConstants.GSM_PHONE),
+ int authType = (apn.user != null) ? RILConstants.SETUP_DATA_AUTH_PAP_CHAP :
+ RILConstants.SETUP_DATA_AUTH_NONE;
+
+ phone.mCM.setupDataCall(Integer.toString(RILConstants.SETUP_DATA_TECH_GSM),
Integer.toString(RILConstants.DATA_PROFILE_DEFAULT), apn.apn, apn.user,
- apn.password, obtainMessage(EVENT_SETUP_DATA_CONNECTION_DONE));
+ apn.password, Integer.toString(authType),
+ obtainMessage(EVENT_SETUP_DATA_CONNECTION_DONE));
}
private void tearDownData(Message msg) {
diff --git a/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java b/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java
index be5b842..11b3fd6 100644
--- a/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java
+++ b/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java
@@ -944,7 +944,7 @@
}
public void setupDataCall(String radioTechnology, String profile, String apn, String user,
- String password, Message result) {
+ String password, String authType, Message result) {
unimplemented(result);
}