summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Android.mk22
-rw-r--r--api/current.txt1
-rw-r--r--core/java/android/app/ActivityManager.java13
-rw-r--r--core/java/android/provider/ContactsContract.java2
-rw-r--r--core/java/android/view/ViewRootImpl.java2
-rw-r--r--core/jni/android/graphics/TextLayoutCache.cpp33
-rw-r--r--core/jni/android/graphics/TextLayoutCache.h10
-rw-r--r--core/jni/android_os_SELinux.cpp10
-rw-r--r--core/jni/android_view_GLES20Canvas.cpp30
-rw-r--r--core/jni/android_view_InputEventReceiver.cpp93
-rw-r--r--docs/html/tools/device.jd4
-rw-r--r--libs/hwui/DeferredDisplayList.cpp13
-rw-r--r--libs/hwui/DisplayListOp.h47
-rw-r--r--libs/hwui/DisplayListRenderer.cpp7
-rw-r--r--libs/hwui/DisplayListRenderer.h3
-rw-r--r--libs/hwui/OpenGLRenderer.cpp49
-rw-r--r--libs/hwui/OpenGLRenderer.h12
-rw-r--r--libs/hwui/Rect.h4
-rw-r--r--media/jni/android_media_MediaDrm.cpp136
-rw-r--r--services/java/com/android/server/accounts/AccountManagerService.java15
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java3
21 files changed, 337 insertions, 172 deletions
diff --git a/Android.mk b/Android.mk
index e06f4a5..fad3f13 100644
--- a/Android.mk
+++ b/Android.mk
@@ -644,28 +644,6 @@ $(full_target): $(framework_built) $(gen)
.PHONY: checkbuild
checkbuild: doc-comment-check-docs
-# ==== static html in the pdk ==================================
-include $(CLEAR_VARS)
-
-LOCAL_INTERMEDIATE_SOURCES:=$(framework_docs_LOCAL_INTERMEDIATE_SOURCES)
-LOCAL_JAVA_LIBRARIES:=$(framework_docs_LOCAL_JAVA_LIBRARIES)
-LOCAL_MODULE_CLASS:=$(framework_docs_LOCAL_MODULE_CLASS)
-LOCAL_DROIDDOC_SOURCE_PATH:=$(framework_docs_LOCAL_DROIDDOC_SOURCE_PATH)
-LOCAL_DROIDDOC_HTML_DIR:=../../vendor/pdk/data/google/docs
-LOCAL_ADDITIONAL_JAVA_DIR:=$(framework_docs_LOCAL_ADDITIONAL_JAVA_DIR)
-LOCAL_ADDITIONAL_DEPENDENCIES:=$(framework_docs_LOCAL_ADDITIONAL_DEPENDENCIES)
-
-LOCAL_MODULE := offline-pdk
-
-LOCAL_DROIDDOC_OPTIONS:=\
- -hdf android.whichdoc offline \
- -hdf android.whichmodule $(LOCAL_MODULE)
-
-LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=build/tools/droiddoc/templates-pdk
-
-include $(BUILD_DROIDDOC)
-
-
# ==== static html in the sdk ==================================
include $(CLEAR_VARS)
diff --git a/api/current.txt b/api/current.txt
index a80c27f..262596a 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -2951,6 +2951,7 @@ package android.app {
field public int id;
field public android.content.ComponentName origActivity;
field public int persistentId;
+ field public int stackId;
}
public static class ActivityManager.RunningAppProcessInfo implements android.os.Parcelable {
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 729ebd7..1f6f421 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -452,14 +452,21 @@ public class ActivityManager {
* Description of the task's last state.
*/
public CharSequence description;
-
+
+ /**
+ * The id of the ActivityStack this Task was on most recently.
+ */
+ public int stackId;
+
public RecentTaskInfo() {
}
+ @Override
public int describeContents() {
return 0;
}
+ @Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id);
dest.writeInt(persistentId);
@@ -472,6 +479,7 @@ public class ActivityManager {
ComponentName.writeToParcel(origActivity, dest);
TextUtils.writeToParcel(description, dest,
Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
+ dest.writeInt(stackId);
}
public void readFromParcel(Parcel source) {
@@ -484,8 +492,9 @@ public class ActivityManager {
}
origActivity = ComponentName.readFromParcel(source);
description = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
+ stackId = source.readInt();
}
-
+
public static final Creator<RecentTaskInfo> CREATOR
= new Creator<RecentTaskInfo>() {
public RecentTaskInfo createFromParcel(Parcel source) {
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index c41c35e..220b997 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -2383,7 +2383,7 @@ public final class ContactsContract {
* parameters. The latter approach is preferable, especially when you can reuse the
* URI:
* <pre>
- * Uri rawContactUri = RawContacts.URI.buildUpon()
+ * Uri rawContactUri = RawContacts.CONTENT_URI.buildUpon()
* .appendQueryParameter(RawContacts.ACCOUNT_NAME, accountName)
* .appendQueryParameter(RawContacts.ACCOUNT_TYPE, accountType)
* .build();
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index fc005d1..0c506d8 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1601,7 +1601,7 @@ public final class ViewRootImpl implements ViewParent,
if (mAttachInfo.mHardwareRenderer != null &&
mAttachInfo.mHardwareRenderer.isEnabled()) {
- if (hwInitialized || windowShouldResize ||
+ if (hwInitialized ||
mWidth != mAttachInfo.mHardwareRenderer.getWidth() ||
mHeight != mAttachInfo.mHardwareRenderer.getHeight()) {
mAttachInfo.mHardwareRenderer.setup(mWidth, mHeight);
diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp
index be14f58..cd84fff 100644
--- a/core/jni/android/graphics/TextLayoutCache.cpp
+++ b/core/jni/android/graphics/TextLayoutCache.cpp
@@ -318,6 +318,7 @@ hash_t TextLayoutCacheKey::hash() const {
*/
TextLayoutValue::TextLayoutValue(size_t contextCount) :
mTotalAdvance(0), mElapsedTime(0) {
+ mBounds.setEmpty();
// Give a hint for advances and glyphs vectors size
mAdvances.setCapacity(contextCount);
mGlyphs.setCapacity(contextCount);
@@ -345,11 +346,11 @@ TextLayoutShaper::~TextLayoutShaper() {
hb_buffer_destroy(mBuffer);
}
-void TextLayoutShaper::computeValues(TextLayoutValue* value, const SkPaint* paint, const UChar* chars,
- size_t start, size_t count, size_t contextCount, int dirFlags) {
-
+void TextLayoutShaper::computeValues(TextLayoutValue* value, const SkPaint* paint,
+ const UChar* chars, size_t start, size_t count, size_t contextCount, int dirFlags) {
computeValues(paint, chars, start, count, contextCount, dirFlags,
- &value->mAdvances, &value->mTotalAdvance, &value->mGlyphs, &value->mPos);
+ &value->mAdvances, &value->mTotalAdvance, &value->mBounds,
+ &value->mGlyphs, &value->mPos);
#if DEBUG_ADVANCES
ALOGD("Advances - start = %d, count = %d, contextCount = %d, totalAdvance = %f", start, count,
contextCount, value->mTotalAdvance);
@@ -358,7 +359,7 @@ void TextLayoutShaper::computeValues(TextLayoutValue* value, const SkPaint* pain
void TextLayoutShaper::computeValues(const SkPaint* paint, const UChar* chars,
size_t start, size_t count, size_t contextCount, int dirFlags,
- Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
+ Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance, SkRect* outBounds,
Vector<jchar>* const outGlyphs, Vector<jfloat>* const outPos) {
*outTotalAdvance = 0;
if (!count) {
@@ -454,7 +455,7 @@ void TextLayoutShaper::computeValues(const SkPaint* paint, const UChar* chars,
i, startRun, lengthRun, isRTL);
#endif
computeRunValues(paint, chars, startRun, lengthRun, contextCount, isRTL,
- outAdvances, outTotalAdvance, outGlyphs, outPos);
+ outAdvances, outTotalAdvance, outBounds, outGlyphs, outPos);
}
}
@@ -478,7 +479,7 @@ void TextLayoutShaper::computeValues(const SkPaint* paint, const UChar* chars,
"-- run-start = %d, run-len = %d, isRTL = %d", start, count, isRTL);
#endif
computeRunValues(paint, chars, start, count, contextCount, isRTL,
- outAdvances, outTotalAdvance, outGlyphs, outPos);
+ outAdvances, outTotalAdvance, outBounds, outGlyphs, outPos);
}
#if DEBUG_GLYPHS
@@ -675,7 +676,7 @@ static void logGlyphs(hb_buffer_t* buffer) {
void TextLayoutShaper::computeRunValues(const SkPaint* paint, const UChar* contextChars,
size_t start, size_t count, size_t contextCount, bool isRTL,
- Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
+ Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance, SkRect* outBounds,
Vector<jchar>* const outGlyphs, Vector<jfloat>* const outPos) {
if (!count) {
// We cannot shape an empty run.
@@ -749,12 +750,22 @@ void TextLayoutShaper::computeRunValues(const SkPaint* paint, const UChar* conte
size_t cluster = info[i].cluster - start;
float xAdvance = HBFixedToFloat(positions[i].x_advance);
outAdvances->replaceAt(outAdvances->itemAt(cluster) + xAdvance, cluster);
- outGlyphs->add(info[i].codepoint + glyphBaseCount);
+ jchar glyphId = info[i].codepoint + glyphBaseCount;
+ outGlyphs->add(glyphId);
float xo = HBFixedToFloat(positions[i].x_offset);
float yo = -HBFixedToFloat(positions[i].y_offset);
- outPos->add(totalAdvance + xo + yo * skewX);
- outPos->add(yo);
+
+ float xpos = totalAdvance + xo + yo * skewX;
+ float ypos = yo;
+ outPos->add(xpos);
+ outPos->add(ypos);
totalAdvance += xAdvance;
+
+ // TODO: consider using glyph cache
+ const SkGlyph& metrics = mShapingPaint.getGlyphMetrics(glyphId, NULL);
+ outBounds->join(xpos + metrics.fLeft, ypos + metrics.fTop,
+ xpos + metrics.fLeft + metrics.fWidth, ypos + metrics.fTop + metrics.fHeight);
+
}
}
diff --git a/core/jni/android/graphics/TextLayoutCache.h b/core/jni/android/graphics/TextLayoutCache.h
index 5414a11..ab6ac72 100644
--- a/core/jni/android/graphics/TextLayoutCache.h
+++ b/core/jni/android/graphics/TextLayoutCache.h
@@ -134,6 +134,7 @@ public:
inline const jfloat* getAdvances() const { return mAdvances.array(); }
inline size_t getAdvancesCount() const { return mAdvances.size(); }
inline jfloat getTotalAdvance() const { return mTotalAdvance; }
+ inline const SkRect& getBounds() const { return mBounds; }
inline const jchar* getGlyphs() const { return mGlyphs.array(); }
inline size_t getGlyphsCount() const { return mGlyphs.size(); }
inline const jfloat* getPos() const { return mPos.array(); }
@@ -150,6 +151,11 @@ public:
jfloat mTotalAdvance;
/**
+ * Bounds containing all glyphs
+ */
+ SkRect mBounds;
+
+ /**
* Glyphs vector
*/
Vector<jchar> mGlyphs;
@@ -208,12 +214,12 @@ private:
void computeValues(const SkPaint* paint, const UChar* chars,
size_t start, size_t count, size_t contextCount, int dirFlags,
- Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
+ Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance, SkRect* outBounds,
Vector<jchar>* const outGlyphs, Vector<jfloat>* const outPos);
void computeRunValues(const SkPaint* paint, const UChar* chars,
size_t start, size_t count, size_t contextCount, bool isRTL,
- Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
+ Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance, SkRect* outBounds,
Vector<jchar>* const outGlyphs, Vector<jfloat>* const outPos);
SkTypeface* setCachedTypeface(SkTypeface** typeface, hb_script_t script, SkTypeface::Style style);
diff --git a/core/jni/android_os_SELinux.cpp b/core/jni/android_os_SELinux.cpp
index 0a97f39..ca278cf 100644
--- a/core/jni/android_os_SELinux.cpp
+++ b/core/jni/android_os_SELinux.cpp
@@ -102,7 +102,7 @@ static jstring getPeerCon(JNIEnv *env, jobject, jobject fileDescriptor) {
return NULL;
}
- security_context_t tmp;
+ security_context_t tmp = NULL;
int ret = getpeercon(fd, &tmp);
Unique_SecurityContext context(tmp);
@@ -111,7 +111,7 @@ static jstring getPeerCon(JNIEnv *env, jobject, jobject fileDescriptor) {
contextStr.reset(env->NewStringUTF(context.get()));
}
- ALOGV("getPeerCon(%d) => %s", fd, contextStr.get());
+ ALOGV("getPeerCon(%d) => %s", fd, context.get());
return contextStr.release();
}
@@ -198,7 +198,7 @@ static jstring getFileCon(JNIEnv *env, jobject, jstring pathStr) {
return NULL;
}
- security_context_t tmp;
+ security_context_t tmp = NULL;
int ret = getfilecon(path.c_str(), &tmp);
Unique_SecurityContext context(tmp);
@@ -224,7 +224,7 @@ static jstring getCon(JNIEnv *env, jobject) {
return NULL;
}
- security_context_t tmp;
+ security_context_t tmp = NULL;
int ret = getcon(&tmp);
Unique_SecurityContext context(tmp);
@@ -251,7 +251,7 @@ static jstring getPidCon(JNIEnv *env, jobject, jint pid) {
return NULL;
}
- security_context_t tmp;
+ security_context_t tmp = NULL;
int ret = getpidcon(static_cast<pid_t>(pid), &tmp);
Unique_SecurityContext context(tmp);
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index cd7a032..983a838 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -574,6 +574,20 @@ static void android_view_GLES20Canvas_resetPaintFilter(JNIEnv* env, jobject claz
// Text
// ----------------------------------------------------------------------------
+static float xOffsetForTextAlign(SkPaint* paint, float totalAdvance) {
+ switch (paint->getTextAlign()) {
+ case SkPaint::kCenter_Align:
+ return -totalAdvance / 2.0f;
+ break;
+ case SkPaint::kRight_Align:
+ return -totalAdvance;
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
static void renderText(OpenGLRenderer* renderer, const jchar* text, int count,
jfloat x, jfloat y, int flags, SkPaint* paint) {
sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(paint,
@@ -586,8 +600,12 @@ static void renderText(OpenGLRenderer* renderer, const jchar* text, int count,
jfloat totalAdvance = value->getTotalAdvance();
const float* positions = value->getPos();
int bytesCount = glyphsCount * sizeof(jchar);
- renderer->drawText((const char*) glyphs, bytesCount, glyphsCount, x, y,
- positions, paint, totalAdvance);
+ const SkRect& r = value->getBounds();
+ android::uirenderer::Rect bounds(r.fLeft, r.fTop, r.fRight, r.fBottom);
+
+ renderer->drawText((const char*) glyphs, bytesCount, glyphsCount,
+ x + xOffsetForTextAlign(paint, totalAdvance), y, positions,
+ paint, totalAdvance, bounds);
}
static void renderTextOnPath(OpenGLRenderer* renderer, const jchar* text, int count,
@@ -617,8 +635,12 @@ static void renderTextRun(OpenGLRenderer* renderer, const jchar* text,
jfloat totalAdvance = value->getTotalAdvance();
const float* positions = value->getPos();
int bytesCount = glyphsCount * sizeof(jchar);
- renderer->drawText((const char*) glyphs, bytesCount, glyphsCount, x, y,
- positions, paint, totalAdvance);
+ const SkRect& r = value->getBounds();
+ android::uirenderer::Rect bounds(r.fLeft, r.fTop, r.fRight, r.fBottom);
+
+ renderer->drawText((const char*) glyphs, bytesCount, glyphsCount,
+ x + xOffsetForTextAlign(paint, totalAdvance), y, positions,
+ paint, totalAdvance, bounds);
}
static void android_view_GLES20Canvas_drawTextArray(JNIEnv* env, jobject clazz,
diff --git a/core/jni/android_view_InputEventReceiver.cpp b/core/jni/android_view_InputEventReceiver.cpp
index c350521..8e1e04a 100644
--- a/core/jni/android_view_InputEventReceiver.cpp
+++ b/core/jni/android_view_InputEventReceiver.cpp
@@ -27,6 +27,7 @@
#include <android_runtime/AndroidRuntime.h>
#include <utils/Log.h>
#include <utils/Looper.h>
+#include <utils/Vector.h>
#include <utils/threads.h>
#include <androidfw/InputTransport.h>
#include "android_os_MessageQueue.h"
@@ -61,11 +62,20 @@ protected:
virtual ~NativeInputEventReceiver();
private:
+ struct Finish {
+ uint32_t seq;
+ bool handled;
+ };
+
jobject mReceiverWeakGlobal;
InputConsumer mInputConsumer;
sp<MessageQueue> mMessageQueue;
PreallocatedInputEventFactory mInputEventFactory;
bool mBatchedInputEventPending;
+ int mFdEvents;
+ Vector<Finish> mFinishQueue;
+
+ void setFdEvents(int events);
const char* getInputChannelName() {
return mInputConsumer.getChannel()->getName().string();
@@ -80,7 +90,7 @@ NativeInputEventReceiver::NativeInputEventReceiver(JNIEnv* env,
const sp<MessageQueue>& messageQueue) :
mReceiverWeakGlobal(env->NewGlobalRef(receiverWeak)),
mInputConsumer(inputChannel), mMessageQueue(messageQueue),
- mBatchedInputEventPending(false) {
+ mBatchedInputEventPending(false), mFdEvents(0) {
#if DEBUG_DISPATCH_CYCLE
ALOGD("channel '%s' ~ Initializing input event receiver.", getInputChannelName());
#endif
@@ -92,8 +102,7 @@ NativeInputEventReceiver::~NativeInputEventReceiver() {
}
status_t NativeInputEventReceiver::initialize() {
- int receiveFd = mInputConsumer.getChannel()->getFd();
- mMessageQueue->getLooper()->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, this, NULL);
+ setFdEvents(ALOOPER_EVENT_INPUT);
return OK;
}
@@ -102,7 +111,7 @@ void NativeInputEventReceiver::dispose() {
ALOGD("channel '%s' ~ Disposing input event receiver.", getInputChannelName());
#endif
- mMessageQueue->getLooper()->removeFd(mInputConsumer.getChannel()->getFd());
+ setFdEvents(0);
}
status_t NativeInputEventReceiver::finishInputEvent(uint32_t seq, bool handled) {
@@ -112,12 +121,38 @@ status_t NativeInputEventReceiver::finishInputEvent(uint32_t seq, bool handled)
status_t status = mInputConsumer.sendFinishedSignal(seq, handled);
if (status) {
+ if (status == WOULD_BLOCK) {
+#if DEBUG_DISPATCH_CYCLE
+ ALOGD("channel '%s' ~ Could not send finished signal immediately. "
+ "Enqueued for later.", getInputChannelName());
+#endif
+ Finish finish;
+ finish.seq = seq;
+ finish.handled = handled;
+ mFinishQueue.add(finish);
+ if (mFinishQueue.size() == 1) {
+ setFdEvents(ALOOPER_EVENT_INPUT | ALOOPER_EVENT_OUTPUT);
+ }
+ return OK;
+ }
ALOGW("Failed to send finished signal on channel '%s'. status=%d",
getInputChannelName(), status);
}
return status;
}
+void NativeInputEventReceiver::setFdEvents(int events) {
+ if (mFdEvents != events) {
+ mFdEvents = events;
+ int fd = mInputConsumer.getChannel()->getFd();
+ if (events) {
+ mMessageQueue->getLooper()->addFd(fd, 0, events, this, NULL);
+ } else {
+ mMessageQueue->getLooper()->removeFd(fd);
+ }
+ }
+}
+
int NativeInputEventReceiver::handleEvent(int receiveFd, int events, void* data) {
if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
#if DEBUG_DISPATCH_CYCLE
@@ -130,16 +165,52 @@ int NativeInputEventReceiver::handleEvent(int receiveFd, int events, void* data)
return 0; // remove the callback
}
- if (!(events & ALOOPER_EVENT_INPUT)) {
- ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
- "events=0x%x", getInputChannelName(), events);
+ if (events & ALOOPER_EVENT_INPUT) {
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
+ status_t status = consumeEvents(env, false /*consumeBatches*/, -1);
+ mMessageQueue->raiseAndClearException(env, "handleReceiveCallback");
+ return status == OK || status == NO_MEMORY ? 1 : 0;
+ }
+
+ if (events & ALOOPER_EVENT_OUTPUT) {
+ for (size_t i = 0; i < mFinishQueue.size(); i++) {
+ const Finish& finish = mFinishQueue.itemAt(i);
+ status_t status = mInputConsumer.sendFinishedSignal(finish.seq, finish.handled);
+ if (status) {
+ mFinishQueue.removeItemsAt(0, i);
+
+ if (status == WOULD_BLOCK) {
+#if DEBUG_DISPATCH_CYCLE
+ ALOGD("channel '%s' ~ Sent %u queued finish events; %u left.",
+ getInputChannelName(), i, mFinishQueue.size());
+#endif
+ return 1; // keep the callback, try again later
+ }
+
+ ALOGW("Failed to send finished signal on channel '%s'. status=%d",
+ getInputChannelName(), status);
+ if (status != DEAD_OBJECT) {
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
+ String8 message;
+ message.appendFormat("Failed to finish input event. status=%d", status);
+ jniThrowRuntimeException(env, message.string());
+ mMessageQueue->raiseAndClearException(env, "finishInputEvent");
+ }
+ return 0; // remove the callback
+ }
+ }
+#if DEBUG_DISPATCH_CYCLE
+ ALOGD("channel '%s' ~ Sent %u queued finish events; none left.",
+ getInputChannelName(), mFinishQueue.size());
+#endif
+ mFinishQueue.clear();
+ setFdEvents(ALOOPER_EVENT_INPUT);
return 1;
}
- JNIEnv* env = AndroidRuntime::getJNIEnv();
- status_t status = consumeEvents(env, false /*consumeBatches*/, -1);
- mMessageQueue->raiseAndClearException(env, "handleReceiveCallback");
- return status == OK || status == NO_MEMORY ? 1 : 0;
+ ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
+ "events=0x%x", getInputChannelName(), events);
+ return 1;
}
status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env,
diff --git a/docs/html/tools/device.jd b/docs/html/tools/device.jd
index c7827b2..a1fb817 100644
--- a/docs/html/tools/device.jd
+++ b/docs/html/tools/device.jd
@@ -177,6 +177,10 @@ above.</p>
<td><code>18d1</code></td>
</tr>
<tr>
+ <td>Haier</td>
+ <td><code>201E</code></td>
+ </tr>
+ <tr>
<td>Hisense</td>
<td><code>109b</code></td>
</tr>
diff --git a/libs/hwui/DeferredDisplayList.cpp b/libs/hwui/DeferredDisplayList.cpp
index 9323a3a..512d3b1 100644
--- a/libs/hwui/DeferredDisplayList.cpp
+++ b/libs/hwui/DeferredDisplayList.cpp
@@ -85,8 +85,8 @@ public:
}
virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int index) {
- DEFER_LOGD("%d replaying DrawingBatch %p, with %d ops (batch id %x, merge id %p)",
- index, this, mOps.size(), mOps[0]->getBatchId(), mOps[0]->getMergeId());
+ DEFER_LOGD("%d replaying DrawBatch %p, with %d ops (batch id %x, merge id %p)",
+ index, this, mOps.size(), getBatchId(), getMergeId());
status_t status = DrawGlInfo::kStatusDone;
DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
@@ -145,7 +145,10 @@ public:
* dropped, so we make simplifying qualifications on the ops that can merge, per op type.
*/
bool canMergeWith(DrawOp* op) {
- if (!op->state.mMatrix.isPureTranslate()) return false;
+ if (getBatchId() == DeferredDisplayList::kOpBatch_Bitmap) {
+ // Bitmap batches can handle translate and scaling
+ if (!op->state.mMatrix.isSimple()) return false;
+ } else if (!op->state.mMatrix.isPureTranslate()) return false;
bool isTextBatch = getBatchId() == DeferredDisplayList::kOpBatch_Text ||
getBatchId() == DeferredDisplayList::kOpBatch_ColorText;
@@ -193,10 +196,10 @@ public:
}
virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int index) {
- DEFER_LOGD("%d replaying DrawingBatch %p, with %d ops (batch id %x, merge id %p)",
+ DEFER_LOGD("%d replaying MergingDrawBatch %p, with %d ops (batch id %x, merge id %p)",
index, this, mOps.size(), getBatchId(), getMergeId());
if (mOps.size() == 1) {
- return DrawBatch::replay(renderer, dirty, false);
+ return DrawBatch::replay(renderer, dirty, 0);
}
DrawOp* op = mOps[0];
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index 990372e..6839b18 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -220,6 +220,9 @@ public:
DrawBoundedOp(float left, float top, float right, float bottom, SkPaint* paint)
: DrawOp(paint), mLocalBounds(left, top, right, bottom) {}
+ DrawBoundedOp(const Rect& localBounds, SkPaint* paint)
+ : DrawOp(paint), mLocalBounds(localBounds) {}
+
// Calculates bounds as smallest rect encompassing all points
// NOTE: requires at least 1 vertex, and doesn't account for stroke size (should be handled in
// subclass' constructor)
@@ -757,10 +760,16 @@ public:
TextureVertex vertices[6 * ops.size()];
TextureVertex* vertex = &vertices[0];
+ bool transformed = false;
+
// TODO: manually handle rect clip for bitmaps by adjusting texCoords per op,
// and allowing them to be merged in getBatchId()
for (unsigned int i = 0; i < ops.size(); i++) {
const Rect& opBounds = ops[i]->state.mBounds;
+ // When we reach multiDraw(), the matrix can be either
+ // pureTranslate or simple (translate and/or scale).
+ // If the matrix is not pureTranslate, then we have a scale
+ if (!ops[i]->state.mMatrix.isPureTranslate()) transformed = true;
Rect texCoords(0, 0, 1, 1);
((DrawBitmapOp*) ops[i])->mUvMapper.map(texCoords);
@@ -774,7 +783,8 @@ public:
SET_TEXTURE(vertex, opBounds, bounds, texCoords, right, bottom);
}
- return renderer.drawBitmaps(mBitmap, ops.size(), &vertices[0], bounds, mPaint);
+ return renderer.drawBitmaps(mBitmap, ops.size(), &vertices[0],
+ transformed, bounds, mPaint);
}
virtual void output(int level, uint32_t logFlags) {
@@ -783,13 +793,18 @@ public:
virtual const char* name() { return "DrawBitmap"; }
+ bool bitmapMergeAllowed() {
+ return state.mMatrix.isSimple() && !state.mClipped &&
+ OpenGLRenderer::getXfermodeDirect(mPaint) == SkXfermode::kSrcOver_Mode;
+ }
+
virtual bool onDefer(OpenGLRenderer& renderer, int* batchId, mergeid_t* mergeId) {
*batchId = DeferredDisplayList::kOpBatch_Bitmap;
*mergeId = mAtlasEntry ? (mergeid_t) &mAtlasEntry->atlas : (mergeid_t) mBitmap;
// don't merge A8 bitmaps - the paint's color isn't compared by mergeId, or in
// MergingDrawBatch::canMergeWith
- return mergeAllowed() && (mBitmap->getConfig() != SkBitmap::kA8_Config);
+ return bitmapMergeAllowed() && (mBitmap->getConfig() != SkBitmap::kA8_Config);
}
const SkBitmap* bitmap() { return mBitmap; }
@@ -1272,23 +1287,10 @@ private:
class DrawTextOp : public DrawBoundedOp {
public:
DrawTextOp(const char* text, int bytesCount, int count, float x, float y,
- const float* positions, SkPaint* paint, float length)
- : DrawBoundedOp(paint), mText(text), mBytesCount(bytesCount), mCount(count),
- mX(x), mY(y), mPositions(positions), mLength(length) {
- // duplicates bounds calculation from OpenGLRenderer::drawText, but doesn't alter mX
- SkPaint::FontMetrics metrics;
- paint->getFontMetrics(&metrics, 0.0f);
- switch (paint->getTextAlign()) {
- case SkPaint::kCenter_Align:
- x -= length / 2.0f;
- break;
- case SkPaint::kRight_Align:
- x -= length;
- break;
- default:
- break;
- }
- mLocalBounds.set(x, mY + metrics.fTop, x + length, mY + metrics.fBottom);
+ const float* positions, SkPaint* paint, float totalAdvance, const Rect& bounds)
+ : DrawBoundedOp(bounds, paint), mText(text), mBytesCount(bytesCount), mCount(count),
+ mX(x), mY(y), mPositions(positions), mTotalAdvance(totalAdvance) {
+ mLocalBounds.translate(x,y);
memset(&mPrecacheTransform.data[0], 0xff, 16 * sizeof(float));
}
@@ -1314,7 +1316,7 @@ public:
virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
return renderer.drawText(mText, mBytesCount, mCount, mX, mY,
- mPositions, getPaint(renderer), mLength);
+ mPositions, getPaint(renderer), mTotalAdvance, mLocalBounds);
}
virtual status_t multiDraw(OpenGLRenderer& renderer, Rect& dirty,
@@ -1327,7 +1329,8 @@ public:
DrawTextOp& op = *((DrawTextOp*)ops[i]);
status |= renderer.drawText(op.mText, op.mBytesCount, op.mCount, op.mX, op.mY,
- op.mPositions, op.getPaint(renderer), op.mLength, drawOpMode);
+ op.mPositions, op.getPaint(renderer), op.mTotalAdvance, op.mLocalBounds,
+ drawOpMode);
}
return status;
}
@@ -1345,7 +1348,7 @@ private:
float mX;
float mY;
const float* mPositions;
- float mLength;
+ float mTotalAdvance;
mat4 mPrecacheTransform;
};
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index bfd4086..6d85a16 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -420,17 +420,16 @@ status_t DisplayListRenderer::drawPosText(const char* text, int bytesCount, int
status_t DisplayListRenderer::drawText(const char* text, int bytesCount, int count,
float x, float y, const float* positions, SkPaint* paint,
- float length, DrawOpMode drawOpMode) {
+ float totalAdvance, const Rect& bounds, DrawOpMode drawOpMode) {
if (!text || count <= 0) return DrawGlInfo::kStatusDone;
- if (length < 0.0f) length = paint->measureText(text, bytesCount);
-
text = refText(text, bytesCount);
positions = refBuffer<float>(positions, count * 2);
paint = refPaint(paint);
- DrawOp* op = new (alloc()) DrawTextOp(text, bytesCount, count, x, y, positions, paint, length);
+ DrawOp* op = new (alloc()) DrawTextOp(text, bytesCount, count,
+ x, y, positions, paint, totalAdvance, bounds);
addDrawOp(op);
return DrawGlInfo::kStatusDone;
}
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index db08921..85d6107 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -121,7 +121,8 @@ public:
virtual status_t drawPosText(const char* text, int bytesCount, int count,
const float* positions, SkPaint* paint);
virtual status_t drawText(const char* text, int bytesCount, int count, float x, float y,
- const float* positions, SkPaint* paint, float length, DrawOpMode drawOpMode);
+ const float* positions, SkPaint* paint, float totalAdvance, const Rect& bounds,
+ DrawOpMode drawOpMode);
virtual status_t drawRects(const float* rects, int count, SkPaint* paint);
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 038df07..2465b48 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -1359,11 +1359,15 @@ bool OpenGLRenderer::storeDisplayState(DeferredDisplayState& state, int stateDef
// state has bounds initialized in local coordinates
if (!state.mBounds.isEmpty()) {
currentMatrix.mapRect(state.mBounds);
+ state.mClipped = !currentClip.contains(state.mBounds);
if (!state.mBounds.intersect(currentClip)) {
// quick rejected
return true;
}
} else {
+ // If we don't have bounds, let's assume we're clipped
+ // to prevent merging
+ state.mClipped = true;
state.mBounds.set(currentClip);
}
}
@@ -2010,7 +2014,7 @@ void OpenGLRenderer::drawAlphaBitmap(Texture* texture, float left, float top, Sk
}
status_t OpenGLRenderer::drawBitmaps(SkBitmap* bitmap, int bitmapCount, TextureVertex* vertices,
- const Rect& bounds, SkPaint* paint) {
+ bool transformed, const Rect& bounds, SkPaint* paint) {
// merged draw operations don't need scissor, but clip should still be valid
mCaches.setScissorEnabled(mScissorOptimizationDisabled);
@@ -2026,7 +2030,7 @@ status_t OpenGLRenderer::drawBitmaps(SkBitmap* bitmap, int bitmapCount, TextureV
getAlphaAndMode(paint, &alpha, &mode);
texture->setWrap(GL_CLAMP_TO_EDGE, true);
- texture->setFilter(GL_NEAREST, true); // merged ops are always pure-translation for now
+ texture->setFilter(transformed ? FILTER(paint) : GL_NEAREST, true);
const float x = (int) floorf(bounds.left + 0.5f);
const float y = (int) floorf(bounds.top + 0.5f);
@@ -2846,8 +2850,8 @@ mat4 OpenGLRenderer::findBestFontTransform(const mat4& transform) const {
return fontTransform;
}
-status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
- float x, float y, const float* positions, SkPaint* paint, float length,
+status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count, float x, float y,
+ const float* positions, SkPaint* paint, float totalAdvance, const Rect& bounds,
DrawOpMode drawOpMode) {
if (drawOpMode == kDrawOpMode_Immediate &&
@@ -2855,24 +2859,8 @@ status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
return DrawGlInfo::kStatusDone;
}
- if (length < 0.0f) length = paint->measureText(text, bytesCount);
- switch (paint->getTextAlign()) {
- case SkPaint::kCenter_Align:
- x -= length / 2.0f;
- break;
- case SkPaint::kRight_Align:
- x -= length;
- break;
- default:
- break;
- }
-
- SkPaint::FontMetrics metrics;
- paint->getFontMetrics(&metrics, 0.0f);
if (drawOpMode == kDrawOpMode_Immediate) {
- if (quickReject(x, y + metrics.fTop, x + length, y + metrics.fBottom)) {
- return DrawGlInfo::kStatusDone;
- }
+ if (quickReject(bounds)) return DrawGlInfo::kStatusDone;
} else {
// merged draw operations don't need scissor, but clip should still be valid
mCaches.setScissorEnabled(mScissorOptimizationDisabled);
@@ -2923,7 +2911,7 @@ status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
// TODO: Implement better clipping for scaled/rotated text
const Rect* clip = !pureTranslate ? NULL : mSnapshot->clipRect;
- Rect bounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f);
+ Rect layerBounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f);
bool status;
TextSetupFunctor functor(*this, x, y, pureTranslate, alpha, mode, paint);
@@ -2934,20 +2922,20 @@ status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
SkPaint paintCopy(*paint);
paintCopy.setTextAlign(SkPaint::kLeft_Align);
status = fontRenderer.renderPosText(&paintCopy, clip, text, 0, bytesCount, count, x, y,
- positions, hasActiveLayer ? &bounds : NULL, &functor, forceFinish);
+ positions, hasActiveLayer ? &layerBounds : NULL, &functor, forceFinish);
} else {
status = fontRenderer.renderPosText(paint, clip, text, 0, bytesCount, count, x, y,
- positions, hasActiveLayer ? &bounds : NULL, &functor, forceFinish);
+ positions, hasActiveLayer ? &layerBounds : NULL, &functor, forceFinish);
}
if ((status || drawOpMode != kDrawOpMode_Immediate) && hasActiveLayer) {
if (!pureTranslate) {
- transform.mapRect(bounds);
+ transform.mapRect(layerBounds);
}
- dirtyLayerUnchecked(bounds, getRegion());
+ dirtyLayerUnchecked(layerBounds, getRegion());
}
- drawTextDecorations(text, bytesCount, length, oldX, oldY, paint);
+ drawTextDecorations(text, bytesCount, totalAdvance, oldX, oldY, paint);
return DrawGlInfo::kStatusDrew;
}
@@ -3231,17 +3219,12 @@ void OpenGLRenderer::drawPathTexture(const PathTexture* texture,
#define kStdUnderline_Offset (1.0f / 9.0f)
#define kStdUnderline_Thickness (1.0f / 18.0f)
-void OpenGLRenderer::drawTextDecorations(const char* text, int bytesCount, float length,
+void OpenGLRenderer::drawTextDecorations(const char* text, int bytesCount, float underlineWidth,
float x, float y, SkPaint* paint) {
// Handle underline and strike-through
uint32_t flags = paint->getFlags();
if (flags & (SkPaint::kUnderlineText_Flag | SkPaint::kStrikeThruText_Flag)) {
SkPaint paintCopy(*paint);
- float underlineWidth = length;
- // If length is > 0.0f, we already measured the text for the text alignment
- if (length <= 0.0f) {
- underlineWidth = paintCopy.measureText(text, bytesCount);
- }
if (CC_LIKELY(underlineWidth > 0.0f)) {
const float textSize = paintCopy.getTextSize();
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 597e458..d9ba93a 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -87,6 +87,7 @@ struct DeferredDisplayState {
// the below are set and used by the OpenGLRenderer at record and deferred playback
bool mClipValid;
Rect mClip;
+ bool mClipped;
mat4 mMatrix;
DrawModifiers mDrawModifiers;
float mAlpha;
@@ -241,6 +242,9 @@ public:
ANDROID_API const Rect& getClipBounds();
ANDROID_API bool quickReject(float left, float top, float right, float bottom);
+ bool quickReject(const Rect& bounds) {
+ return quickReject(bounds.left, bounds.top, bounds.right, bounds.bottom);
+ }
bool quickRejectNoScissor(float left, float top, float right, float bottom);
virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
virtual bool clipPath(SkPath* path, SkRegion::Op op);
@@ -252,7 +256,7 @@ public:
virtual status_t drawLayer(Layer* layer, float x, float y);
virtual status_t drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
status_t drawBitmaps(SkBitmap* bitmap, int bitmapCount, TextureVertex* vertices,
- const Rect& bounds, SkPaint* paint);
+ bool transformed, const Rect& bounds, SkPaint* paint);
virtual status_t drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
virtual status_t drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
float srcRight, float srcBottom, float dstLeft, float dstTop,
@@ -280,7 +284,7 @@ public:
virtual status_t drawPosText(const char* text, int bytesCount, int count,
const float* positions, SkPaint* paint);
virtual status_t drawText(const char* text, int bytesCount, int count, float x, float y,
- const float* positions, SkPaint* paint, float length = -1.0f,
+ const float* positions, SkPaint* paint, float totalAdvance, const Rect& bounds,
DrawOpMode drawOpMode = kDrawOpMode_Immediate);
virtual status_t drawRects(const float* rects, int count, SkPaint* paint);
@@ -824,12 +828,12 @@ private:
*
* @param text The text to decor
* @param bytesCount The number of bytes in the text
- * @param length The length in pixels of the text, can be <= 0.0f to force a measurement
+ * @param totalAdvance The total advance in pixels, defines underline/strikethrough length
* @param x The x coordinate where the text will be drawn
* @param y The y coordinate where the text will be drawn
* @param paint The paint to draw the text with
*/
- void drawTextDecorations(const char* text, int bytesCount, float length,
+ void drawTextDecorations(const char* text, int bytesCount, float totalAdvance,
float x, float y, SkPaint* paint);
/**
diff --git a/libs/hwui/Rect.h b/libs/hwui/Rect.h
index f50ac3c..689fe6c0 100644
--- a/libs/hwui/Rect.h
+++ b/libs/hwui/Rect.h
@@ -125,11 +125,11 @@ public:
return intersect(r.left, r.top, r.right, r.bottom);
}
- inline bool contains(float l, float t, float r, float b) {
+ inline bool contains(float l, float t, float r, float b) const {
return l >= left && t >= top && r <= right && b <= bottom;
}
- inline bool contains(const Rect& r) {
+ inline bool contains(const Rect& r) const {
return contains(r.left, r.top, r.right, r.bottom);
}
diff --git a/media/jni/android_media_MediaDrm.cpp b/media/jni/android_media_MediaDrm.cpp
index ec88949..7799ca4 100644
--- a/media/jni/android_media_MediaDrm.cpp
+++ b/media/jni/android_media_MediaDrm.cpp
@@ -87,12 +87,18 @@ struct EntryFields {
};
struct EventTypes {
- int kEventProvisionRequired;
- int kEventKeyRequired;
- int kEventKeyExpired;
- int kEventVendorDefined;
+ jint kEventProvisionRequired;
+ jint kEventKeyRequired;
+ jint kEventKeyExpired;
+ jint kEventVendorDefined;
} gEventTypes;
+struct KeyTypes {
+ jint kKeyTypeStreaming;
+ jint kKeyTypeOffline;
+ jint kKeyTypeRelease;
+} gKeyTypes;
+
struct fields_t {
jfieldID context;
jmethodID post_event;
@@ -128,7 +134,8 @@ JNIDrmListener::JNIDrmListener(JNIEnv* env, jobject thiz, jobject weak_thiz)
jclass clazz = env->GetObjectClass(thiz);
if (clazz == NULL) {
ALOGE("Can't find android/media/MediaDrm");
- jniThrowException(env, "java/lang/Exception", NULL);
+ jniThrowException(env, "java/lang/Exception",
+ "Can't find android/media/MediaDrm");
return;
}
mClass = (jclass)env->NewGlobalRef(clazz);
@@ -408,13 +415,15 @@ static KeyedVector<String8, String8> HashMapToKeyedVector(JNIEnv *env, jobject &
if (entry) {
jobject obj = env->CallObjectMethod(entry, gFields.entry.getKey);
if (!env->IsInstanceOf(obj, clazz)) {
- jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ "HashMap key is not a String");
}
jstring jkey = static_cast<jstring>(obj);
obj = env->CallObjectMethod(entry, gFields.entry.getValue);
if (!env->IsInstanceOf(obj, clazz)) {
- jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ "HashMap value is not a String");
}
jstring jvalue = static_cast<jstring>(obj);
@@ -486,12 +495,12 @@ static sp<JDrm> setDrm(
static bool CheckSession(JNIEnv *env, const sp<IDrm> &drm, jbyteArray const &jsessionId)
{
if (drm == NULL) {
- jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ jniThrowException(env, "java/lang/IllegalStateException", "MediaDrm obj is null");
return false;
}
if (jsessionId == NULL) {
- jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+ jniThrowException(env, "java/lang/IllegalArgumentException", "sessionId is null");
return false;
}
return true;
@@ -521,6 +530,13 @@ static void android_media_MediaDrm_native_init(JNIEnv *env) {
GET_STATIC_FIELD_ID(field, clazz, "EVENT_VENDOR_DEFINED", "I");
gEventTypes.kEventVendorDefined = env->GetStaticIntField(clazz, field);
+ GET_STATIC_FIELD_ID(field, clazz, "KEY_TYPE_STREAMING", "I");
+ gKeyTypes.kKeyTypeStreaming = env->GetStaticIntField(clazz, field);
+ GET_STATIC_FIELD_ID(field, clazz, "KEY_TYPE_OFFLINE", "I");
+ gKeyTypes.kKeyTypeOffline = env->GetStaticIntField(clazz, field);
+ GET_STATIC_FIELD_ID(field, clazz, "KEY_TYPE_RELEASE", "I");
+ gKeyTypes.kKeyTypeRelease = env->GetStaticIntField(clazz, field);
+
FIND_CLASS(clazz, "android/media/MediaDrm$KeyRequest");
GET_FIELD_ID(gFields.keyRequest.data, clazz, "mData", "[B");
GET_FIELD_ID(gFields.keyRequest.defaultUrl, clazz, "mDefaultUrl", "Ljava/lang/String;");
@@ -557,14 +573,15 @@ static void android_media_MediaDrm_native_setup(
jobject weak_this, jbyteArray uuidObj) {
if (uuidObj == NULL) {
- jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+ jniThrowException(env, "java/lang/IllegalArgumentException", "uuid is null");
return;
}
Vector<uint8_t> uuid = JByteArrayToVector(env, uuidObj);
if (uuid.size() != 16) {
- jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ "invalid UUID size, expected 16 bytes");
return;
}
@@ -604,7 +621,7 @@ static jboolean android_media_MediaDrm_isCryptoSchemeSupportedNative(
jniThrowException(
env,
"java/lang/IllegalArgumentException",
- NULL);
+ "invalid UUID size, expected 16 bytes");
return false;
}
@@ -616,7 +633,8 @@ static jbyteArray android_media_MediaDrm_openSession(
sp<IDrm> drm = GetDrm(env, thiz);
if (drm == NULL) {
- jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ jniThrowException(env, "java/lang/IllegalStateException",
+ "MediaDrm obj is null");
return NULL;
}
@@ -666,7 +684,18 @@ static jobject android_media_MediaDrm_getKeyRequest(
mimeType = JStringToString8(env, jmimeType);
}
- DrmPlugin::KeyType keyType = (DrmPlugin::KeyType)jkeyType;
+ DrmPlugin::KeyType keyType;
+ if (jkeyType == gKeyTypes.kKeyTypeStreaming) {
+ keyType = DrmPlugin::kKeyType_Streaming;
+ } else if (jkeyType == gKeyTypes.kKeyTypeOffline) {
+ keyType = DrmPlugin::kKeyType_Offline;
+ } else if (jkeyType == gKeyTypes.kKeyTypeRelease) {
+ keyType = DrmPlugin::kKeyType_Release;
+ } else {
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ "invalid keyType");
+ return NULL;
+ }
KeyedVector<String8, String8> optParams;
if (joptParams != NULL) {
@@ -712,7 +741,8 @@ static jbyteArray android_media_MediaDrm_provideKeyResponse(
Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));
if (jresponse == NULL) {
- jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ "key response is null");
return NULL;
}
Vector<uint8_t> response(JByteArrayToVector(env, jresponse));
@@ -729,7 +759,8 @@ static void android_media_MediaDrm_removeKeys(
sp<IDrm> drm = GetDrm(env, thiz);
if (jkeysetId == NULL) {
- jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ "keySetId is null");
return;
}
@@ -788,7 +819,8 @@ static jobject android_media_MediaDrm_getProvisionRequest(
sp<IDrm> drm = GetDrm(env, thiz);
if (drm == NULL) {
- jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ jniThrowException(env, "java/lang/IllegalStateException",
+ "MediaDrm obj is null");
return NULL;
}
@@ -824,12 +856,14 @@ static void android_media_MediaDrm_provideProvisionResponse(
sp<IDrm> drm = GetDrm(env, thiz);
if (drm == NULL) {
- jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ jniThrowException(env, "java/lang/IllegalStateException",
+ "MediaDrm obj is null");
return;
}
if (jresponse == NULL) {
- jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ "provision response is null");
return;
}
@@ -845,7 +879,8 @@ static jobject android_media_MediaDrm_getSecureStops(
sp<IDrm> drm = GetDrm(env, thiz);
if (drm == NULL) {
- jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ jniThrowException(env, "java/lang/IllegalStateException",
+ "MediaDrm obj is null");
return NULL;
}
@@ -865,7 +900,8 @@ static void android_media_MediaDrm_releaseSecureStops(
sp<IDrm> drm = GetDrm(env, thiz);
if (drm == NULL) {
- jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ jniThrowException(env, "java/lang/IllegalStateException",
+ "MediaDrm obj is null");
return;
}
@@ -881,12 +917,14 @@ static jstring android_media_MediaDrm_getPropertyString(
sp<IDrm> drm = GetDrm(env, thiz);
if (drm == NULL) {
- jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ jniThrowException(env, "java/lang/IllegalStateException",
+ "MediaDrm obj is null");
return NULL;
}
if (jname == NULL) {
- jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ "property name String is null");
return NULL;
}
@@ -907,12 +945,14 @@ static jbyteArray android_media_MediaDrm_getPropertyByteArray(
sp<IDrm> drm = GetDrm(env, thiz);
if (drm == NULL) {
- jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ jniThrowException(env, "java/lang/IllegalStateException",
+ "MediaDrm obj is null");
return NULL;
}
if (jname == NULL) {
- jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ "property name String is null");
return NULL;
}
@@ -933,12 +973,20 @@ static void android_media_MediaDrm_setPropertyString(
sp<IDrm> drm = GetDrm(env, thiz);
if (drm == NULL) {
- jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ jniThrowException(env, "java/lang/IllegalStateException",
+ "MediaDrm obj is null");
return;
}
- if (jname == NULL || jvalue == NULL) {
- jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+ if (jname == NULL) {
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ "property name String is null");
+ return;
+ }
+
+ if (jvalue == NULL) {
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ "property value String is null");
return;
}
@@ -955,12 +1003,20 @@ static void android_media_MediaDrm_setPropertyByteArray(
sp<IDrm> drm = GetDrm(env, thiz);
if (drm == NULL) {
- jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ jniThrowException(env, "java/lang/IllegalStateException",
+ "MediaDrm obj is null");
return;
}
- if (jname == NULL || jvalue == NULL) {
- jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+ if (jname == NULL) {
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ "property name String is null");
+ return;
+ }
+
+ if (jvalue == NULL) {
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ "property value byte array is null");
return;
}
@@ -983,7 +1039,8 @@ static void android_media_MediaDrm_setCipherAlgorithmNative(
}
if (jalgorithm == NULL) {
- jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ "algorithm String is null");
return;
}
@@ -1006,7 +1063,8 @@ static void android_media_MediaDrm_setMacAlgorithmNative(
}
if (jalgorithm == NULL) {
- jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ "algorithm String is null");
return;
}
@@ -1030,7 +1088,8 @@ static jbyteArray android_media_MediaDrm_encryptNative(
}
if (jkeyId == NULL || jinput == NULL || jiv == NULL) {
- jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ "required argument is null");
return NULL;
}
@@ -1058,7 +1117,8 @@ static jbyteArray android_media_MediaDrm_decryptNative(
}
if (jkeyId == NULL || jinput == NULL || jiv == NULL) {
- jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ "required argument is null");
return NULL;
}
@@ -1085,7 +1145,8 @@ static jbyteArray android_media_MediaDrm_signNative(
}
if (jkeyId == NULL || jmessage == NULL) {
- jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ "required argument is null");
return NULL;
}
@@ -1112,7 +1173,8 @@ static jboolean android_media_MediaDrm_verifyNative(
}
if (jkeyId == NULL || jmessage == NULL || jsignature == NULL) {
- jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ "required argument is null");
return false;
}
diff --git a/services/java/com/android/server/accounts/AccountManagerService.java b/services/java/com/android/server/accounts/AccountManagerService.java
index 4f5008d..c5242f0 100644
--- a/services/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/java/com/android/server/accounts/AccountManagerService.java
@@ -2805,12 +2805,19 @@ public class AccountManagerService
if (sharedAccounts == null || sharedAccounts.length == 0) return unfiltered;
String requiredAccountType = "";
try {
- for (String packageName : packages) {
- PackageInfo pi = mPackageManager.getPackageInfo(packageName, 0);
+ // If there's an explicit callingPackage specified, check if that package
+ // opted in to see restricted accounts.
+ if (callingPackage != null) {
+ PackageInfo pi = mPackageManager.getPackageInfo(callingPackage, 0);
if (pi != null && pi.restrictedAccountType != null) {
requiredAccountType = pi.restrictedAccountType;
- // If it matches the package name of the original caller, use this choice.
- if (callingPackage != null && packageName.equals(callingPackage)) {
+ }
+ } else {
+ // Otherwise check if the callingUid has a package that has opted in
+ for (String packageName : packages) {
+ PackageInfo pi = mPackageManager.getPackageInfo(packageName, 0);
+ if (pi != null && pi.restrictedAccountType != null) {
+ requiredAccountType = pi.restrictedAccountType;
break;
}
}
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index d1cc6ba..dcb2984 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -6062,7 +6062,8 @@ public final class ActivityManagerService extends ActivityManagerNative
}
rti.origActivity = tr.origActivity;
rti.description = tr.lastDescription;
-
+ rti.stackId = tr.stack.mStackId;
+
if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
// Check whether this activity is currently available.
try {