summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt9
-rw-r--r--cmds/stagefright/sf2.cpp31
-rw-r--r--core/java/android/net/http/SslError.java68
-rw-r--r--core/java/android/provider/CallLog.java41
-rw-r--r--core/java/android/provider/ContactsContract.java9
-rw-r--r--core/java/android/view/MotionEvent.java14
-rw-r--r--core/java/android/view/View.java8
-rw-r--r--core/java/android/webkit/BrowserFrame.java5
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java69
-rw-r--r--core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java5
-rw-r--r--core/java/com/android/internal/widget/multiwaveview/Tweener.java90
-rw-r--r--core/jni/android/graphics/SurfaceTexture.cpp7
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_handle_normal.pngbin3020 -> 8582 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_handle_pressed.pngbin8376 -> 8378 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_handle_normal.pngbin1883 -> 4734 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_handle_pressed.pngbin4800 -> 4299 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_handle_normal.pngbin0 -> 12479 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_handle_pressed.pngbin0 -> 12182 bytes
-rw-r--r--core/res/res/values-sw600dp/config.xml3
-rwxr-xr-xcore/res/res/values/config.xml44
-rw-r--r--graphics/java/android/graphics/SurfaceTexture.java4
-rw-r--r--include/gui/SurfaceTexture.h18
-rw-r--r--include/media/stagefright/MPEG2TSWriter.h10
-rw-r--r--include/media/stagefright/OMXCodec.h13
-rw-r--r--libs/gui/SurfaceTexture.cpp45
-rw-r--r--libs/gui/tests/SurfaceTexture_test.cpp176
-rw-r--r--libs/hwui/DisplayListRenderer.cpp17
-rw-r--r--media/libstagefright/ACodec.cpp63
-rw-r--r--media/libstagefright/MPEG2TSWriter.cpp41
-rw-r--r--native/include/android/input.h1
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java7
-rw-r--r--policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java5
-rw-r--r--services/input/InputReader.cpp8
-rw-r--r--services/java/com/android/server/am/BatteryStatsService.java13
-rw-r--r--services/surfaceflinger/Layer.cpp19
35 files changed, 642 insertions, 201 deletions
diff --git a/api/current.txt b/api/current.txt
index f6bfd73d2935..9273b712f4a3 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -11446,11 +11446,14 @@ package android.net.http {
}
public class SslError {
- ctor public SslError(int, android.net.http.SslCertificate);
- ctor public SslError(int, java.security.cert.X509Certificate);
+ ctor public deprecated SslError(int, android.net.http.SslCertificate);
+ ctor public deprecated SslError(int, java.security.cert.X509Certificate);
+ ctor public SslError(int, android.net.http.SslCertificate, java.lang.String);
+ ctor public SslError(int, java.security.cert.X509Certificate, java.lang.String);
method public boolean addError(int);
method public android.net.http.SslCertificate getCertificate();
method public int getPrimaryError();
+ method public java.lang.String getUrl();
method public boolean hasError(int);
field public static final int SSL_EXPIRED = 1; // 0x1
field public static final int SSL_IDMISMATCH = 2; // 0x2
@@ -21426,7 +21429,6 @@ package android.view {
field public static final int AXIS_Y = 1; // 0x1
field public static final int AXIS_Z = 11; // 0xb
field public static final int BUTTON_BACK = 8; // 0x8
- field public static final int BUTTON_ERASER = 32; // 0x20
field public static final int BUTTON_FORWARD = 16; // 0x10
field public static final int BUTTON_PRIMARY = 1; // 0x1
field public static final int BUTTON_SECONDARY = 2; // 0x2
@@ -22011,6 +22013,7 @@ package android.view {
method public void setOnDragListener(android.view.View.OnDragListener);
method public void setOnFocusChangeListener(android.view.View.OnFocusChangeListener);
method public void setOnGenericMotionListener(android.view.View.OnGenericMotionListener);
+ method public void setOnHoverListener(android.view.View.OnHoverListener);
method public void setOnKeyListener(android.view.View.OnKeyListener);
method public void setOnLongClickListener(android.view.View.OnLongClickListener);
method public void setOnSystemUiVisibilityChangeListener(android.view.View.OnSystemUiVisibilityChangeListener);
diff --git a/cmds/stagefright/sf2.cpp b/cmds/stagefright/sf2.cpp
index 289665f51b5d..ddd64ecf0445 100644
--- a/cmds/stagefright/sf2.cpp
+++ b/cmds/stagefright/sf2.cpp
@@ -29,6 +29,7 @@
#include <media/stagefright/MediaExtractor.h>
#include <media/stagefright/MediaSource.h>
#include <media/stagefright/MetaData.h>
+#include <media/stagefright/NativeWindowWrapper.h>
#include <media/stagefright/Utils.h>
#include <surfaceflinger/ISurfaceComposer.h>
@@ -39,10 +40,12 @@
using namespace android;
struct Controller : public AHandler {
- Controller(const char *uri, bool decodeAudio, const sp<Surface> &surface)
+ Controller(const char *uri, bool decodeAudio,
+ const sp<Surface> &surface, bool renderToSurface)
: mURI(uri),
mDecodeAudio(decodeAudio),
mSurface(surface),
+ mRenderToSurface(renderToSurface),
mCodec(new ACodec) {
CHECK(!mDecodeAudio || mSurface == NULL);
}
@@ -97,7 +100,8 @@ protected:
sp<AMessage> format = makeFormat(mSource->getFormat());
if (mSurface != NULL) {
- format->setObject("surface", mSurface);
+ format->setObject(
+ "native-window", new NativeWindowWrapper(mSurface));
}
mCodec->initiateSetup(format);
@@ -220,6 +224,7 @@ private:
AString mURI;
bool mDecodeAudio;
sp<Surface> mSurface;
+ bool mRenderToSurface;
sp<ACodec> mCodec;
sp<MediaSource> mSource;
@@ -451,7 +456,7 @@ private:
inBuffer->release();
inBuffer = NULL;
- // break; // Don't coalesce
+ break; // Don't coalesce
}
LOGV("coalesced %d input buffers", n);
@@ -479,6 +484,10 @@ private:
sp<AMessage> reply;
CHECK(msg->findMessage("reply", &reply));
+ if (mRenderToSurface) {
+ reply->setInt32("render", 1);
+ }
+
reply->post();
}
@@ -491,7 +500,8 @@ static void usage(const char *me) {
fprintf(stderr, " -a(udio)\n");
fprintf(stderr,
- " -s(surface) Allocate output buffers on a surface.\n");
+ " -S(urface) Allocate output buffers on a surface.\n"
+ " -R(ender) Render surface-allocated buffers.\n");
}
int main(int argc, char **argv) {
@@ -499,18 +509,23 @@ int main(int argc, char **argv) {
bool decodeAudio = false;
bool useSurface = false;
+ bool renderToSurface = false;
int res;
- while ((res = getopt(argc, argv, "has")) >= 0) {
+ while ((res = getopt(argc, argv, "haSR")) >= 0) {
switch (res) {
case 'a':
decodeAudio = true;
break;
- case 's':
+ case 'S':
useSurface = true;
break;
+ case 'R':
+ renderToSurface = true;
+ break;
+
case '?':
case 'h':
default:
@@ -562,7 +577,9 @@ int main(int argc, char **argv) {
CHECK(surface != NULL);
}
- sp<Controller> controller = new Controller(argv[0], decodeAudio, surface);
+ sp<Controller> controller =
+ new Controller(argv[0], decodeAudio, surface, renderToSurface);
+
looper->registerHandler(controller);
controller->startAsync();
diff --git a/core/java/android/net/http/SslError.java b/core/java/android/net/http/SslError.java
index e1b9debb8f2b..1e1cb49dabad 100644
--- a/core/java/android/net/http/SslError.java
+++ b/core/java/android/net/http/SslError.java
@@ -59,36 +59,97 @@ public class SslError {
/**
* The SSL certificate associated with the error set
*/
- SslCertificate mCertificate;
+ final SslCertificate mCertificate;
+
+ /**
+ * The URL associated with the error set.
+ */
+ final String mUrl;
/**
* Creates a new SSL error set object
* @param error The SSL error
* @param certificate The associated SSL certificate
+ * @deprecated Use {@link #SslError(int, SslCertificate, String)}
*/
+ @Deprecated
public SslError(int error, SslCertificate certificate) {
addError(error);
+ if (certificate == null) {
+ throw new NullPointerException("certificate is null.");
+ }
mCertificate = certificate;
+ mUrl = "";
}
/**
* Creates a new SSL error set object
* @param error The SSL error
* @param certificate The associated SSL certificate
+ * @deprecated Use {@link #SslError(int, X509Certificate, String)}
*/
+ @Deprecated
public SslError(int error, X509Certificate certificate) {
addError(error);
+ if (certificate == null) {
+ throw new NullPointerException("certificate is null.");
+ }
mCertificate = new SslCertificate(certificate);
+ mUrl = "";
}
/**
- * @return The SSL certificate associated with the error set
+ * Creates a new SSL error set object
+ * @param error The SSL error
+ * @param certificate The associated SSL certificate
+ * @param url The associated URL.
+ */
+ public SslError(int error, SslCertificate certificate, String url) {
+ addError(error);
+ if (certificate == null) {
+ throw new NullPointerException("certificate is null.");
+ }
+ mCertificate = certificate;
+ if (url == null) {
+ throw new NullPointerException("url is null.");
+ }
+ mUrl = url;
+ }
+
+ /**
+ * Creates a new SSL error set object
+ * @param error The SSL error
+ * @param certificate The associated SSL certificate
+ * @param url The associated URL.
+ */
+ public SslError(int error, X509Certificate certificate, String url) {
+ addError(error);
+ if (certificate == null) {
+ throw new NullPointerException("certificate is null.");
+ }
+ mCertificate = new SslCertificate(certificate);
+ if (url == null) {
+ throw new NullPointerException("url is null.");
+ }
+ mUrl = url;
+ }
+
+ /**
+ * @return The SSL certificate associated with the error set, non-null.
*/
public SslCertificate getCertificate() {
return mCertificate;
}
/**
+ * @return The URL associated with the error set, non-null.
+ * "" if one of the deprecated constructors is used.
+ */
+ public String getUrl() {
+ return mUrl;
+ }
+
+ /**
* Adds the SSL error to the error set
* @param error The SSL error to add
* @return True iff the error being added is a known SSL error
@@ -137,6 +198,7 @@ public class SslError {
*/
public String toString() {
return "primary error: " + getPrimaryError() +
- " certificate: " + getCertificate();
+ " certificate: " + getCertificate() +
+ " on URL: " + getUrl();
}
}
diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java
index 02faf496843e..09331939f616 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -24,6 +24,8 @@ import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.DataUsageFeedback;
import android.text.TextUtils;
/**
@@ -204,7 +206,44 @@ public class CallLog {
}
if ((ci != null) && (ci.person_id > 0)) {
- ContactsContract.Contacts.markAsContacted(resolver, ci.person_id);
+ // Update usage information for the number associated with the contact ID.
+ // We need to use both the number and the ID for obtaining a data ID since other
+ // contacts may have the same number.
+
+ final Cursor cursor;
+
+ // We should prefer normalized one (probably coming from
+ // Phone.NORMALIZED_NUMBER column) first. If it isn't available try others.
+ if (ci.normalizedNumber != null) {
+ final String normalizedPhoneNumber = ci.normalizedNumber;
+ cursor = resolver.query(Phone.CONTENT_URI,
+ new String[] { Phone._ID },
+ Phone.CONTACT_ID + " =? AND " + Phone.NORMALIZED_NUMBER + " =?",
+ new String[] { String.valueOf(ci.person_id), normalizedPhoneNumber},
+ null);
+ } else {
+ final String phoneNumber = ci.phoneNumber != null ? ci.phoneNumber : number;
+ cursor = resolver.query(Phone.CONTENT_URI,
+ new String[] { Phone._ID },
+ Phone.CONTACT_ID + " =? AND " + Phone.NUMBER + " =?",
+ new String[] { String.valueOf(ci.person_id), phoneNumber},
+ null);
+ }
+
+ if (cursor != null) {
+ try {
+ if (cursor.getCount() > 0 && cursor.moveToFirst()) {
+ final Uri feedbackUri = DataUsageFeedback.FEEDBACK_URI.buildUpon()
+ .appendPath(cursor.getString(0))
+ .appendQueryParameter(DataUsageFeedback.USAGE_TYPE,
+ DataUsageFeedback.USAGE_TYPE_CALL)
+ .build();
+ resolver.update(feedbackUri, new ContentValues(), null, null);
+ }
+ } finally {
+ cursor.close();
+ }
+ }
}
Uri result = resolver.insert(CONTENT_URI, values);
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index cb96bfd2c9d1..ad71061f52be 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -174,6 +174,15 @@ public final class ContactsContract {
*/
public static final String PRIMARY_ACCOUNT_TYPE = "type_for_primary_account";
+ /**
+ * A boolean parameter for {@link Contacts#CONTENT_STREQUENT_URI} and
+ * {@link Contacts#CONTENT_STREQUENT_FILTER_URI}, which requires the ContactsProvider to
+ * return only phone-related results. For example, frequently contacted person list should
+ * include persons contacted via phone (not email, sms, etc.)
+ *
+ * @hide
+ */
+ public static final String STREQUENT_PHONE_ONLY = "strequent_phone_only";
/**
* @hide
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index 3436cd1df94f..f45e78bfef10 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -1130,14 +1130,14 @@ public final class MotionEvent extends InputEvent implements Parcelable {
public static final int BUTTON_PRIMARY = 1 << 0;
/**
- * Button constant: Secondary button (right mouse button, stylus barrel).
+ * Button constant: Secondary button (right mouse button, stylus first button).
*
* @see #getButtonState
*/
public static final int BUTTON_SECONDARY = 1 << 1;
/**
- * Button constant: Tertiary button (middle mouse button).
+ * Button constant: Tertiary button (middle mouse button, stylus second button).
*
* @see #getButtonState
*/
@@ -1165,13 +1165,6 @@ public final class MotionEvent extends InputEvent implements Parcelable {
*/
public static final int BUTTON_FORWARD = 1 << 4;
- /**
- * Button constant: Eraser button pressed (stylus end).
- *
- * @see #getButtonState
- */
- public static final int BUTTON_ERASER = 1 << 5;
-
// NOTE: If you add a new axis here you must also add it to:
// native/include/android/input.h
@@ -1183,7 +1176,7 @@ public final class MotionEvent extends InputEvent implements Parcelable {
"BUTTON_TERTIARY",
"BUTTON_BACK",
"BUTTON_FORWARD",
- "BUTTON_ERASER",
+ "0x00000020",
"0x00000040",
"0x00000080",
"0x00000100",
@@ -2176,7 +2169,6 @@ public final class MotionEvent extends InputEvent implements Parcelable {
* @see #BUTTON_TERTIARY
* @see #BUTTON_FORWARD
* @see #BUTTON_BACK
- * @see #BUTTON_ERASER
*/
public final int getButtonState() {
return nativeGetButtonState(mNativePtr);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 574313441d15..411b7142a6dc 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -3390,6 +3390,14 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit
}
/**
+ * Register a callback to be invoked when a hover event is sent to this view.
+ * @param l the hover listener to attach to this view
+ */
+ public void setOnHoverListener(OnHoverListener l) {
+ mOnHoverListener = l;
+ }
+
+ /**
* Register a drag event listener callback object for this View. The parameter is
* an implementation of {@link android.view.View.OnDragListener}. To send a drag event to a
* View, the system calls the
diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index 2f4774f61e17..79a5affffa44 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -1150,11 +1150,12 @@ class BrowserFrame extends Handler {
* {@link #nativeSslCertErrorProceed(int)} or
* {@link #nativeSslCertErrorCancel(int, int)}.
*/
- private void reportSslCertError(final int handle, final int cert_error, byte cert_der[]) {
+ private void reportSslCertError(
+ final int handle, final int cert_error, byte cert_der[], String url) {
final SslError ssl_error;
try {
X509Certificate cert = new X509CertImpl(cert_der);
- ssl_error = new SslError(cert_error, cert);
+ ssl_error = new SslError(cert_error, cert, url);
} catch (IOException e) {
// Can't get the certificate, not much to do.
Log.e(LOGTAG, "Can't get the certificate from WebKit, canceling");
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 12687a130e3f..7b65964a2fc0 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -41,6 +41,7 @@ import android.util.PrintWriterPrinter;
import android.util.Printer;
import android.util.Slog;
import android.util.SparseArray;
+import android.util.TimeUtils;
import java.io.BufferedReader;
import java.io.File;
@@ -4870,8 +4871,8 @@ public final class BatteryStatsImpl extends BatteryStats {
return 0;
}
- void readHistory(Parcel in) {
- mHistoryBaseTime = in.readLong();
+ void readHistory(Parcel in, boolean andOldHistory) {
+ final long historyBaseTime = in.readLong();
mHistoryBuffer.setDataSize(0);
mHistoryBuffer.setDataPosition(0);
@@ -4889,15 +4890,35 @@ public final class BatteryStatsImpl extends BatteryStats {
in.setDataPosition(curPos + bufSize);
}
- long oldnow = SystemClock.elapsedRealtime() - (5*60*1000);
- if (oldnow > 0) {
- // If the system process has restarted, but not the entire
- // system, then the mHistoryBaseTime already accounts for
- // much of the elapsed time. We thus want to adjust it back,
- // to avoid large gaps in the data. We determine we are
- // in this case by arbitrarily saying it is so if at this
- // point in boot the elapsed time is already more than 5 minutes.
- mHistoryBaseTime -= oldnow;
+ if (andOldHistory) {
+ readOldHistory(in);
+ }
+
+ if (DEBUG_HISTORY) {
+ StringBuilder sb = new StringBuilder(128);
+ sb.append("****************** OLD mHistoryBaseTime: ");
+ TimeUtils.formatDuration(mHistoryBaseTime, sb);
+ Slog.i(TAG, sb.toString());
+ }
+ mHistoryBaseTime = historyBaseTime;
+ if (DEBUG_HISTORY) {
+ StringBuilder sb = new StringBuilder(128);
+ sb.append("****************** NEW mHistoryBaseTime: ");
+ TimeUtils.formatDuration(mHistoryBaseTime, sb);
+ Slog.i(TAG, sb.toString());
+ }
+
+ // We are just arbitrarily going to insert 1 minute from the sample of
+ // the last run until samples in this run.
+ if (mHistoryBaseTime > 0) {
+ long oldnow = SystemClock.elapsedRealtime();
+ mHistoryBaseTime = (mHistoryBaseTime - oldnow) + 60*1000;
+ if (DEBUG_HISTORY) {
+ StringBuilder sb = new StringBuilder(128);
+ sb.append("****************** ADJUSTED mHistoryBaseTime: ");
+ TimeUtils.formatDuration(mHistoryBaseTime, sb);
+ Slog.i(TAG, sb.toString());
+ }
}
}
@@ -4910,12 +4931,24 @@ public final class BatteryStatsImpl extends BatteryStats {
}
}
- void writeHistory(Parcel out) {
- out.writeLong(mLastHistoryTime);
+ void writeHistory(Parcel out, boolean andOldHistory) {
+ if (DEBUG_HISTORY) {
+ StringBuilder sb = new StringBuilder(128);
+ sb.append("****************** WRITING mHistoryBaseTime: ");
+ TimeUtils.formatDuration(mHistoryBaseTime, sb);
+ sb.append(" mLastHistoryTime: ");
+ TimeUtils.formatDuration(mLastHistoryTime, sb);
+ Slog.i(TAG, sb.toString());
+ }
+ out.writeLong(mHistoryBaseTime + mLastHistoryTime);
out.writeInt(mHistoryBuffer.dataSize());
if (DEBUG_HISTORY) Slog.i(TAG, "***************** WRITING HISTORY: "
+ mHistoryBuffer.dataSize() + " bytes at " + out.dataPosition());
out.appendFrom(mHistoryBuffer, 0, mHistoryBuffer.dataSize());
+
+ if (andOldHistory) {
+ writeOldHistory(out);
+ }
}
void writeOldHistory(Parcel out) {
@@ -4935,8 +4968,7 @@ public final class BatteryStatsImpl extends BatteryStats {
return;
}
- readHistory(in);
- readOldHistory(in);
+ readHistory(in, true);
mStartCount = in.readInt();
mBatteryUptime = in.readLong();
@@ -5136,8 +5168,7 @@ public final class BatteryStatsImpl extends BatteryStats {
out.writeInt(VERSION);
- writeHistory(out);
- writeOldHistory(out);
+ writeHistory(out, true);
out.writeInt(mStartCount);
out.writeLong(computeBatteryUptime(NOW_SYS, STATS_SINCE_CHARGED));
@@ -5340,7 +5371,7 @@ public final class BatteryStatsImpl extends BatteryStats {
throw new ParcelFormatException("Bad magic number");
}
- readHistory(in);
+ readHistory(in, false);
mStartCount = in.readInt();
mBatteryUptime = in.readLong();
@@ -5461,7 +5492,7 @@ public final class BatteryStatsImpl extends BatteryStats {
out.writeInt(MAGIC);
- writeHistory(out);
+ writeHistory(out, false);
out.writeInt(mStartCount);
out.writeLong(mBatteryUptime);
diff --git a/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java b/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java
index 3e7b976aedb7..5b3510428f7b 100644
--- a/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java
+++ b/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java
@@ -224,8 +224,8 @@ public class MultiWaveView extends View implements AnimatorUpdateListener {
/**
* Animation used to attract user's attention to the target button.
- * Assumes mChevronDrawables is an a list with an even number of chevrons filled with left
- * followed by right chevrons.
+ * Assumes mChevronDrawables is an a list with an even number of chevrons filled with
+ * mFeedbackCount items in the order: left, right, top, bottom.
*/
private void startChevronAnimation() {
final float r = mHandleDrawable.getWidth() / 2;
@@ -442,6 +442,7 @@ public class MultiWaveView extends View implements AnimatorUpdateListener {
mHandleDrawable.setX(mWaveCenterX);
mHandleDrawable.setY(mWaveCenterY);
mHandleDrawable.setState(TargetDrawable.STATE_INACTIVE);
+ Tweener.reset();
}
@Override
diff --git a/core/java/com/android/internal/widget/multiwaveview/Tweener.java b/core/java/com/android/internal/widget/multiwaveview/Tweener.java
index 0cff00a514ab..bc8a62f2ca0b 100644
--- a/core/java/com/android/internal/widget/multiwaveview/Tweener.java
+++ b/core/java/com/android/internal/widget/multiwaveview/Tweener.java
@@ -18,25 +18,42 @@ package com.android.internal.widget.multiwaveview;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map.Entry;
import android.animation.Animator.AnimatorListener;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
+import android.util.Log;
class Tweener {
private static final String TAG = "Tweener";
+ private static final boolean DEBUG = false;
- private Object object;
ObjectAnimator animator;
private static HashMap<Object, Tweener> sTweens = new HashMap<Object, Tweener>();
- public Tweener(Object obj, ObjectAnimator anim) {
- object = obj;
+ public Tweener(ObjectAnimator anim) {
animator = anim;
}
+ private static void remove(Animator animator) {
+ Iterator<Entry<Object, Tweener>> iter = sTweens.entrySet().iterator();
+ while (iter.hasNext()) {
+ Entry<Object, Tweener> entry = iter.next();
+ if (entry.getValue().animator == animator) {
+ if (DEBUG) Log.v(TAG, "Removing tweener " + sTweens.get(entry.getKey())
+ + " sTweens.size() = " + sTweens.size());
+ iter.remove();
+ break; // an animator can only be attached to one object
+ }
+ }
+ }
+
public static Tweener to(Object object, long duration, Object... vars) {
long delay = 0;
AnimatorUpdateListener updateListener = null;
@@ -77,32 +94,35 @@ class Tweener {
// Re-use existing tween, if present
Tweener tween = sTweens.get(object);
+ ObjectAnimator anim = null;
if (tween == null) {
- ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(object,
+ anim = ObjectAnimator.ofPropertyValuesHolder(object,
props.toArray(new PropertyValuesHolder[props.size()]));
- tween = new Tweener(object, anim);
+ tween = new Tweener(anim);
sTweens.put(object, tween);
+ if (DEBUG) Log.v(TAG, "Added new Tweener " + tween);
} else {
- tween.animator.cancel();
- replace(props, object);
+ anim = sTweens.get(object).animator;
+ replace(props, object); // Cancel all animators for given object
}
if (interpolator != null) {
- tween.animator.setInterpolator(interpolator);
+ anim.setInterpolator(interpolator);
}
// Update animation with properties discovered in loop above
- tween.animator.setStartDelay(delay);
- tween.animator.setDuration(duration);
+ anim.setStartDelay(delay);
+ anim.setDuration(duration);
if (updateListener != null) {
- tween.animator.removeAllUpdateListeners(); // There should be only one
- tween.animator.addUpdateListener(updateListener);
+ anim.removeAllUpdateListeners(); // There should be only one
+ anim.addUpdateListener(updateListener);
}
if (listener != null) {
- tween.animator.removeAllListeners(); // There should be only one.
- tween.animator.addListener(listener);
+ anim.removeAllListeners(); // There should be only one.
+ anim.addListener(listener);
}
- tween.animator.start();
+ anim.addListener(mCleanupListener);
+ anim.start();
return tween;
}
@@ -114,18 +134,40 @@ class Tweener {
return Tweener.to(object, duration, vars);
}
- static void replace(ArrayList<PropertyValuesHolder> props, Object... args) {
+ // Listener to watch for completed animations and remove them.
+ private static AnimatorListener mCleanupListener = new AnimatorListenerAdapter() {
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ remove(animation);
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ remove(animation);
+ }
+ };
+
+ public static void reset() {
+ if (DEBUG) {
+ Log.v(TAG, "Reset()");
+ if (sTweens.size() > 0) {
+ Log.v(TAG, "Cleaning up " + sTweens.size() + " animations");
+ }
+ }
+ sTweens.clear();
+ }
+
+ private static void replace(ArrayList<PropertyValuesHolder> props, Object... args) {
for (final Object killobject : args) {
Tweener tween = sTweens.get(killobject);
if (tween != null) {
- if (killobject == tween.object) {
- tween.animator.cancel();
- if (props != null) {
- tween.animator.setValues(
- props.toArray(new PropertyValuesHolder[props.size()]));
- } else {
- sTweens.remove(tween);
- }
+ tween.animator.cancel();
+ if (props != null) {
+ tween.animator.setValues(
+ props.toArray(new PropertyValuesHolder[props.size()]));
+ } else {
+ sTweens.remove(tween);
}
}
}
diff --git a/core/jni/android/graphics/SurfaceTexture.cpp b/core/jni/android/graphics/SurfaceTexture.cpp
index dd8b3780f06c..2de0932e540f 100644
--- a/core/jni/android/graphics/SurfaceTexture.cpp
+++ b/core/jni/android/graphics/SurfaceTexture.cpp
@@ -233,12 +233,6 @@ static jlong SurfaceTexture_getTimestamp(JNIEnv* env, jobject thiz)
return surfaceTexture->getTimestamp();
}
-static jint SurfaceTexture_getQueuedCount(JNIEnv* env, jobject thiz)
-{
- sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
- return surfaceTexture->getQueuedCount();
-}
-
// ----------------------------------------------------------------------------
static JNINativeMethod gSurfaceTextureMethods[] = {
@@ -249,7 +243,6 @@ static JNINativeMethod gSurfaceTextureMethods[] = {
{"nativeUpdateTexImage", "()V", (void*)SurfaceTexture_updateTexImage },
{"nativeGetTransformMatrix", "([F)V", (void*)SurfaceTexture_getTransformMatrix },
{"nativeGetTimestamp", "()J", (void*)SurfaceTexture_getTimestamp },
- {"nativeGetQueuedCount", "()I", (void*)SurfaceTexture_getQueuedCount }
};
int register_android_graphics_SurfaceTexture(JNIEnv* env)
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_handle_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_handle_normal.png
index e21a87caa40c..0f4bfe6d0d1f 100644
--- a/core/res/res/drawable-hdpi/ic_lockscreen_handle_normal.png
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_handle_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_handle_pressed.png b/core/res/res/drawable-hdpi/ic_lockscreen_handle_pressed.png
index 3283f99a555e..995705dc607e 100644
--- a/core/res/res/drawable-hdpi/ic_lockscreen_handle_pressed.png
+++ b/core/res/res/drawable-hdpi/ic_lockscreen_handle_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_handle_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_handle_normal.png
index c10344f83bba..754d7bc830e5 100644
--- a/core/res/res/drawable-mdpi/ic_lockscreen_handle_normal.png
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_handle_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_handle_pressed.png b/core/res/res/drawable-mdpi/ic_lockscreen_handle_pressed.png
index 08c6cfe71bc6..0187a02afc21 100644
--- a/core/res/res/drawable-mdpi/ic_lockscreen_handle_pressed.png
+++ b/core/res/res/drawable-mdpi/ic_lockscreen_handle_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_handle_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_handle_normal.png
new file mode 100644
index 000000000000..544924e4bcf9
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_handle_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_handle_pressed.png b/core/res/res/drawable-xhdpi/ic_lockscreen_handle_pressed.png
new file mode 100644
index 000000000000..2d28009f2235
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_lockscreen_handle_pressed.png
Binary files differ
diff --git a/core/res/res/values-sw600dp/config.xml b/core/res/res/values-sw600dp/config.xml
index d6a0cdd7d4a7..13bbac60f5c8 100644
--- a/core/res/res/values-sw600dp/config.xml
+++ b/core/res/res/values-sw600dp/config.xml
@@ -23,9 +23,6 @@
<!-- see comment in values/config.xml -->
<integer name="config_longPressOnPowerBehavior">2</integer>
- <!-- Show sliding tab before lockscreen -->
- <bool name="config_enableSlidingTabFirst">false</bool>
-
<!-- Enable lockscreen rotation -->
<bool name="config_enableLockScreenRotation">true</bool>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 0ad3184fabda..827153e7243e 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3,16 +3,16 @@
/*
** Copyright 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
+** 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
+** 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
+** 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.
*/
-->
@@ -54,25 +54,25 @@
connected. If you use the ims apn DCT will block
any other apn from connecting until ims apn is connected-->
<bool name="ImsConnectedDefaultValue">false</bool>
-
+
<!-- Flag indicating whether the surface flinger is inefficient
at performing a blur. Used by parts of the UI to turn off
the blur effect where it isn't worth the performance hit. -->
<bool name="config_sf_slowBlur">false</bool>
-
+
<!-- The duration (in milliseconds) of a short animation. -->
<integer name="config_shortAnimTime">200</integer>
-
+
<!-- The duration (in milliseconds) of a medium-length animation. -->
<integer name="config_mediumAnimTime">400</integer>
-
+
<!-- The duration (in milliseconds) of a long animation. -->
<integer name="config_longAnimTime">500</integer>
<!-- The duration (in milliseconds) of the activity open/close and fragment open/close animations. -->
<integer name="config_activityShortDur">150</integer>
<integer name="config_activityDefaultDur">220</integer>
-
+
<!-- Duration for the dim animation behind a dialog. This may be either
a percentage, which is relative to the duration of the enter/open
animation of the window being shown that is dimming behind, or it may
@@ -83,11 +83,11 @@
maximum (let them grow as large as the screen). Actual values are
specified for -large and -xlarge configurations. -->
<dimen name="config_prefDialogWidth">320dp</dimen>
-
+
<!-- Whether dialogs should close automatically when the user touches outside
of them. This should not normally be modified. -->
<bool name="config_closeDialogWhenTouchOutside">false</bool>
-
+
<!-- The duration (in milliseconds) that the radio will scan for a signal
when there's no network connection. If the scan doesn't timeout, use zero -->
<integer name="config_radioScanningTimeout">0</integer>
@@ -202,7 +202,7 @@
the slider is open. This can be set or unset depending how easily
the slider can be opened (for example, in a pocket or purse). -->
<bool name="config_bypass_keyguard_if_slider_open">true</bool>
-
+
<!-- Flag indicating whether the we should enable the automatic brightness in Settings.
Software implementation will be used if config_hardware_auto_brightness_available is not set -->
<bool name="config_automatic_brightness_available">false</bool>
@@ -212,10 +212,10 @@
<!-- If this is true, the screen will come on when you unplug usb/power/whatever. -->
<bool name="config_unplugTurnsOnScreen">false</bool>
-
+
<!-- If this is true, the screen will fade off. -->
<bool name="config_animateScreenLights">true</bool>
-
+
<!-- XXXXXX END OF RESOURCES USING WRONG NAMING CONVENTION -->
<!-- If true, the screen can be rotated via the accelerometer in all 4
@@ -300,7 +300,7 @@
<item>20</item>
<item>21</item>
</integer-array>
-
+
<!-- Vibrator pattern for feedback about touching a virtual key -->
<integer-array name="config_virtualKeyVibePattern">
<item>0</item>
@@ -380,8 +380,8 @@
<!-- Allow the menu hard key to be disabled in LockScreen on some devices -->
<bool name="config_disableMenuKeyInLockScreen">false</bool>
- <!-- Show sliding tab before lockscreen -->
- <bool name="config_enableSlidingTabFirst">true</bool>
+ <!-- Don't show lock screen before unlock screen (PIN/pattern/password) -->
+ <bool name="config_enableLockBeforeUnlockScreen">false</bool>
<!-- Diable lockscreen rotation by default -->
<bool name="config_enableLockScreenRotation">false</bool>
@@ -460,7 +460,7 @@
This feature should be disabled for most devices. -->
<integer name="config_virtualKeyQuietTimeMillis">0</integer>
- <!-- Component name of the default wallpaper. This will be ImageWallpaper if not
+ <!-- Component name of the default wallpaper. This will be ImageWallpaper if not
specified -->
<string name="default_wallpaper_component">@null</string>
diff --git a/graphics/java/android/graphics/SurfaceTexture.java b/graphics/java/android/graphics/SurfaceTexture.java
index adb6eac3e6d5..90a7ac22335b 100644
--- a/graphics/java/android/graphics/SurfaceTexture.java
+++ b/graphics/java/android/graphics/SurfaceTexture.java
@@ -144,10 +144,6 @@ public class SurfaceTexture {
*/
public void updateTexImage() {
nativeUpdateTexImage();
- if (nativeGetQueuedCount() > 0) {
- Message m = mEventHandler.obtainMessage();
- mEventHandler.sendMessage(m);
- }
}
/**
diff --git a/include/gui/SurfaceTexture.h b/include/gui/SurfaceTexture.h
index e558dfd6c252..c82fb9b77ed4 100644
--- a/include/gui/SurfaceTexture.h
+++ b/include/gui/SurfaceTexture.h
@@ -46,11 +46,14 @@ public:
enum { NUM_BUFFER_SLOTS = 32 };
struct FrameAvailableListener : public virtual RefBase {
- // onFrameAvailable() is called from queueBuffer() is the FIFO is
- // empty. You can use SurfaceTexture::getQueuedCount() to
- // figure out if there are more frames waiting.
- // This is called without any lock held can be called concurrently by
- // multiple threads.
+ // onFrameAvailable() is called from queueBuffer() each time an
+ // additional frame becomes available for consumption. This means that
+ // frames that are queued while in asynchronous mode only trigger the
+ // callback if no previous frames are pending. Frames queued while in
+ // synchronous mode always trigger the callback.
+ //
+ // This is called without any lock held and can be called concurrently
+ // by multiple threads.
virtual void onFrameAvailable() = 0;
};
@@ -101,11 +104,6 @@ public:
// target texture belongs is bound to the calling thread.
status_t updateTexImage();
- // getqueuedCount returns the number of queued frames waiting in the
- // FIFO. In asynchronous mode, this always returns 0 or 1 since
- // frames are not accumulating in the FIFO.
- size_t getQueuedCount() const;
-
// setBufferCountServer set the buffer count. If the client has requested
// a buffer count using setBufferCount, the server-buffer count will
// take effect once the client sets the count back to zero.
diff --git a/include/media/stagefright/MPEG2TSWriter.h b/include/media/stagefright/MPEG2TSWriter.h
index f2c65057b809..e4c1c49a72d6 100644
--- a/include/media/stagefright/MPEG2TSWriter.h
+++ b/include/media/stagefright/MPEG2TSWriter.h
@@ -31,6 +31,10 @@ struct MPEG2TSWriter : public MediaWriter {
MPEG2TSWriter(int fd);
MPEG2TSWriter(const char *filename);
+ MPEG2TSWriter(
+ void *cookie,
+ ssize_t (*write)(void *cookie, const void *data, size_t size));
+
virtual status_t addSource(const sp<MediaSource> &source);
virtual status_t start(MetaData *param = NULL);
virtual status_t stop();
@@ -51,6 +55,10 @@ private:
struct SourceInfo;
FILE *mFile;
+
+ void *mWriteCookie;
+ ssize_t (*mWriteFunc)(void *cookie, const void *data, size_t size);
+
sp<ALooper> mLooper;
sp<AHandlerReflector<MPEG2TSWriter> > mReflector;
@@ -69,6 +77,8 @@ private:
void writeProgramMap();
void writeAccessUnit(int32_t sourceIndex, const sp<ABuffer> &buffer);
+ ssize_t internalWrite(const void *data, size_t size);
+
DISALLOW_EVIL_CONSTRUCTORS(MPEG2TSWriter);
};
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
index 589cefda2038..92331a16f96a 100644
--- a/include/media/stagefright/OMXCodec.h
+++ b/include/media/stagefright/OMXCodec.h
@@ -79,6 +79,13 @@ struct OMXCodec : public MediaSource,
// from MediaBufferObserver
virtual void signalBufferReturned(MediaBuffer *buffer);
+ // for use by ACodec
+ static void findMatchingCodecs(
+ const char *mime,
+ bool createEncoder, const char *matchComponentName,
+ uint32_t flags,
+ Vector<String8> *matchingCodecs);
+
protected:
virtual ~OMXCodec();
@@ -311,12 +318,6 @@ private:
static uint32_t getComponentQuirks(
const char *componentName, bool isEncoder);
- static void findMatchingCodecs(
- const char *mime,
- bool createEncoder, const char *matchComponentName,
- uint32_t flags,
- Vector<String8> *matchingCodecs);
-
void restorePatchedDataPointer(BufferInfo *info);
status_t applyRotation();
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index 37e6d1187db8..0925001965dd 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -417,17 +417,22 @@ status_t SurfaceTexture::queueBuffer(int buf, int64_t timestamp) {
return -EINVAL;
}
- if (mQueue.empty()) {
- listener = mFrameAvailableListener;
- }
-
if (mSynchronousMode) {
- // in synchronous mode we queue all buffers in a FIFO
+ // In synchronous mode we queue all buffers in a FIFO.
mQueue.push_back(buf);
+
+ // Synchronous mode always signals that an additional frame should
+ // be consumed.
+ listener = mFrameAvailableListener;
} else {
- // in asynchronous mode we only keep the most recent buffer
+ // In asynchronous mode we only keep the most recent buffer.
if (mQueue.empty()) {
mQueue.push_back(buf);
+
+ // Asynchronous mode only signals that a frame should be
+ // consumed if no previous frame was pending. If a frame were
+ // pending then the consumer would have already been notified.
+ listener = mFrameAvailableListener;
} else {
Fifo::iterator front(mQueue.begin());
// buffer currently queued is freed
@@ -483,24 +488,14 @@ status_t SurfaceTexture::setTransform(uint32_t transform) {
status_t SurfaceTexture::updateTexImage() {
LOGV("SurfaceTexture::updateTexImage");
-
Mutex::Autolock lock(mMutex);
- int buf = mCurrentTexture;
+ // In asynchronous mode the list is guaranteed to be one buffer
+ // deep, while in synchronous mode we use the oldest buffer.
if (!mQueue.empty()) {
- // in asynchronous mode the list is guaranteed to be one buffer deep,
- // while in synchronous mode we use the oldest buffer
Fifo::iterator front(mQueue.begin());
- buf = *front;
- mQueue.erase(front);
- if (mQueue.isEmpty()) {
- mDequeueCondition.signal();
- }
- }
+ int buf = *front;
- // Initially both mCurrentTexture and buf are INVALID_BUFFER_SLOT,
- // so this check will fail until a buffer gets queued.
- if (mCurrentTexture != buf) {
// Update the GL texture object.
EGLImageKHR image = mSlots[buf].mEglImage;
if (image == EGL_NO_IMAGE_KHR) {
@@ -538,7 +533,7 @@ status_t SurfaceTexture::updateTexImage() {
}
if (mCurrentTexture != INVALID_BUFFER_SLOT) {
- // the current buffer becomes FREE if it was still in the queued
+ // The current buffer becomes FREE if it was still in the queued
// state. If it has already been given to the client
// (synchronous mode), then it stays in DEQUEUED state.
if (mSlots[mCurrentTexture].mBufferState == BufferSlot::QUEUED)
@@ -553,17 +548,17 @@ status_t SurfaceTexture::updateTexImage() {
mCurrentTransform = mSlots[buf].mTransform;
mCurrentTimestamp = mSlots[buf].mTimestamp;
computeCurrentTransformMatrix();
+
+ // Now that we've passed the point at which failures can happen,
+ // it's safe to remove the buffer from the front of the queue.
+ mQueue.erase(front);
mDequeueCondition.signal();
} else {
// We always bind the texture even if we don't update its contents.
glBindTexture(mCurrentTextureTarget, mTexName);
}
- return OK;
-}
-size_t SurfaceTexture::getQueuedCount() const {
- Mutex::Autolock lock(mMutex);
- return mQueue.size();
+ return OK;
}
bool SurfaceTexture::isExternalFormat(uint32_t format)
diff --git a/libs/gui/tests/SurfaceTexture_test.cpp b/libs/gui/tests/SurfaceTexture_test.cpp
index f219639a0627..dfa9211afac5 100644
--- a/libs/gui/tests/SurfaceTexture_test.cpp
+++ b/libs/gui/tests/SurfaceTexture_test.cpp
@@ -419,6 +419,31 @@ protected:
ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
}
+ class FrameWaiter : public SurfaceTexture::FrameAvailableListener {
+ public:
+ FrameWaiter():
+ mPendingFrames(0) {
+ }
+
+ void waitForFrame() {
+ Mutex::Autolock lock(mMutex);
+ while (mPendingFrames == 0) {
+ mCondition.wait(mMutex);
+ }
+ mPendingFrames--;
+ }
+
+ virtual void onFrameAvailable() {
+ Mutex::Autolock lock(mMutex);
+ mPendingFrames++;
+ mCondition.signal();
+ }
+
+ int mPendingFrames;
+ Mutex mMutex;
+ Condition mCondition;
+ };
+
sp<SurfaceTexture> mST;
sp<SurfaceTextureClient> mSTC;
sp<ANativeWindow> mANW;
@@ -648,6 +673,157 @@ TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferWithCrop) {
}
}
+// This test is intended to catch synchronization bugs between the CPU-written
+// and GPU-read buffers.
+TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BuffersRepeatedly) {
+ enum { texWidth = 16 };
+ enum { texHeight = 16 };
+ enum { numFrames = 1024 };
+
+ ASSERT_EQ(NO_ERROR, mST->setSynchronousMode(true));
+ ASSERT_EQ(NO_ERROR, mST->setBufferCountServer(2));
+ ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
+ texWidth, texHeight, HAL_PIXEL_FORMAT_YV12));
+ ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
+ GRALLOC_USAGE_SW_WRITE_OFTEN));
+
+ struct TestPixel {
+ int x;
+ int y;
+ };
+ const TestPixel testPixels[] = {
+ { 4, 11 },
+ { 12, 14 },
+ { 7, 2 },
+ };
+ enum {numTestPixels = sizeof(testPixels) / sizeof(testPixels[0])};
+
+ class ProducerThread : public Thread {
+ public:
+ ProducerThread(const sp<ANativeWindow>& anw, const TestPixel* testPixels):
+ mANW(anw),
+ mTestPixels(testPixels) {
+ }
+
+ virtual ~ProducerThread() {
+ }
+
+ virtual bool threadLoop() {
+ for (int i = 0; i < numFrames; i++) {
+ ANativeWindowBuffer* anb;
+ if (mANW->dequeueBuffer(mANW.get(), &anb) != NO_ERROR) {
+ return false;
+ }
+ if (anb == NULL) {
+ return false;
+ }
+
+ sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
+ if (mANW->lockBuffer(mANW.get(), buf->getNativeBuffer())
+ != NO_ERROR) {
+ return false;
+ }
+
+ const int yuvTexOffsetY = 0;
+ int stride = buf->getStride();
+ int yuvTexStrideY = stride;
+ int yuvTexOffsetV = yuvTexStrideY * texHeight;
+ int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf;
+ int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * texHeight/2;
+ int yuvTexStrideU = yuvTexStrideV;
+
+ uint8_t* img = NULL;
+ buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
+
+ // Gray out all the test pixels first, so we're more likely to
+ // see a failure if GL is still texturing from the buffer we
+ // just dequeued.
+ for (int j = 0; j < numTestPixels; j++) {
+ int x = mTestPixels[j].x;
+ int y = mTestPixels[j].y;
+ uint8_t value = 128;
+ img[y*stride + x] = value;
+ }
+
+ // Fill the buffer with gray.
+ for (int y = 0; y < texHeight; y++) {
+ for (int x = 0; x < texWidth; x++) {
+ img[yuvTexOffsetY + y*yuvTexStrideY + x] = 128;
+ img[yuvTexOffsetU + (y/2)*yuvTexStrideU + x/2] = 128;
+ img[yuvTexOffsetV + (y/2)*yuvTexStrideV + x/2] = 128;
+ }
+ }
+
+ // Set the test pixels to either white or black.
+ for (int j = 0; j < numTestPixels; j++) {
+ int x = mTestPixels[j].x;
+ int y = mTestPixels[j].y;
+ uint8_t value = 0;
+ if (j == (i % numTestPixels)) {
+ value = 255;
+ }
+ img[y*stride + x] = value;
+ }
+
+ buf->unlock();
+ if (mANW->queueBuffer(mANW.get(), buf->getNativeBuffer())
+ != NO_ERROR) {
+ return false;
+ }
+ }
+ return false;
+ }
+
+ sp<ANativeWindow> mANW;
+ const TestPixel* mTestPixels;
+ };
+
+ sp<FrameWaiter> fw(new FrameWaiter);
+ mST->setFrameAvailableListener(fw);
+
+ sp<Thread> pt(new ProducerThread(mANW, testPixels));
+ pt->run();
+
+ glViewport(0, 0, texWidth, texHeight);
+
+ glClearColor(0.2, 0.2, 0.2, 0.2);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ // We wait for the first two frames up front so that the producer will be
+ // likely to dequeue the buffer that's currently being textured from.
+ fw->waitForFrame();
+ fw->waitForFrame();
+
+ for (int i = 0; i < numFrames; i++) {
+ SCOPED_TRACE(String8::format("frame %d", i).string());
+
+ // We must wait for each frame to come in because if we ever do an
+ // updateTexImage call that doesn't consume a newly available buffer
+ // then the producer and consumer will get out of sync, which will cause
+ // a deadlock.
+ if (i > 1) {
+ fw->waitForFrame();
+ }
+ mST->updateTexImage();
+ drawTexture();
+
+ for (int j = 0; j < numTestPixels; j++) {
+ int x = testPixels[j].x;
+ int y = testPixels[j].y;
+ uint8_t value = 0;
+ if (j == (i % numTestPixels)) {
+ // We must y-invert the texture coords
+ EXPECT_TRUE(checkPixel(x, texHeight-y-1, 255, 255, 255, 255));
+ } else {
+ // We must y-invert the texture coords
+ EXPECT_TRUE(checkPixel(x, texHeight-y-1, 0, 0, 0, 255));
+ }
+ }
+ }
+
+ pt->requestExitAndWait();
+}
+
// XXX: This test is disabled because there are currently no drivers that can
// handle RGBA textures with the GL_TEXTURE_EXTERNAL_OES target.
TEST_F(SurfaceTextureGLTest, DISABLED_TexturingFromCpuFilledRGBABufferNpot) {
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index e43f6e55fb23..8b1caeeedf59 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -699,9 +699,10 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level)
float* vertices = getFloats(verticesCount);
bool hasColors = getInt();
int* colors = hasColors ? getInts(colorsCount) : NULL;
+ SkPaint* paint = getPaint();
DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
- renderer.drawBitmapMesh(bitmap, meshWidth, meshHeight, vertices, colors, getPaint());
+ renderer.drawBitmapMesh(bitmap, meshWidth, meshHeight, vertices, colors, paint);
}
break;
case DrawPatch: {
@@ -718,9 +719,15 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level)
yDivs = getInts(yDivsCount);
colors = getUInts(numColors);
+ float left = getFloat();
+ float top = getFloat();
+ float right = getFloat();
+ float bottom = getFloat();
+ SkPaint* paint = getPaint();
+
DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
renderer.drawPatch(bitmap, xDivs, yDivs, colors, xDivsCount, yDivsCount,
- numColors, getFloat(), getFloat(), getFloat(), getFloat(), getPaint());
+ numColors, left, top, right, bottom, paint);
}
break;
case DrawColor: {
@@ -799,15 +806,17 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level)
case DrawLines: {
int count = 0;
float* points = getFloats(count);
+ SkPaint* paint = getPaint();
DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
- renderer.drawLines(points, count, getPaint());
+ renderer.drawLines(points, count, paint);
}
break;
case DrawPoints: {
int count = 0;
float* points = getFloats(count);
+ SkPaint* paint = getPaint();
DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
- renderer.drawPoints(points, count, getPaint());
+ renderer.drawPoints(points, count, paint);
}
break;
case DrawText: {
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index d628301b5b71..513eda82f868 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -29,6 +29,7 @@
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/NativeWindowWrapper.h>
#include <media/stagefright/OMXClient.h>
+#include <media/stagefright/OMXCodec.h>
#include <surfaceflinger/Surface.h>
#include <gui/SurfaceTextureClient.h>
@@ -401,11 +402,22 @@ status_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
CHECK(mem.get() != NULL);
IOMX::buffer_id buffer;
-#if 0
- err = mOMX->allocateBufferWithBackup(mNode, portIndex, mem, &buffer);
-#else
- err = mOMX->useBuffer(mNode, portIndex, mem, &buffer);
-#endif
+
+ if (!strcasecmp(
+ mComponentName.c_str(), "OMX.TI.DUCATI1.VIDEO.DECODER")) {
+ if (portIndex == kPortIndexInput && i == 0) {
+ // Only log this warning once per allocation round.
+
+ LOGW("OMX.TI.DUCATI1.VIDEO.DECODER requires the use of "
+ "OMX_AllocateBuffer instead of the preferred "
+ "OMX_UseBuffer. Vendor must fix this.");
+ }
+
+ err = mOMX->allocateBufferWithBackup(
+ mNode, portIndex, mem, &buffer);
+ } else {
+ err = mOMX->useBuffer(mNode, portIndex, mem, &buffer);
+ }
if (err != OK) {
return err;
@@ -891,6 +903,7 @@ status_t ACodec::setSupportedOutputFormat() {
CHECK(format.eColorFormat == OMX_COLOR_FormatYUV420Planar
|| format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
|| format.eColorFormat == OMX_COLOR_FormatCbYCrY
+ || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar
|| format.eColorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar);
return mOMX->setParameter(
@@ -1639,27 +1652,33 @@ void ACodec::UninitializedState::onSetup(
AString mime;
CHECK(msg->findString("mime", &mime));
+ Vector<String8> matchingCodecs;
+ OMXCodec::findMatchingCodecs(
+ mime.c_str(),
+ false, // createEncoder
+ NULL, // matchComponentName
+ 0, // flags
+ &matchingCodecs);
+
+ sp<CodecObserver> observer = new CodecObserver;
+ IOMX::node_id node = NULL;
+
AString componentName;
- if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) {
- componentName = "OMX.Nvidia.h264.decode";
- } else if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)) {
- componentName = "OMX.google.aac.decoder";
- } else if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_MPEG)) {
- componentName = "OMX.Nvidia.mp3.decoder";
- } else if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_MPEG2)) {
- componentName = "OMX.Nvidia.mpeg2v.decode";
- } else if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_MPEG4)) {
- componentName = "OMX.google.mpeg4.decoder";
- } else {
- TRESPASS();
- }
+ for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
+ ++matchIndex) {
+ componentName = matchingCodecs.itemAt(matchIndex).string();
- sp<CodecObserver> observer = new CodecObserver;
+ status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
- IOMX::node_id node;
- CHECK_EQ(omx->allocateNode(componentName.c_str(), observer, &node),
- (status_t)OK);
+ if (err == OK) {
+ break;
+ }
+
+ node = NULL;
+ }
+
+ CHECK(node != NULL);
sp<AMessage> notify = new AMessage(kWhatOMXMessage, mCodec->id());
observer->setNotificationMessage(notify);
diff --git a/media/libstagefright/MPEG2TSWriter.cpp b/media/libstagefright/MPEG2TSWriter.cpp
index 4e4f2898b622..02eeb40030c4 100644
--- a/media/libstagefright/MPEG2TSWriter.cpp
+++ b/media/libstagefright/MPEG2TSWriter.cpp
@@ -466,6 +466,8 @@ bool MPEG2TSWriter::SourceInfo::eosReceived() const {
MPEG2TSWriter::MPEG2TSWriter(int fd)
: mFile(fdopen(dup(fd), "wb")),
+ mWriteCookie(NULL),
+ mWriteFunc(NULL),
mStarted(false),
mNumSourcesDone(0),
mNumTSPacketsWritten(0),
@@ -475,6 +477,21 @@ MPEG2TSWriter::MPEG2TSWriter(int fd)
MPEG2TSWriter::MPEG2TSWriter(const char *filename)
: mFile(fopen(filename, "wb")),
+ mWriteCookie(NULL),
+ mWriteFunc(NULL),
+ mStarted(false),
+ mNumSourcesDone(0),
+ mNumTSPacketsWritten(0),
+ mNumTSPacketsBeforeMeta(0) {
+ init();
+}
+
+MPEG2TSWriter::MPEG2TSWriter(
+ void *cookie,
+ ssize_t (*write)(void *cookie, const void *data, size_t size))
+ : mFile(NULL),
+ mWriteCookie(cookie),
+ mWriteFunc(write),
mStarted(false),
mNumSourcesDone(0),
mNumTSPacketsWritten(0),
@@ -483,7 +500,7 @@ MPEG2TSWriter::MPEG2TSWriter(const char *filename)
}
void MPEG2TSWriter::init() {
- CHECK(mFile != NULL);
+ CHECK(mFile != NULL || mWriteFunc != NULL);
mLooper = new ALooper;
mLooper->setName("MPEG2TSWriter");
@@ -502,8 +519,10 @@ MPEG2TSWriter::~MPEG2TSWriter() {
mLooper->unregisterHandler(mReflector->id());
mLooper->stop();
- fclose(mFile);
- mFile = NULL;
+ if (mFile != NULL) {
+ fclose(mFile);
+ mFile = NULL;
+ }
}
status_t MPEG2TSWriter::addSource(const sp<MediaSource> &source) {
@@ -718,7 +737,7 @@ void MPEG2TSWriter::writeProgramAssociationTable() {
static const unsigned kContinuityCounter = 5;
buffer->data()[3] |= kContinuityCounter;
- CHECK_EQ(fwrite(buffer->data(), 1, buffer->size(), mFile), buffer->size());
+ CHECK_EQ(internalWrite(buffer->data(), buffer->size()), buffer->size());
}
void MPEG2TSWriter::writeProgramMap() {
@@ -794,7 +813,7 @@ void MPEG2TSWriter::writeProgramMap() {
*ptr++ = 0x00;
*ptr++ = 0x00;
- CHECK_EQ(fwrite(buffer->data(), 1, buffer->size(), mFile), buffer->size());
+ CHECK_EQ(internalWrite(buffer->data(), buffer->size()), buffer->size());
}
void MPEG2TSWriter::writeAccessUnit(
@@ -890,7 +909,7 @@ void MPEG2TSWriter::writeAccessUnit(
memcpy(ptr, accessUnit->data(), copy);
- CHECK_EQ(fwrite(buffer->data(), 1, buffer->size(), mFile), buffer->size());
+ CHECK_EQ(internalWrite(buffer->data(), buffer->size()), buffer->size());
size_t offset = copy;
while (offset < accessUnit->size()) {
@@ -923,7 +942,7 @@ void MPEG2TSWriter::writeAccessUnit(
}
memcpy(ptr, accessUnit->data() + offset, copy);
- CHECK_EQ(fwrite(buffer->data(), 1, buffer->size(), mFile),
+ CHECK_EQ(internalWrite(buffer->data(), buffer->size()),
buffer->size());
offset += copy;
@@ -939,5 +958,13 @@ void MPEG2TSWriter::writeTS() {
}
}
+ssize_t MPEG2TSWriter::internalWrite(const void *data, size_t size) {
+ if (mFile != NULL) {
+ return fwrite(data, 1, size, mFile);
+ }
+
+ return (*mWriteFunc)(mWriteCookie, data, size);
+}
+
} // namespace android
diff --git a/native/include/android/input.h b/native/include/android/input.h
index 26cac50cb169..0d8ea2841ea5 100644
--- a/native/include/android/input.h
+++ b/native/include/android/input.h
@@ -404,7 +404,6 @@ enum {
AMOTION_EVENT_BUTTON_TERTIARY = 1 << 2,
AMOTION_EVENT_BUTTON_BACK = 1 << 3,
AMOTION_EVENT_BUTTON_FORWARD = 1 << 4,
- AMOTION_EVENT_BUTTON_ERASER = 1 << 5,
};
/*
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index a9aa31b61284..946960122565 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -531,7 +531,12 @@ public class SettingsBackupAgent extends BackupAgentHelper {
private void restoreFileData(String filename, BackupDataInput data) {
byte[] bytes = new byte[data.getDataSize()];
if (bytes.length <= 0) return;
- restoreFileData(filename, bytes, bytes.length);
+ try {
+ data.readEntityData(bytes, 0, data.getDataSize());
+ restoreFileData(filename, bytes, bytes.length);
+ } catch (IOException e) {
+ Log.w(TAG, "Unable to read file data for " + filename);
+ }
}
private void restoreFileData(String filename, byte[] bytes, int size) {
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
index eea30407af55..b60bae7d49eb 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -682,8 +682,9 @@ public class LockPatternKeyguardView extends KeyguardViewBase {
final boolean usingLockPattern = mLockPatternUtils.getKeyguardStoredPasswordQuality()
== DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
- boolean showSlidingTab = getResources().getBoolean(R.bool.config_enableSlidingTabFirst);
- if (isSecure() && (usingLockPattern || !showSlidingTab)) {
+ boolean showLockBeforeUnlock = getResources()
+ .getBoolean(R.bool.config_enableLockBeforeUnlockScreen);
+ if (isSecure() && (usingLockPattern || !showLockBeforeUnlock)) {
return Mode.UnlockScreen;
} else {
return Mode.LockScreen;
diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp
index 3e4c66691cb0..5a25f8cc9584 100644
--- a/services/input/InputReader.cpp
+++ b/services/input/InputReader.cpp
@@ -154,14 +154,15 @@ static uint32_t getButtonStateForScanCode(int32_t scanCode) {
case BTN_LEFT:
return AMOTION_EVENT_BUTTON_PRIMARY;
case BTN_RIGHT:
+ case BTN_STYLUS:
return AMOTION_EVENT_BUTTON_SECONDARY;
case BTN_MIDDLE:
+ case BTN_STYLUS2:
return AMOTION_EVENT_BUTTON_TERTIARY;
case BTN_SIDE:
return AMOTION_EVENT_BUTTON_BACK;
- case BTN_EXTRA:
- return AMOTION_EVENT_BUTTON_FORWARD;
case BTN_FORWARD:
+ case BTN_EXTRA:
return AMOTION_EVENT_BUTTON_FORWARD;
case BTN_BACK:
return AMOTION_EVENT_BUTTON_BACK;
@@ -176,8 +177,7 @@ static uint32_t getButtonStateForScanCode(int32_t scanCode) {
static bool isPointerDown(int32_t buttonState) {
return buttonState &
(AMOTION_EVENT_BUTTON_PRIMARY | AMOTION_EVENT_BUTTON_SECONDARY
- | AMOTION_EVENT_BUTTON_TERTIARY
- | AMOTION_EVENT_BUTTON_ERASER);
+ | AMOTION_EVENT_BUTTON_TERTIARY);
}
static int32_t calculateEdgeFlagsUsingPointerBounds(
diff --git a/services/java/com/android/server/am/BatteryStatsService.java b/services/java/com/android/server/am/BatteryStatsService.java
index b4fdc9f3c0ff..293702dfe750 100644
--- a/services/java/com/android/server/am/BatteryStatsService.java
+++ b/services/java/com/android/server/am/BatteryStatsService.java
@@ -446,6 +446,15 @@ public final class BatteryStatsService extends IBatteryStats.Stub {
Binder.getCallingPid(), Binder.getCallingUid(), null);
}
+ private void dumpHelp(PrintWriter pw) {
+ pw.println("Battery stats (batteryinfo) dump options:");
+ pw.println(" [--checkin] [--reset] [--write] [-h]");
+ pw.println(" --checkin: format output for a checkin report.");
+ pw.println(" --reset: reset the stats, clearing all current data.");
+ pw.println(" --write: force write current collected stats to disk.");
+ pw.println(" -h: print this help text.");
+ }
+
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
boolean isCheckin = false;
@@ -466,8 +475,12 @@ public final class BatteryStatsService extends IBatteryStats.Stub {
pw.println("Battery stats written.");
noOutput = true;
}
+ } else if ("-h".equals(arg)) {
+ dumpHelp(pw);
+ return;
} else {
pw.println("Unknown option: " + arg);
+ dumpHelp(pw);
}
}
}
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 2bab6a8fe18b..35e29a6315a8 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -101,9 +101,8 @@ Layer::~Layer()
}
void Layer::onFrameQueued() {
- if (android_atomic_or(1, &mQueuedFrames) == 0) {
- mFlinger->signalEvent();
- }
+ android_atomic_inc(&mQueuedFrames);
+ mFlinger->signalEvent();
}
// called with SurfaceFlinger::mStateLock as soon as the layer is entered
@@ -406,20 +405,18 @@ bool Layer::isCropped() const {
void Layer::lockPageFlip(bool& recomputeVisibleRegions)
{
- if (android_atomic_and(0, &mQueuedFrames)) {
+ if (mQueuedFrames > 0) {
+ // signal another event if we have more frames pending
+ if (android_atomic_dec(&mQueuedFrames) > 1) {
+ mFlinger->signalEvent();
+ }
+
if (mSurfaceTexture->updateTexImage() < NO_ERROR) {
// something happened!
recomputeVisibleRegions = true;
return;
}
- // signal another event if we have more frames waiting
- if (mSurfaceTexture->getQueuedCount()) {
- if (android_atomic_or(1, &mQueuedFrames) == 0) {
- mFlinger->signalEvent();
- }
- }
-
mActiveBuffer = mSurfaceTexture->getCurrentBuffer();
mSurfaceTexture->getTransformMatrix(mTextureMatrix);