Merge "Handle audio focus in HTML5 audio"
diff --git a/core/java/android/app/backup/WallpaperBackupHelper.java b/core/java/android/app/backup/WallpaperBackupHelper.java
index 0c034cf..170171e 100644
--- a/core/java/android/app/backup/WallpaperBackupHelper.java
+++ b/core/java/android/app/backup/WallpaperBackupHelper.java
@@ -35,7 +35,7 @@
*/
public class WallpaperBackupHelper extends FileBackupHelperBase implements BackupHelper {
private static final String TAG = "WallpaperBackupHelper";
- private static final boolean DEBUG = true;
+ private static final boolean DEBUG = false;
// This path must match what the WallpaperManagerService uses
private static final String WALLPAPER_IMAGE = "/data/data/com.android.settings/files/wallpaper";
diff --git a/core/java/android/server/BluetoothHealthProfileHandler.java b/core/java/android/server/BluetoothHealthProfileHandler.java
index 2961fd2..5e93b81 100644
--- a/core/java/android/server/BluetoothHealthProfileHandler.java
+++ b/core/java/android/server/BluetoothHealthProfileHandler.java
@@ -45,8 +45,7 @@
*/
final class BluetoothHealthProfileHandler {
private static final String TAG = "BluetoothHealthProfileHandler";
- /*STOPSHIP*/
- private static final boolean DBG = true;
+ private static final boolean DBG = false;
private static BluetoothHealthProfileHandler sInstance;
private BluetoothService mBluetoothService;
diff --git a/core/java/android/webkit/FindActionModeCallback.java b/core/java/android/webkit/FindActionModeCallback.java
index 7398262..b85fd17 100644
--- a/core/java/android/webkit/FindActionModeCallback.java
+++ b/core/java/android/webkit/FindActionModeCallback.java
@@ -22,16 +22,14 @@
import android.text.Selection;
import android.text.Spannable;
import android.text.TextWatcher;
-import android.webkit.WebView;
-import android.widget.EditText;
-import android.widget.TextView;
import android.view.ActionMode;
import android.view.LayoutInflater;
import android.view.Menu;
-import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
+import android.widget.EditText;
+import android.widget.TextView;
class FindActionModeCallback implements ActionMode.Callback, TextWatcher,
View.OnLongClickListener, View.OnClickListener {
@@ -203,6 +201,7 @@
@Override
public void onDestroyActionMode(ActionMode mode) {
+ mActionMode = null;
mWebView.notifyFindDialogDismissed();
mInput.hideSoftInputFromWindow(mWebView.getWindowToken(), 0);
}
@@ -255,4 +254,13 @@
// Does nothing. Needed to implement TextWatcher.
}
+ public int getActionModeHeight() {
+ if (mActionMode == null) {
+ return 0;
+ }
+ View parent = (View) mCustomView.getParent();
+ return parent != null ? parent.getMeasuredHeight()
+ : mCustomView.getMeasuredHeight();
+ }
+
}
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index d920f27..05d8da2 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -1483,7 +1483,8 @@
private int getVisibleTitleHeightImpl() {
// need to restrict mScrollY due to over scroll
- return Math.max(getTitleHeight() - Math.max(0, mScrollY), 0);
+ return Math.max(getTitleHeight() - Math.max(0, mScrollY),
+ mFindCallback != null ? mFindCallback.getActionModeHeight() : 0);
}
/*
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index c218f23..0d287cf 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -237,9 +237,11 @@
SparseBooleanArray mCheckStates;
/**
- * Running state of which IDs are currently checked
+ * Running state of which IDs are currently checked.
+ * If there is a value for a given key, the checked state for that ID is true
+ * and the value holds the last known position in the adapter for that id.
*/
- LongSparseArray<Boolean> mCheckedIdStates;
+ LongSparseArray<Integer> mCheckedIdStates;
/**
* Controls how the next layout will happen
@@ -472,6 +474,13 @@
static final int OVERSCROLL_LIMIT_DIVISOR = 3;
/**
+ * How many positions in either direction we will search to try to
+ * find a checked item with a stable ID that moved position across
+ * a data set change. If the item isn't found it will be unselected.
+ */
+ private static final int CHECK_POSITION_SEARCH_DISTANCE = 20;
+
+ /**
* Used to request a layout when we changed touch mode
*/
private static final int TOUCH_MODE_UNKNOWN = -1;
@@ -806,7 +815,7 @@
if (adapter != null) {
if (mChoiceMode != CHOICE_MODE_NONE && mAdapter.hasStableIds() &&
mCheckedIdStates == null) {
- mCheckedIdStates = new LongSparseArray<Boolean>();
+ mCheckedIdStates = new LongSparseArray<Integer>();
}
}
@@ -901,7 +910,7 @@
return new long[0];
}
- final LongSparseArray<Boolean> idStates = mCheckedIdStates;
+ final LongSparseArray<Integer> idStates = mCheckedIdStates;
final int count = idStates.size();
final long[] ids = new long[count];
@@ -948,7 +957,7 @@
mCheckStates.put(position, value);
if (mCheckedIdStates != null && mAdapter.hasStableIds()) {
if (value) {
- mCheckedIdStates.put(mAdapter.getItemId(position), Boolean.TRUE);
+ mCheckedIdStates.put(mAdapter.getItemId(position), position);
} else {
mCheckedIdStates.delete(mAdapter.getItemId(position));
}
@@ -980,7 +989,7 @@
if (value) {
mCheckStates.put(position, true);
if (updateIds) {
- mCheckedIdStates.put(mAdapter.getItemId(position), Boolean.TRUE);
+ mCheckedIdStates.put(mAdapter.getItemId(position), position);
}
mCheckedItemCount = 1;
} else if (mCheckStates.size() == 0 || !mCheckStates.valueAt(0)) {
@@ -1010,7 +1019,7 @@
mCheckStates.put(position, newValue);
if (mCheckedIdStates != null && mAdapter.hasStableIds()) {
if (newValue) {
- mCheckedIdStates.put(mAdapter.getItemId(position), Boolean.TRUE);
+ mCheckedIdStates.put(mAdapter.getItemId(position), position);
} else {
mCheckedIdStates.delete(mAdapter.getItemId(position));
}
@@ -1032,7 +1041,7 @@
mCheckStates.put(position, true);
if (mCheckedIdStates != null && mAdapter.hasStableIds()) {
mCheckedIdStates.clear();
- mCheckedIdStates.put(mAdapter.getItemId(position), Boolean.TRUE);
+ mCheckedIdStates.put(mAdapter.getItemId(position), position);
}
mCheckedItemCount = 1;
} else if (mCheckStates.size() == 0 || !mCheckStates.valueAt(0)) {
@@ -1081,7 +1090,7 @@
mCheckStates = new SparseBooleanArray();
}
if (mCheckedIdStates == null && mAdapter != null && mAdapter.hasStableIds()) {
- mCheckedIdStates = new LongSparseArray<Boolean>();
+ mCheckedIdStates = new LongSparseArray<Integer>();
}
// Modal multi-choice mode only has choices when the mode is active. Clear them.
if (mChoiceMode == CHOICE_MODE_MULTIPLE_MODAL) {
@@ -1411,7 +1420,7 @@
boolean inActionMode;
int checkedItemCount;
SparseBooleanArray checkState;
- LongSparseArray<Boolean> checkIdState;
+ LongSparseArray<Integer> checkIdState;
/**
* Constructor called from {@link AbsListView#onSaveInstanceState()}
@@ -1435,10 +1444,14 @@
checkedItemCount = in.readInt();
checkState = in.readSparseBooleanArray();
long[] idState = in.createLongArray();
+ int[] idPositions = in.createIntArray();
- if (idState.length > 0) {
- checkIdState = new LongSparseArray<Boolean>();
- checkIdState.setValues(idState, Boolean.TRUE);
+ final int idLength = idState.length;
+ if (idLength > 0) {
+ checkIdState = new LongSparseArray<Integer>();
+ for (int i = 0; i < idLength; i++) {
+ checkIdState.put(idState[i], idPositions[i]);
+ }
}
}
@@ -1455,6 +1468,15 @@
out.writeInt(checkedItemCount);
out.writeSparseBooleanArray(checkState);
out.writeLongArray(checkIdState != null ? checkIdState.getKeys() : new long[0]);
+
+ int size = checkIdState != null ? checkIdState.size() : 0;
+ int[] idPositions = new int[size];
+ if (size > 0) {
+ for (int i = 0; i < size; i++) {
+ idPositions[i] = checkIdState.valueAt(i);
+ }
+ out.writeIntArray(idPositions);
+ }
}
@Override
@@ -1549,7 +1571,7 @@
ss.checkState = mCheckStates.clone();
}
if (mCheckedIdStates != null) {
- final LongSparseArray<Boolean> idState = new LongSparseArray<Boolean>();
+ final LongSparseArray<Integer> idState = new LongSparseArray<Integer>();
final int count = mCheckedIdStates.size();
for (int i = 0; i < count; i++) {
idState.put(mCheckedIdStates.keyAt(i), mCheckedIdStates.valueAt(i));
@@ -4770,15 +4792,63 @@
return selectedPos >= 0;
}
+ void confirmCheckedPositionsById() {
+ // Clear out the positional check states, we'll rebuild it below from IDs.
+ mCheckStates.clear();
+
+ boolean checkedCountChanged = false;
+ for (int checkedIndex = 0; checkedIndex < mCheckedIdStates.size(); checkedIndex++) {
+ final long id = mCheckedIdStates.keyAt(checkedIndex);
+ final int lastPos = mCheckedIdStates.valueAt(checkedIndex);
+
+ final long lastPosId = mAdapter.getItemId(lastPos);
+ if (id != lastPosId) {
+ // Look around to see if the ID is nearby. If not, uncheck it.
+ final int start = Math.max(0, lastPos - CHECK_POSITION_SEARCH_DISTANCE);
+ final int end = Math.min(lastPos + CHECK_POSITION_SEARCH_DISTANCE, mItemCount);
+ boolean found = false;
+ for (int searchPos = start; searchPos < end; searchPos++) {
+ final long searchId = mAdapter.getItemId(searchPos);
+ if (id == searchId) {
+ found = true;
+ mCheckStates.put(searchPos, true);
+ mCheckedIdStates.setValueAt(checkedIndex, searchPos);
+ break;
+ }
+ }
+
+ if (!found) {
+ mCheckedIdStates.delete(id);
+ checkedIndex--;
+ mCheckedItemCount--;
+ checkedCountChanged = true;
+ if (mChoiceActionMode != null && mMultiChoiceModeCallback != null) {
+ mMultiChoiceModeCallback.onItemCheckedStateChanged(mChoiceActionMode,
+ lastPos, id, false);
+ }
+ }
+ } else {
+ mCheckStates.put(lastPos, true);
+ }
+ }
+
+ if (checkedCountChanged && mChoiceActionMode != null) {
+ mChoiceActionMode.invalidate();
+ }
+ }
+
@Override
protected void handleDataChanged() {
int count = mItemCount;
int lastHandledItemCount = mLastHandledItemCount;
mLastHandledItemCount = mItemCount;
+
+ if (mChoiceMode != CHOICE_MODE_NONE && mAdapter != null && mAdapter.hasStableIds()) {
+ confirmCheckedPositionsById();
+ }
+
if (count > 0) {
-
int newPos;
-
int selectablePos;
// Find the row we are supposed to sync to
diff --git a/core/jni/android/graphics/Canvas.cpp b/core/jni/android/graphics/Canvas.cpp
index 02c5bb3..7724646 100644
--- a/core/jni/android/graphics/Canvas.cpp
+++ b/core/jni/android/graphics/Canvas.cpp
@@ -767,20 +767,17 @@
sp<TextLayoutCacheValue> value;
#if USE_TEXT_LAYOUT_CACHE
- value = TextLayoutCache::getInstance().getValue(paint, textArray, contextCount, flags);
+ value = TextLayoutCache::getInstance().getValue(paint, textArray, start, count,
+ contextCount, flags);
if (value == NULL) {
LOGE("Cannot get TextLayoutCache value");
return ;
}
#else
value = new TextLayoutCacheValue();
- value->computeValues(paint, textArray, contextCount, flags);
+ value->computeValues(paint, textArray, start, count, contextCount, flags);
#endif
- size_t startIndex = 0;
- size_t glyphsCount = 0;
- value->getGlyphsIndexAndCount(start, count, &startIndex, &glyphsCount);
- const jchar* glyphs = value->getGlyphs(startIndex, glyphsCount);
- doDrawGlyphs(canvas, glyphs, 0, glyphsCount, x, y, flags, paint);
+ doDrawGlyphs(canvas, value->getGlyphs(), 0, value->getGlyphsCount(), x, y, flags, paint);
}
static void doDrawGlyphs(SkCanvas* canvas, const jchar* glyphArray, int index, int count,
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index 3daf7d0..2ab7da9 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -483,18 +483,15 @@
}
jchar* glyphsArray = env->GetCharArrayElements(glyphs, NULL);
- HB_ShaperItem shaperItem;
- HB_FontRec font;
- FontData fontData;
- TextLayoutCacheValue::shapeWithHarfbuzz(&shaperItem, &font, &fontData, paint, text,
- start, count, contextCount, flags);
- int glyphCount = shaperItem.num_glyphs;
- for (int i = 0; i < glyphCount; i++) {
- glyphsArray[i] = (jchar) shaperItem.glyphs[i];
- }
+ TextLayoutCacheValue value;
+ value.computeValues(paint, text, start, count, contextCount, flags);
+ const jchar* shapedGlyphs = value.getGlyphs();
+ size_t glyphsCount = value.getGlyphsCount();
+ memcpy(glyphsArray, shapedGlyphs, sizeof(jchar) * glyphsCount);
+
env->ReleaseCharArrayElements(glyphs, glyphsArray, JNI_ABORT);
- return glyphCount;
+ return glyphsCount;
}
static int getTextGlyphs__StringIIIII_C(JNIEnv* env, jobject clazz, SkPaint* paint,
diff --git a/core/jni/android/graphics/TextLayout.cpp b/core/jni/android/graphics/TextLayout.cpp
index ae17aed..9b424f2 100644
--- a/core/jni/android/graphics/TextLayout.cpp
+++ b/core/jni/android/graphics/TextLayout.cpp
@@ -257,17 +257,18 @@
sp<TextLayoutCacheValue> value;
#if USE_TEXT_LAYOUT_CACHE
// Return advances from the cache. Compute them if needed
- value = TextLayoutCache::getInstance().getValue(paint, chars, contextCount, dirFlags);
+ value = TextLayoutCache::getInstance().getValue(paint, chars, start, count,
+ contextCount, dirFlags);
#else
value = new TextLayoutCacheValue();
- value->computeValues(paint, chars, contextCount, dirFlags);
+ value->computeValues(paint, chars, start, count, contextCount, dirFlags);
#endif
if (value != NULL) {
- if (resultAdvances != NULL) {
- value->getAdvances(start, count, resultAdvances);
+ if (resultAdvances) {
+ memcpy(resultAdvances, value->getAdvances(), value->getAdvancesCount() * sizeof(jfloat));
}
if (resultTotalAdvance) {
- *resultTotalAdvance = value->getTotalAdvance(start, count);
+ *resultTotalAdvance = value->getTotalAdvance();
}
}
}
diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp
index 9ba95bd..0b53850 100644
--- a/core/jni/android/graphics/TextLayoutCache.cpp
+++ b/core/jni/android/graphics/TextLayoutCache.cpp
@@ -106,7 +106,7 @@
* Caching
*/
sp<TextLayoutCacheValue> TextLayoutCache::getValue(SkPaint* paint,
- const jchar* text, jint count, jint dirFlags) {
+ const jchar* text, jint start, jint count, jint contextCount, jint dirFlags) {
AutoMutex _l(mLock);
nsecs_t startTime = 0;
if (mDebugEnabled) {
@@ -114,7 +114,7 @@
}
// Create the key
- TextLayoutCacheKey key(paint, text, count, dirFlags);
+ TextLayoutCacheKey key(paint, text, start, count, contextCount, dirFlags);
// Get value from cache if possible
sp<TextLayoutCacheValue> value = mCache.get(key);
@@ -128,7 +128,7 @@
value = new TextLayoutCacheValue();
// Compute advances and store them
- value->computeValues(paint, text, count, dirFlags);
+ value->computeValues(paint, text, start, count, contextCount, dirFlags);
nsecs_t endTime = systemTime(SYSTEM_TIME_MONOTONIC);
@@ -166,10 +166,10 @@
} else {
if (mDebugEnabled) {
LOGD("CACHE MISS: Calculated but not storing entry because it is too big "
- "with count=%d, "
+ "with start=%d count=%d contextCount=%d, "
"entry size %d bytes, remaining space %d bytes"
" - Compute time in nanos: %lld - Text='%s'",
- count, size, mMaxSize - mSize, endTime,
+ start, count, contextCount, size, mMaxSize - mSize, endTime,
String8(text, count).string());
}
value.clear();
@@ -184,10 +184,10 @@
if (value->getElapsedTime() > 0) {
float deltaPercent = 100 * ((value->getElapsedTime() - elapsedTimeThruCacheGet)
/ ((float)value->getElapsedTime()));
- LOGD("CACHE HIT #%d with count=%d "
+ LOGD("CACHE HIT #%d with start=%d count=%d contextCount=%d"
"- Compute time in nanos: %d - "
"Cache get time in nanos: %lld - Gain in percent: %2.2f - Text='%s' ",
- mCacheHitCount, count,
+ mCacheHitCount, start, count, contextCount,
value->getElapsedTime(), elapsedTimeThruCacheGet, deltaPercent,
String8(text, count).string());
}
@@ -218,14 +218,14 @@
/**
* TextLayoutCacheKey
*/
-TextLayoutCacheKey::TextLayoutCacheKey(): text(NULL), count(0),
+TextLayoutCacheKey::TextLayoutCacheKey(): text(NULL), start(0), count(0), contextCount(0),
dirFlags(0), typeface(NULL), textSize(0), textSkewX(0), textScaleX(0), flags(0),
hinting(SkPaint::kNo_Hinting) {
}
-TextLayoutCacheKey::TextLayoutCacheKey(const SkPaint* paint,
- const UChar* text, size_t count, int dirFlags) :
- text(text), count(count),
+TextLayoutCacheKey::TextLayoutCacheKey(const SkPaint* paint, const UChar* text,
+ size_t start, size_t count, size_t contextCount, int dirFlags) :
+ text(text), start(start), count(count), contextCount(contextCount),
dirFlags(dirFlags) {
typeface = paint->getTypeface();
textSize = paint->getTextSize();
@@ -238,7 +238,9 @@
TextLayoutCacheKey::TextLayoutCacheKey(const TextLayoutCacheKey& other) :
text(NULL),
textCopy(other.textCopy),
+ start(other.start),
count(other.count),
+ contextCount(other.contextCount),
dirFlags(other.dirFlags),
typeface(other.typeface),
textSize(other.textSize),
@@ -252,7 +254,13 @@
}
int TextLayoutCacheKey::compare(const TextLayoutCacheKey& lhs, const TextLayoutCacheKey& rhs) {
- int deltaInt = lhs.count - rhs.count;
+ int deltaInt = lhs.start - rhs.start;
+ if (deltaInt != 0) return (deltaInt);
+
+ deltaInt = lhs.count - rhs.count;
+ if (deltaInt != 0) return (deltaInt);
+
+ deltaInt = lhs.contextCount - rhs.contextCount;
if (deltaInt != 0) return (deltaInt);
if (lhs.typeface < rhs.typeface) return -1;
@@ -276,16 +284,16 @@
deltaInt = lhs.dirFlags - rhs.dirFlags;
if (deltaInt) return (deltaInt);
- return memcmp(lhs.getText(), rhs.getText(), lhs.count * sizeof(UChar));
+ return memcmp(lhs.getText(), rhs.getText(), lhs.contextCount * sizeof(UChar));
}
void TextLayoutCacheKey::internalTextCopy() {
- textCopy.setTo(text, count);
+ textCopy.setTo(text, contextCount);
text = NULL;
}
size_t TextLayoutCacheKey::getSize() {
- return sizeof(TextLayoutCacheKey) + sizeof(UChar) * count;
+ return sizeof(TextLayoutCacheKey) + sizeof(UChar) * contextCount;
}
/**
@@ -304,29 +312,32 @@
}
void TextLayoutCacheValue::computeValues(SkPaint* paint, const UChar* chars,
- size_t contextCount, int dirFlags) {
+ size_t start, size_t count, size_t contextCount, int dirFlags) {
// Give a hint for advances, glyphs and log clusters vectors size
mAdvances.setCapacity(contextCount);
mGlyphs.setCapacity(contextCount);
- mLogClusters.setCapacity(contextCount);
- computeValuesWithHarfbuzz(paint, chars, contextCount, dirFlags,
- &mAdvances, &mTotalAdvance, &mGlyphs, &mLogClusters);
+ computeValuesWithHarfbuzz(paint, chars, start, count, contextCount, dirFlags,
+ &mAdvances, &mTotalAdvance, &mGlyphs);
#if DEBUG_ADVANCES
- LOGD("Advances - countextCount=%d - totalAdvance=%f", contextCount, mTotalAdvance);
+ LOGD("Advances - start=%d, count=%d, countextCount=%d, totalAdvance=%f", start, count,
+ contextCount, mTotalAdvance);
#endif
}
size_t TextLayoutCacheValue::getSize() {
return sizeof(TextLayoutCacheValue) + sizeof(jfloat) * mAdvances.capacity() +
- sizeof(jchar) * mGlyphs.capacity() + sizeof(unsigned short) * mLogClusters.capacity();
+ sizeof(jchar) * mGlyphs.capacity();
}
-void TextLayoutCacheValue::setupShaperItem(HB_ShaperItem* shaperItem, HB_FontRec* font,
- FontData* fontData, SkPaint* paint, const UChar* chars, size_t start, size_t count,
- size_t contextCount, bool isRTL) {
+void TextLayoutCacheValue::initShaperItem(HB_ShaperItem& shaperItem, HB_FontRec* font,
+ FontData* fontData, SkPaint* paint, const UChar* chars, size_t contextCount) {
+ // Zero the Shaper struct
+ memset(&shaperItem, 0, sizeof(shaperItem));
+
font->klass = &harfbuzzSkiaClass;
font->userData = 0;
+
// The values which harfbuzzSkiaClass returns are already scaled to
// pixel units, so we just set all these to one to disable further
// scaling.
@@ -335,33 +346,13 @@
font->x_scale = 1;
font->y_scale = 1;
- memset(shaperItem, 0, sizeof(*shaperItem));
- shaperItem->font = font;
- shaperItem->face = HB_NewFace(shaperItem->font, harfbuzzSkiaGetTable);
+ shaperItem.font = font;
+ shaperItem.face = HB_NewFace(shaperItem.font, harfbuzzSkiaGetTable);
- shaperItem->kerning_applied = false;
+ // Reset kerning
+ shaperItem.kerning_applied = false;
- // We cannot know, ahead of time, how many glyphs a given script run
- // will produce. We take a guess that script runs will not produce more
- // than twice as many glyphs as there are code points plus a bit of
- // padding and fallback if we find that we are wrong.
- createGlyphArrays(shaperItem, (contextCount + 2) * 2);
-
- // Free memory for clusters if needed and recreate the clusters array
- if (shaperItem->log_clusters) {
- delete shaperItem->log_clusters;
- }
- shaperItem->log_clusters = new unsigned short[contextCount];
-
- shaperItem->item.pos = start;
- shaperItem->item.length = count;
- shaperItem->item.bidiLevel = isRTL;
-
- shaperItem->item.script = isRTL ? HB_Script_Arabic : HB_Script_Common;
-
- shaperItem->string = chars;
- shaperItem->stringLength = contextCount;
-
+ // Define font data
fontData->typeFace = paint->getTypeface();
fontData->textSize = paint->getTextSize();
fontData->textSkewX = paint->getTextSkewX();
@@ -369,31 +360,50 @@
fontData->flags = paint->getFlags();
fontData->hinting = paint->getHinting();
- shaperItem->font->userData = fontData;
+ shaperItem.font->userData = fontData;
+
+ // We cannot know, ahead of time, how many glyphs a given script run
+ // will produce. We take a guess that script runs will not produce more
+ // than twice as many glyphs as there are code points plus a bit of
+ // padding and fallback if we find that we are wrong.
+ createGlyphArrays(shaperItem, (contextCount + 2) * 2);
+
+ // Create log clusters array
+ shaperItem.log_clusters = new unsigned short[contextCount];
+
+ // Set the string properties
+ shaperItem.string = chars;
+ shaperItem.stringLength = contextCount;
}
-void TextLayoutCacheValue::shapeWithHarfbuzz(HB_ShaperItem* shaperItem, HB_FontRec* font,
- FontData* fontData, SkPaint* paint, const UChar* chars, size_t start, size_t count,
- size_t contextCount, bool isRTL) {
- // Setup Harfbuzz Shaper
- setupShaperItem(shaperItem, font, fontData, paint, chars, start, count,
- contextCount, isRTL);
+void TextLayoutCacheValue::freeShaperItem(HB_ShaperItem& shaperItem) {
+ deleteGlyphArrays(shaperItem);
+ delete[] shaperItem.log_clusters;
+ HB_FreeFace(shaperItem.face);
+}
+
+void TextLayoutCacheValue::shapeRun(HB_ShaperItem& shaperItem, size_t start, size_t count,
+ bool isRTL) {
+ // Update Harfbuzz Shaper
+ shaperItem.item.pos = start;
+ shaperItem.item.length = count;
+ shaperItem.item.bidiLevel = isRTL;
+
+ shaperItem.item.script = isRTL ? HB_Script_Arabic : HB_Script_Common;
// Shape
- resetGlyphArrays(shaperItem);
- while (!HB_ShapeItem(shaperItem)) {
+ while (!HB_ShapeItem(&shaperItem)) {
// We overflowed our arrays. Resize and retry.
// HB_ShapeItem fills in shaperItem.num_glyphs with the needed size.
deleteGlyphArrays(shaperItem);
- createGlyphArrays(shaperItem, shaperItem->num_glyphs << 1);
- resetGlyphArrays(shaperItem);
+ createGlyphArrays(shaperItem, shaperItem.num_glyphs << 1);
}
}
void TextLayoutCacheValue::computeValuesWithHarfbuzz(SkPaint* paint, const UChar* chars,
- size_t contextCount, int dirFlags,
+ size_t start, size_t count, size_t contextCount, int dirFlags,
Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
- Vector<jchar>* const outGlyphs, Vector<unsigned short>* const outLogClusters) {
+ Vector<jchar>* const outGlyphs) {
UBiDiLevel bidiReq = 0;
bool forceLTR = false;
@@ -408,13 +418,21 @@
case kBidi_Force_RTL: forceRTL = true; break; // every char is RTL
}
+ HB_ShaperItem shaperItem;
+ HB_FontRec font;
+ FontData fontData;
+
+ // Initialize Harfbuzz Shaper
+ initShaperItem(shaperItem, &font, &fontData, paint, chars, contextCount);
+
if (forceLTR || forceRTL) {
#if DEBUG_GLYPHS
LOGD("computeValuesWithHarfbuzz -- forcing run with LTR=%d RTL=%d",
forceLTR, forceRTL);
#endif
- computeRunValuesWithHarfbuzz(paint, chars, 0, contextCount, contextCount, forceRTL,
- outAdvances, outTotalAdvance, outGlyphs, outLogClusters);
+ computeRunValuesWithHarfbuzz(shaperItem, paint,
+ start, count, forceRTL,
+ outAdvances, outTotalAdvance, outGlyphs);
} else {
UBiDi* bidi = ubidi_open();
if (bidi) {
@@ -427,32 +445,49 @@
int paraDir = ubidi_getParaLevel(bidi) & kDirection_Mask; // 0 if ltr, 1 if rtl
size_t rc = ubidi_countRuns(bidi, &status);
#if DEBUG_GLYPHS
- LOGD("computeValuesWithHarfbuzz -- dirFlags=%d run-count=%d paraDir=%d", dirFlags, rc, paraDir);
+ LOGD("computeValuesWithHarfbuzz -- dirFlags=%d run-count=%d paraDir=%d",
+ dirFlags, rc, paraDir);
#endif
if (rc == 1 || !U_SUCCESS(status)) {
bool isRTL = (paraDir == 1);
#if DEBUG_GLYPHS
LOGD("computeValuesWithHarfbuzz -- processing SINGLE run "
- "-- run-start=%d run-len=%d isRTL=%d", 0, contextCount, isRTL);
+ "-- run-start=%d run-len=%d isRTL=%d", start, count, isRTL);
#endif
- computeRunValuesWithHarfbuzz(paint, chars, 0, contextCount, contextCount,
- isRTL, outAdvances, outTotalAdvance, outGlyphs, outLogClusters);
+ computeRunValuesWithHarfbuzz(shaperItem, paint,
+ start, count, isRTL,
+ outAdvances, outTotalAdvance, outGlyphs);
} else {
+ int32_t end = start + count;
for (size_t i = 0; i < rc; ++i) {
int32_t startRun;
int32_t lengthRun;
UBiDiDirection runDir = ubidi_getVisualRun(bidi, i, &startRun, &lengthRun);
+ if (startRun >= end) {
+ continue;
+ }
+ int32_t endRun = startRun + lengthRun;
+ if (endRun <= start) {
+ continue;
+ }
+ if (startRun < start) {
+ startRun = start;
+ }
+ if (endRun > end) {
+ endRun = end;
+ }
+
+ lengthRun = endRun - startRun;
bool isRTL = (runDir == UBIDI_RTL);
jfloat runTotalAdvance = 0;
#if DEBUG_GLYPHS
LOGD("computeValuesWithHarfbuzz -- run-start=%d run-len=%d isRTL=%d",
startRun, lengthRun, isRTL);
#endif
- computeRunValuesWithHarfbuzz(paint, chars, startRun,
- lengthRun, contextCount, isRTL,
- outAdvances, &runTotalAdvance,
- outGlyphs, outLogClusters);
+ computeRunValuesWithHarfbuzz(shaperItem, paint,
+ startRun, lengthRun, isRTL,
+ outAdvances, &runTotalAdvance, outGlyphs);
*outTotalAdvance += runTotalAdvance;
}
@@ -464,12 +499,17 @@
bool isRTL = (bidiReq = 1) || (bidiReq = UBIDI_DEFAULT_RTL);
#if DEBUG_GLYPHS
LOGD("computeValuesWithHarfbuzz -- cannot run BiDi, considering a SINGLE Run "
- "-- run-start=%d run-len=%d isRTL=%d", 0, contextCount, isRTL);
+ "-- run-start=%d run-len=%d isRTL=%d", start, count, isRTL);
#endif
- computeRunValuesWithHarfbuzz(paint, chars, 0, contextCount, contextCount, isRTL,
- outAdvances, outTotalAdvance, outGlyphs, outLogClusters);
+ computeRunValuesWithHarfbuzz(shaperItem, paint,
+ start, count, isRTL,
+ outAdvances, outTotalAdvance, outGlyphs);
}
}
+
+ // Cleaning
+ freeShaperItem(shaperItem);
+
#if DEBUG_GLYPHS
LOGD("computeValuesWithHarfbuzz -- total-glyphs-count=%d", outGlyphs->size());
#endif
@@ -484,17 +524,12 @@
}
}
-void TextLayoutCacheValue::computeRunValuesWithHarfbuzz(SkPaint* paint, const UChar* chars,
- size_t start, size_t count, size_t contextCount, bool isRTL,
+void TextLayoutCacheValue::computeRunValuesWithHarfbuzz(HB_ShaperItem& shaperItem, SkPaint* paint,
+ size_t start, size_t count, bool isRTL,
Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
- Vector<jchar>* const outGlyphs, Vector<unsigned short>* const outLogClusters) {
+ Vector<jchar>* const outGlyphs) {
- HB_ShaperItem shaperItem;
- HB_FontRec font;
- FontData fontData;
-
- shapeWithHarfbuzz(&shaperItem, &font, &fontData, paint, chars, start, count,
- contextCount, isRTL);
+ shapeRun(shaperItem, start, count, isRTL);
#if DEBUG_GLYPHS
LOGD("HARFBUZZ -- num_glypth=%d - kerning_applied=%d", shaperItem.num_glyphs,
@@ -511,10 +546,6 @@
#endif
outAdvances->insertAt(0, outAdvances->size(), count);
*outTotalAdvance = 0;
-
- // Cleaning
- deleteGlyphArrays(&shaperItem);
- HB_FreeFace(shaperItem.face);
return;
}
@@ -553,103 +584,21 @@
outGlyphs->add(glyph);
}
}
-
- // Get LogClusters
- if (outLogClusters) {
- size_t countLogClusters = outLogClusters->size();
- for (size_t i = 0; i < count; i++) {
- // As there may be successive runs, we need to shift the log clusters
- unsigned short logCluster = shaperItem.log_clusters[i] + countLogClusters;
-#if DEBUG_GLYPHS
- LOGD("HARFBUZZ -- logCluster[%d] relative=%d - absolute=%d", i, shaperItem.log_clusters[i], logCluster);
-#endif
- outLogClusters->add(logCluster);
- }
- }
-
- // Cleaning
- deleteGlyphArrays(&shaperItem);
- HB_FreeFace(shaperItem.face);
}
-void TextLayoutCacheValue::deleteGlyphArrays(HB_ShaperItem* shaperItem) {
- delete[] shaperItem->glyphs;
- delete[] shaperItem->attributes;
- delete[] shaperItem->advances;
- delete[] shaperItem->offsets;
+void TextLayoutCacheValue::deleteGlyphArrays(HB_ShaperItem& shaperItem) {
+ delete[] shaperItem.glyphs;
+ delete[] shaperItem.attributes;
+ delete[] shaperItem.advances;
+ delete[] shaperItem.offsets;
}
-void TextLayoutCacheValue::createGlyphArrays(HB_ShaperItem* shaperItem, int size) {
- shaperItem->glyphs = new HB_Glyph[size];
- shaperItem->attributes = new HB_GlyphAttributes[size];
- shaperItem->advances = new HB_Fixed[size];
- shaperItem->offsets = new HB_FixedPoint[size];
- shaperItem->num_glyphs = size;
-}
-
-void TextLayoutCacheValue::resetGlyphArrays(HB_ShaperItem* shaperItem) {
- int size = shaperItem->num_glyphs;
- // All the types here don't have pointers. It is safe to reset to
- // zero unless Harfbuzz breaks the compatibility in the future.
- memset(shaperItem->glyphs, 0, size * sizeof(shaperItem->glyphs[0]));
- memset(shaperItem->attributes, 0, size * sizeof(shaperItem->attributes[0]));
- memset(shaperItem->advances, 0, size * sizeof(shaperItem->advances[0]));
- memset(shaperItem->offsets, 0, size * sizeof(shaperItem->offsets[0]));
-}
-
-void TextLayoutCacheValue::getAdvances(size_t start, size_t count, jfloat* outAdvances) const {
- memcpy(outAdvances, mAdvances.array() + start, count * sizeof(jfloat));
-#if DEBUG_ADVANCES
- LOGD("getAdvances - start=%d count=%d", start, count);
- for (size_t i = 0; i < count; i++) {
- LOGD(" adv[%d] = %f", i, outAdvances[i]);
- }
-#endif
-}
-
-jfloat TextLayoutCacheValue::getTotalAdvance(size_t start, size_t count) const {
- jfloat outTotalAdvance = 0;
- for (size_t i = start; i < start + count; i++) {
- outTotalAdvance += mAdvances[i];
- }
-#if DEBUG_ADVANCES
- LOGD("getTotalAdvance - start=%d count=%d - total=%f", start, count, outTotalAdvance);
-#endif
- return outTotalAdvance;
-}
-
-void TextLayoutCacheValue::getGlyphsIndexAndCount(size_t start, size_t count, size_t* outStartIndex,
- size_t* outGlyphsCount) const {
- *outStartIndex = 0;
- if (count == 0) {
- *outGlyphsCount = 0;
- return;
- }
- *outStartIndex = mLogClusters[start];
- size_t endIndex = (start + count >= mAdvances.size()) ?
- mGlyphs.size() : mLogClusters[start + count];
- *outGlyphsCount = endIndex - *outStartIndex;
-#if DEBUG_GLYPHS
- LOGD("getGlyphsIndexes - start=%d count=%d - startIndex=%d count=%d", start, count,
- *outStartIndex, *outGlyphsCount);
- for(size_t i = 0; i < mGlyphs.size(); i++) {
- LOGD("getGlyphs - all - glyph[%d] = %d", i, mGlyphs[i]);
- }
- for(size_t i = 0; i < mAdvances.size(); i++) {
- LOGD("getGlyphs - all - logcl[%d] = %d", i, mLogClusters[i]);
- }
-#endif
-}
-
-const jchar* TextLayoutCacheValue::getGlyphs(size_t startIndex, size_t count) {
- const jchar* glyphs = mGlyphs.array() + startIndex;
-#if DEBUG_GLYPHS
- LOGD("getGlyphs - with startIndex = %d count = %d", startIndex, count);
- for (size_t i = 0; i < count; i++) {
- LOGD("getGlyphs - result - glyph[%d] = %d", i, glyphs[i]);
- }
-#endif
- return glyphs;
+void TextLayoutCacheValue::createGlyphArrays(HB_ShaperItem& shaperItem, int size) {
+ shaperItem.glyphs = new HB_Glyph[size];
+ shaperItem.attributes = new HB_GlyphAttributes[size];
+ shaperItem.advances = new HB_Fixed[size];
+ shaperItem.offsets = new HB_FixedPoint[size];
+ shaperItem.num_glyphs = size;
}
} // namespace android
diff --git a/core/jni/android/graphics/TextLayoutCache.h b/core/jni/android/graphics/TextLayoutCache.h
index 6dda1e5..580079d 100644
--- a/core/jni/android/graphics/TextLayoutCache.h
+++ b/core/jni/android/graphics/TextLayoutCache.h
@@ -68,7 +68,8 @@
public:
TextLayoutCacheKey();
- TextLayoutCacheKey(const SkPaint* paint, const UChar* text, size_t count, int dirFlags);
+ TextLayoutCacheKey(const SkPaint* paint, const UChar* text, size_t start, size_t count,
+ size_t contextCount, int dirFlags);
TextLayoutCacheKey(const TextLayoutCacheKey& other);
@@ -88,7 +89,9 @@
private:
const UChar* text; // if text is NULL, use textCopy
String16 textCopy;
+ size_t start;
size_t count;
+ size_t contextCount;
int dirFlags;
SkTypeface* typeface;
SkScalar textSize;
@@ -119,32 +122,20 @@
void setElapsedTime(uint32_t time);
uint32_t getElapsedTime();
- void computeValues(SkPaint* paint, const UChar* chars, size_t contextCount, int dirFlags);
+ void computeValues(SkPaint* paint, const UChar* chars, size_t start, size_t count,
+ size_t contextCount, int dirFlags);
- void getAdvances(size_t start, size_t count, jfloat* outAdvances) const;
- jfloat getTotalAdvance(size_t start, size_t count) const;
- void getGlyphsIndexAndCount(size_t start, size_t count, size_t* outStartIndex,
- size_t* outGlyphsCount) const;
- const jchar* getGlyphs(size_t startIndex, size_t count);
+ inline const jfloat* getAdvances() const { return mAdvances.array(); }
+ inline size_t getAdvancesCount() const { return mAdvances.size(); }
+ inline jfloat getTotalAdvance() const { return mTotalAdvance; }
+ inline const jchar* getGlyphs() const { return mGlyphs.array(); }
+ inline size_t getGlyphsCount() const { return mGlyphs.size(); }
/**
* Get the size of the Cache entry
*/
size_t getSize();
- static void setupShaperItem(HB_ShaperItem* shaperItem, HB_FontRec* font, FontData* fontData,
- SkPaint* paint, const UChar* chars, size_t start, size_t count, size_t contextCount,
- bool isRTL);
-
- static void shapeWithHarfbuzz(HB_ShaperItem* shaperItem, HB_FontRec* font, FontData* fontData,
- SkPaint* paint, const UChar* chars, size_t start, size_t count, size_t contextCount,
- bool isRTL);
-
- static void computeValuesWithHarfbuzz(SkPaint* paint, const UChar* chars,
- size_t contextCount, int dirFlags,
- Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
- Vector<jchar>* const outGlyphs, Vector<unsigned short>* const outLogClusters);
-
private:
/**
* Advances vector
@@ -162,23 +153,31 @@
Vector<jchar> mGlyphs;
/**
- * Harfbuzz Log Clusters
- */
- Vector<unsigned short> mLogClusters;
-
- /**
* Time for computing the values (in milliseconds)
*/
uint32_t mElapsedTime;
- static void deleteGlyphArrays(HB_ShaperItem* shaperItem);
- static void createGlyphArrays(HB_ShaperItem* shaperItem, int size);
- static void resetGlyphArrays(HB_ShaperItem* shaperItem);
-
- static void computeRunValuesWithHarfbuzz(SkPaint* paint, const UChar* chars, size_t start,
- size_t count, size_t contextCount, bool isRTL,
+ static void computeValuesWithHarfbuzz(SkPaint* paint, const UChar* chars,
+ size_t start, size_t count, size_t contextCount, int dirFlags,
Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
- Vector<jchar>* const outGlyphs, Vector<unsigned short>* const outLogClusters);
+ Vector<jchar>* const outGlyphs);
+
+ static void computeRunValuesWithHarfbuzz(HB_ShaperItem& shaperItem, SkPaint* paint,
+ size_t start, size_t count, bool isRTL,
+ Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
+ Vector<jchar>* const outGlyphs);
+
+ static void initShaperItem(HB_ShaperItem& shaperItem, HB_FontRec* font, FontData* fontData,
+ SkPaint* paint, const UChar* chars, size_t contextCount);
+
+ static void freeShaperItem(HB_ShaperItem& shaperItem);
+
+ static void shapeRun(HB_ShaperItem& shaperItem, size_t start, size_t count, bool isRTL);
+
+ static void deleteGlyphArrays(HB_ShaperItem& shaperItem);
+
+ static void createGlyphArrays(HB_ShaperItem& shaperItem, int size);
+
}; // TextLayoutCacheValue
/**
@@ -202,8 +201,8 @@
*/
void operator()(TextLayoutCacheKey& text, sp<TextLayoutCacheValue>& desc);
- sp<TextLayoutCacheValue> getValue(SkPaint* paint, const jchar* text, jint count,
- jint dirFlags);
+ sp<TextLayoutCacheValue> getValue(SkPaint* paint, const jchar* text, jint start, jint count,
+ jint contextCount, jint dirFlags);
/**
* Clear the cache
@@ -256,6 +255,7 @@
* Dump Cache statistics
*/
void dumpCacheStats();
+
}; // TextLayoutCache
} // namespace android
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index e542a47..e79de2d 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -477,19 +477,17 @@
#if RTL_USE_HARFBUZZ
sp<TextLayoutCacheValue> value;
#if USE_TEXT_LAYOUT_CACHE
- value = TextLayoutCache::getInstance().getValue(paint, text, count, flags);
+ value = TextLayoutCache::getInstance().getValue(paint, text, 0, count, count, flags);
if (value == NULL) {
LOGE("Cannot get TextLayoutCache value");
return ;
}
#else
value = new TextLayoutCacheValue();
- value->computeValues(paint, text, count, flags);
+ value->computeValues(paint, text, 0, count, count, flags);
#endif
- size_t startIndex = 0;
- size_t glyphsCount = 0;
- value->getGlyphsIndexAndCount(0, count, &startIndex, &glyphsCount);
- const jchar* glyphs = value->getGlyphs(startIndex, glyphsCount);
+ const jchar* glyphs = value->getGlyphs();
+ size_t glyphsCount = value->getGlyphsCount();
int bytesCount = glyphsCount * sizeof(jchar);
renderer->drawText((const char*) glyphs, bytesCount, glyphsCount, x, y, paint);
#else
@@ -509,19 +507,17 @@
#if RTL_USE_HARFBUZZ
sp<TextLayoutCacheValue> value;
#if USE_TEXT_LAYOUT_CACHE
- value = TextLayoutCache::getInstance().getValue(paint, text, contextCount, flags);
+ value = TextLayoutCache::getInstance().getValue(paint, text, start, count, contextCount, flags);
if (value == NULL) {
LOGE("Cannot get TextLayoutCache value");
return ;
}
#else
value = new TextLayoutCacheValue();
- value->computeValues(paint, text, contextCount, flags);
+ value->computeValues(paint, text, start, count, contextCount, flags);
#endif
- size_t startIndex = 0;
- size_t glyphsCount = 0;
- value->getGlyphsIndexAndCount(start, count, &startIndex, &glyphsCount);
- const jchar* glyphs = value->getGlyphs(startIndex, glyphsCount);
+ const jchar* glyphs = value->getGlyphs();
+ size_t glyphsCount = value->getGlyphsCount();
int bytesCount = glyphsCount * sizeof(jchar);
renderer->drawText((const char*) glyphs, bytesCount, glyphsCount, x, y, paint);
#else
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index e2950d5e..d3d65a3 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -865,13 +865,7 @@
}
static int getTargetSdkVersion(Context ctx) {
- try {
- PackageManager pm = ctx.getPackageManager();
- ApplicationInfo app = pm.getApplicationInfo(ctx.getPackageName(), 0);
- return app.targetSdkVersion;
- } catch (Exception e) {
- throw new RSDriverException("Error calculating target SDK version for RS.");
- }
+ return ctx.getApplicationInfo().targetSdkVersion;
}
/**
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index dd05e61..a077cbc5 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -185,7 +185,7 @@
return;
}
- SkFixed penX = SkIntToFixed(x);
+ float penX = x;
int penY = y;
int glyphsLeft = 1;
if (numGlyphs > 0) {
@@ -193,7 +193,7 @@
}
SkFixed prevRsbDelta = 0;
- penX += SK_Fixed1 / 2;
+ penX += 0.5f;
text += start;
@@ -206,25 +206,25 @@
}
CachedGlyphInfo* cachedGlyph = getCachedGlyph(paint, glyph);
- penX += SkAutoKern_AdjustF(prevRsbDelta, cachedGlyph->mLsbDelta);
+ penX += SkFixedToFloat(SkAutoKern_AdjustF(prevRsbDelta, cachedGlyph->mLsbDelta));
prevRsbDelta = cachedGlyph->mRsbDelta;
// If it's still not valid, we couldn't cache it, so we shouldn't draw garbage
if (cachedGlyph->mIsValid) {
switch(mode) {
case FRAMEBUFFER:
- drawCachedGlyph(cachedGlyph, SkFixedFloor(penX), penY);
+ drawCachedGlyph(cachedGlyph, (int) floorf(penX), penY);
break;
case BITMAP:
- drawCachedGlyph(cachedGlyph, SkFixedFloor(penX), penY, bitmap, bitmapW, bitmapH);
+ drawCachedGlyph(cachedGlyph, (int) floorf(penX), penY, bitmap, bitmapW, bitmapH);
break;
case MEASURE:
- measureCachedGlyph(cachedGlyph, SkFixedFloor(penX), penY, bounds);
+ measureCachedGlyph(cachedGlyph, (int) floorf(penX), penY, bounds);
break;
}
}
- penX += cachedGlyph->mAdvanceX;
+ penX += SkFixedToFloat(cachedGlyph->mAdvanceX);
// If we were given a specific number of glyphs, decrement
if (numGlyphs > 0) {
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
index 4049c73..071044e 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -526,11 +526,23 @@
if (mUpdateMonitor.getPhoneState() == TelephonyManager.CALL_STATE_IDLE
&& transportInvisible) {
bindToFaceLock();
+ //Eliminate the black background so that the lockpattern will be visible
+ //If FaceUnlock is cancelled
+ mHandler.sendEmptyMessageDelayed(MSG_HIDE_FACELOCK_AREA_VIEW, 4000);
} else {
mHandler.sendEmptyMessage(MSG_HIDE_FACELOCK_AREA_VIEW);
}
}
+ /** Unbind from facelock if something covers this window (such as an alarm) */
+ @Override
+ public void onWindowFocusChanged (boolean hasWindowFocus) {
+ if(!hasWindowFocus) {
+ stopAndUnbindFromFaceLock();
+ mHandler.sendEmptyMessage(MSG_HIDE_FACELOCK_AREA_VIEW);
+ }
+ }
+
@Override
public void show() {
if (mMode == Mode.LockScreen) {
@@ -607,7 +619,10 @@
//We need to stop faceunlock when a phonecall comes in
@Override
public void onPhoneStateChanged(int phoneState) {
- if(phoneState == TelephonyManager.CALL_STATE_RINGING) stopAndUnbindFromFaceLock();
+ if(phoneState == TelephonyManager.CALL_STATE_RINGING) {
+ stopAndUnbindFromFaceLock();
+ mHandler.sendEmptyMessage(MSG_HIDE_FACELOCK_AREA_VIEW);
+ }
}
@Override
diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java
index 253e741..a0e28ed 100644
--- a/services/java/com/android/server/WallpaperManagerService.java
+++ b/services/java/com/android/server/WallpaperManagerService.java
@@ -834,7 +834,7 @@
}
if (DEBUG) Slog.v(TAG, "settingsRestored: success=" + success);
if (success) {
- bindWallpaperComponentLocked(null, false, false);
+ bindWallpaperComponentLocked(mNextWallpaperComponent, false, false);
}
}
}