Merge "Clean up synchronization"
diff --git a/core/java/android/text/TextLine.java b/core/java/android/text/TextLine.java
index b73d900..b3df8ff 100644
--- a/core/java/android/text/TextLine.java
+++ b/core/java/android/text/TextLine.java
@@ -59,6 +59,12 @@
private boolean mCharsValid;
private Spanned mSpanned;
private final TextPaint mWorkPaint = new TextPaint();
+ private final SpanSet<MetricAffectingSpan> mMetricAffectingSpanSpanSet =
+ new SpanSet<MetricAffectingSpan>(MetricAffectingSpan.class);
+ private final SpanSet<CharacterStyle> mCharacterStyleSpanSet =
+ new SpanSet<CharacterStyle>(CharacterStyle.class);
+ private final SpanSet<ReplacementSpan> mReplacementSpanSpanSet =
+ new SpanSet<ReplacementSpan>(ReplacementSpan.class);
private static final TextLine[] sCached = new TextLine[3];
@@ -119,7 +125,6 @@
* @param hasTabs true if the line might contain tabs or emoji
* @param tabStops the tabStops. Can be null.
*/
- @SuppressWarnings("null")
void set(TextPaint paint, CharSequence text, int start, int limit, int dir,
Directions directions, boolean hasTabs, TabStops tabStops) {
mPaint = paint;
@@ -135,12 +140,10 @@
mSpanned = null;
boolean hasReplacement = false;
- SpanSet<ReplacementSpan> replacementSpans = null;
if (text instanceof Spanned) {
mSpanned = (Spanned) text;
- replacementSpans = new SpanSet<ReplacementSpan>(mSpanned, start, limit,
- ReplacementSpan.class);
- hasReplacement = replacementSpans.numberOfSpans > 0;
+ mReplacementSpanSpanSet.init(mSpanned, start, limit);
+ hasReplacement = mReplacementSpanSpanSet.numberOfSpans > 0;
}
mCharsValid = hasReplacement || hasTabs || directions != Layout.DIRS_ALL_LEFT_TO_RIGHT;
@@ -158,9 +161,8 @@
// zero-width characters.
char[] chars = mChars;
for (int i = start, inext; i < limit; i = inext) {
- // replacementSpans cannot be null if hasReplacement is true
- inext = replacementSpans.getNextTransition(i, limit);
- if (replacementSpans.hasSpansIntersecting(i, inext)) {
+ inext = mReplacementSpanSpanSet.getNextTransition(i, limit);
+ if (mReplacementSpanSpanSet.hasSpansIntersecting(i, inext)) {
// transition into a span
chars[i - start] = '\ufffc';
for (int j = i - start + 1, e = inext - start; j < e; ++j) {
@@ -854,21 +856,30 @@
}
private static class SpanSet<E> {
- final int numberOfSpans;
- final E[] spans;
- final int[] spanStarts;
- final int[] spanEnds;
- final int[] spanFlags;
+ int numberOfSpans;
+ E[] spans;
+ int[] spanStarts;
+ int[] spanEnds;
+ int[] spanFlags;
+ final Class<? extends E> classType;
+
+ SpanSet(Class<? extends E> type) {
+ classType = type;
+ numberOfSpans = 0;
+ }
@SuppressWarnings("unchecked")
- SpanSet(Spanned spanned, int start, int limit, Class<? extends E> type) {
- final E[] allSpans = spanned.getSpans(start, limit, type);
+ public void init(Spanned spanned, int start, int limit) {
+ final E[] allSpans = spanned.getSpans(start, limit, classType);
final int length = allSpans.length;
- // These arrays may end up being too large because of empty spans
- spans = (E[]) Array.newInstance(type, length);
- spanStarts = new int[length];
- spanEnds = new int[length];
- spanFlags = new int[length];
+
+ if (length > 0 && (spans == null || spans.length < length)) {
+ // These arrays may end up being too large because of empty spans
+ spans = (E[]) Array.newInstance(classType, length);
+ spanStarts = new int[length];
+ spanEnds = new int[length];
+ spanFlags = new int[length];
+ }
int count = 0;
for (int i = 0; i < length; i++) {
@@ -879,30 +890,11 @@
if (spanStart == spanEnd) continue;
final int spanFlag = spanned.getSpanFlags(span);
- final int priority = spanFlag & Spanned.SPAN_PRIORITY;
- if (priority != 0 && count != 0) {
- int j;
- for (j = 0; j < count; j++) {
- final int otherPriority = spanFlags[j] & Spanned.SPAN_PRIORITY;
- if (priority > otherPriority) break;
- }
-
- System.arraycopy(spans, j, spans, j + 1, count - j);
- System.arraycopy(spanStarts, j, spanStarts, j + 1, count - j);
- System.arraycopy(spanEnds, j, spanEnds, j + 1, count - j);
- System.arraycopy(spanFlags, j, spanFlags, j + 1, count - j);
-
- spans[j] = span;
- spanStarts[j] = spanStart;
- spanEnds[j] = spanEnd;
- spanFlags[j] = spanFlag;
- } else {
- spans[i] = span;
- spanStarts[i] = spanStart;
- spanEnds[i] = spanEnd;
- spanFlags[i] = spanFlag;
- }
+ spans[i] = span;
+ spanStarts[i] = spanStart;
+ spanEnds[i] = spanEnd;
+ spanFlags[i] = spanFlag;
count++;
}
@@ -970,10 +962,8 @@
y, bottom, fmi, needWidth || mlimit < measureLimit);
}
- final SpanSet<MetricAffectingSpan> metricAffectingSpans = new SpanSet<MetricAffectingSpan>(
- mSpanned, mStart + start, mStart + limit, MetricAffectingSpan.class);
- final SpanSet<CharacterStyle> characterStyleSpans = new SpanSet<CharacterStyle>(
- mSpanned, mStart + start, mStart + limit, CharacterStyle.class);
+ mMetricAffectingSpanSpanSet.init(mSpanned, mStart + start, mStart + limit);
+ mCharacterStyleSpanSet.init(mSpanned, mStart + start, mStart + limit);
// Shaping needs to take into account context up to metric boundaries,
// but rendering needs to take into account character style boundaries.
@@ -985,17 +975,18 @@
TextPaint wp = mWorkPaint;
wp.set(mPaint);
- inext = metricAffectingSpans.getNextTransition(mStart + i, mStart + limit) - mStart;
+ inext = mMetricAffectingSpanSpanSet.getNextTransition(mStart + i, mStart + limit) -
+ mStart;
int mlimit = Math.min(inext, measureLimit);
ReplacementSpan replacement = null;
- for (int j = 0; j < metricAffectingSpans.numberOfSpans; j++) {
+ for (int j = 0; j < mMetricAffectingSpanSpanSet.numberOfSpans; j++) {
// Both intervals [spanStarts..spanEnds] and [mStart + i..mStart + mlimit] are NOT
// empty by construction. This special case in getSpans() explains the >= & <= tests
- if ((metricAffectingSpans.spanStarts[j] >= mStart + mlimit) ||
- (metricAffectingSpans.spanEnds[j] <= mStart + i)) continue;
- MetricAffectingSpan span = metricAffectingSpans.spans[j];
+ if ((mMetricAffectingSpanSpanSet.spanStarts[j] >= mStart + mlimit) ||
+ (mMetricAffectingSpanSpanSet.spanEnds[j] <= mStart + i)) continue;
+ MetricAffectingSpan span = mMetricAffectingSpanSpanSet.spans[j];
if (span instanceof ReplacementSpan) {
replacement = (ReplacementSpan)span;
} else {
@@ -1016,16 +1007,16 @@
y, bottom, fmi, needWidth || mlimit < measureLimit);
} else {
for (int j = i, jnext; j < mlimit; j = jnext) {
- jnext = characterStyleSpans.getNextTransition(mStart + j, mStart + mlimit) -
+ jnext = mCharacterStyleSpanSet.getNextTransition(mStart + j, mStart + mlimit) -
mStart;
wp.set(mPaint);
- for (int k = 0; k < characterStyleSpans.numberOfSpans; k++) {
+ for (int k = 0; k < mCharacterStyleSpanSet.numberOfSpans; k++) {
// Intentionally using >= and <= as explained above
- if ((characterStyleSpans.spanStarts[k] >= mStart + jnext) ||
- (characterStyleSpans.spanEnds[k] <= mStart + j)) continue;
+ if ((mCharacterStyleSpanSet.spanStarts[k] >= mStart + jnext) ||
+ (mCharacterStyleSpanSet.spanEnds[k] <= mStart + j)) continue;
- CharacterStyle span = characterStyleSpans.spans[k];
+ CharacterStyle span = mCharacterStyleSpanSet.spans[k];
span.updateDrawState(wp);
}
diff --git a/core/java/android/text/format/Formatter.java b/core/java/android/text/format/Formatter.java
index 5ae65df..121c6f2 100644
--- a/core/java/android/text/format/Formatter.java
+++ b/core/java/android/text/format/Formatter.java
@@ -21,7 +21,7 @@
/**
* Utility class to aid in formatting common values that are not covered
- * by {@link java.util.Formatter}
+ * by the {@link java.util.Formatter} class in {@link java.util}
*/
public final class Formatter {
diff --git a/core/java/android/text/format/package.html b/core/java/android/text/format/package.html
new file mode 100644
index 0000000..b9e6a44
--- /dev/null
+++ b/core/java/android/text/format/package.html
@@ -0,0 +1,7 @@
+<HTML>
+<BODY>
+This package contains alternative classes for some text formatting classes
+defined in {@link java.util} and {@link java.text}. It also contains additional text formatting
+classes for situations not covered by {@link java.util} or {@link java.text}.
+</BODY>
+</HTML>
diff --git a/core/java/android/view/VolumePanel.java b/core/java/android/view/VolumePanel.java
index 48fe0df..24a3066 100644
--- a/core/java/android/view/VolumePanel.java
+++ b/core/java/android/view/VolumePanel.java
@@ -400,7 +400,7 @@
if (LOGD) Log.d(TAG, "onVolumeChanged(streamType: " + streamType + ", flags: " + flags + ")");
if ((flags & AudioManager.FLAG_SHOW_UI) != 0) {
- if (mActiveStreamType == -1) {
+ if (mActiveStreamType != streamType) {
reorderSliders(streamType);
}
onShowVolumeChanged(streamType, flags);
diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index c194559..d8f08b2 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -410,6 +410,7 @@
mCommitted = false;
// remove pending draw to block update until mFirstLayoutDone is
// set to true in didFirstLayout()
+ mWebViewCore.clearContent();
mWebViewCore.removeMessages(WebViewCore.EventHub.WEBKIT_DRAW);
}
}
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 14da23e..de4949c 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -497,6 +497,13 @@
message.sendToTarget();
}
+ /**
+ * Clear the picture set. To be called only on the WebCore thread.
+ */
+ /* package */ void clearContent() {
+ nativeClearContent();
+ }
+
//-------------------------------------------------------------------------
// JNI methods
//-------------------------------------------------------------------------
@@ -1560,7 +1567,7 @@
// Clear the view so that onDraw() will draw nothing
// but white background
// (See public method WebView.clearView)
- nativeClearContent();
+ clearContent();
break;
case MESSAGE_RELAY:
diff --git a/core/java/android/widget/SpellChecker.java b/core/java/android/widget/SpellChecker.java
index 31da5b5..6700829 100644
--- a/core/java/android/widget/SpellChecker.java
+++ b/core/java/android/widget/SpellChecker.java
@@ -45,14 +45,15 @@
// No more than this number of words will be parsed on each iteration to ensure a minimum
// lock of the UI thread
- public static final int MAX_NUMBER_OF_WORDS = 10;
+ public static final int MAX_NUMBER_OF_WORDS = 50;
- // Safe estimate, will ensure that the interval below usually does not have to be updated
- public static final int AVERAGE_WORD_LENGTH = 10;
+ // Rough estimate, such that the word iterator interval usually does not need to be shifted
+ public static final int AVERAGE_WORD_LENGTH = 7;
// When parsing, use a character window of that size. Will be shifted if needed
public static final int WORD_ITERATOR_INTERVAL = AVERAGE_WORD_LENGTH * MAX_NUMBER_OF_WORDS;
+ // Pause between each spell check to keep the UI smooth
private final static int SPELL_PAUSE_DURATION = 400; // milliseconds
private final TextView mTextView;
@@ -75,6 +76,14 @@
private Locale mCurrentLocale;
+ // Shared by all SpellParsers. Cannot be shared with TextView since it may be used
+ // concurrently due to the asynchronous nature of onGetSuggestions.
+ private WordIterator mWordIterator;
+
+ private TextServicesManager mTextServicesManager;
+
+ private Runnable mSpellRunnable;
+
public SpellChecker(TextView textView) {
mTextView = textView;
@@ -136,6 +145,10 @@
for (int i = 0; i < length; i++) {
mSpellParsers[i].stop();
}
+
+ if (mSpellRunnable != null) {
+ mTextView.removeCallbacks(mSpellRunnable);
+ }
}
private int nextSpellCheckSpanIndex() {
@@ -285,18 +298,29 @@
}
}
- mTextView.postDelayed(new Runnable() {
- @Override
- public void run() {
- final int length = mSpellParsers.length;
- for (int i = 0; i < length; i++) {
- final SpellParser spellParser = mSpellParsers[i];
- if (spellParser.isParsing()) {
- spellParser.parse();
+ scheduleNewSpellCheck();
+ }
+
+ private void scheduleNewSpellCheck() {
+ if (mSpellRunnable == null) {
+ mSpellRunnable = new Runnable() {
+ @Override
+ public void run() {
+ final int length = mSpellParsers.length;
+ for (int i = 0; i < length; i++) {
+ final SpellParser spellParser = mSpellParsers[i];
+ if (!spellParser.isFinished()) {
+ spellParser.parse();
+ break; // run one spell parser at a time to bound running time
+ }
}
}
- }
- }, SPELL_PAUSE_DURATION);
+ };
+ } else {
+ mTextView.removeCallbacks(mSpellRunnable);
+ }
+
+ mTextView.postDelayed(mSpellRunnable, SPELL_PAUSE_DURATION);
}
private void createMisspelledSuggestionSpan(Editable editable, SuggestionsInfo suggestionsInfo,
@@ -393,20 +417,19 @@
final int start = editable.getSpanStart(mRange);
final int end = editable.getSpanEnd(mRange);
- final WordIterator wordIterator = mTextView.getWordIterator();
int wordIteratorWindowEnd = Math.min(end, start + WORD_ITERATOR_INTERVAL);
- wordIterator.setCharSequence(editable, start, wordIteratorWindowEnd);
+ mWordIterator.setCharSequence(editable, start, wordIteratorWindowEnd);
// Move back to the beginning of the current word, if any
- int wordStart = wordIterator.preceding(start);
+ int wordStart = mWordIterator.preceding(start);
int wordEnd;
if (wordStart == BreakIterator.DONE) {
- wordEnd = wordIterator.following(start);
+ wordEnd = mWordIterator.following(start);
if (wordEnd != BreakIterator.DONE) {
- wordStart = wordIterator.getBeginning(wordEnd);
+ wordStart = mWordIterator.getBeginning(wordEnd);
}
} else {
- wordEnd = wordIterator.getEnd(wordStart);
+ wordEnd = mWordIterator.getEnd(wordStart);
}
if (wordEnd == BreakIterator.DONE) {
removeRangeSpan(editable);
@@ -472,15 +495,15 @@
// iterate word by word
int originalWordEnd = wordEnd;
- wordEnd = wordIterator.following(wordEnd);
+ wordEnd = mWordIterator.following(wordEnd);
if ((wordIteratorWindowEnd < end) &&
(wordEnd == BreakIterator.DONE || wordEnd >= wordIteratorWindowEnd)) {
wordIteratorWindowEnd = Math.min(end, originalWordEnd + WORD_ITERATOR_INTERVAL);
- wordIterator.setCharSequence(editable, originalWordEnd, wordIteratorWindowEnd);
- wordEnd = wordIterator.following(originalWordEnd);
+ mWordIterator.setCharSequence(editable, originalWordEnd, wordIteratorWindowEnd);
+ wordEnd = mWordIterator.following(originalWordEnd);
}
if (wordEnd == BreakIterator.DONE) break;
- wordStart = wordIterator.getBeginning(wordEnd);
+ wordStart = mWordIterator.getBeginning(wordEnd);
if (wordStart == BreakIterator.DONE) {
break;
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 5b73a74..90fb106 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -3210,7 +3210,6 @@
}
boolean needEditableForNotification = false;
- boolean startSpellCheck = false;
if (mListeners != null && mListeners.size() != 0) {
needEditableForNotification = true;
@@ -3222,7 +3221,6 @@
setFilters(t, mFilters);
InputMethodManager imm = InputMethodManager.peekInstance();
if (imm != null) imm.restartInput(this);
- startSpellCheck = true;
} else if (type == BufferType.SPANNABLE || mMovement != null) {
text = mSpannableFactory.newSpannable(text);
} else if (!(text instanceof CharWrapper)) {
@@ -3311,11 +3309,6 @@
sendOnTextChanged(text, 0, oldlen, textLength);
onTextChanged(text, 0, oldlen, textLength);
- if (startSpellCheck && mSpellChecker != null) {
- // This view has to have been previously attached for mSpellChecker to exist
- updateSpellCheckSpans(0, textLength);
- }
-
if (needEditableForNotification) {
sendAfterTextChanged((Editable) text);
}
@@ -4482,8 +4475,8 @@
// Resolve drawables as the layout direction has been resolved
resolveDrawables();
-
- updateSpellCheckSpans(0, mText.length());
+
+ updateSpellCheckSpans(0, mText.length(), true /* create the spell checker if needed */);
}
@Override
@@ -7636,7 +7629,7 @@
}
}
- updateSpellCheckSpans(start, start + after);
+ updateSpellCheckSpans(start, start + after, false);
// Hide the controllers as soon as text is modified (typing, procedural...)
// We do not hide the span controllers, since they can be added when a new text is
@@ -7794,17 +7787,22 @@
}
}
- if (newStart < 0 && what instanceof SpellCheckSpan) {
- getSpellChecker().removeSpellCheckSpan((SpellCheckSpan) what);
+ if (mSpellChecker != null && newStart < 0 && what instanceof SpellCheckSpan) {
+ mSpellChecker.removeSpellCheckSpan((SpellCheckSpan) what);
}
}
/**
* Create new SpellCheckSpans on the modified region.
*/
- private void updateSpellCheckSpans(int start, int end) {
+ private void updateSpellCheckSpans(int start, int end, boolean createSpellChecker) {
if (isTextEditable() && isSuggestionsEnabled()) {
- getSpellChecker().spellCheck(start, end);
+ if (mSpellChecker == null && createSpellChecker) {
+ mSpellChecker = new SpellChecker(this);
+ }
+ if (mSpellChecker != null) {
+ mSpellChecker.spellCheck(start, end);
+ }
}
}
@@ -8976,13 +8974,6 @@
return packRangeInLong(offset, offset);
}
- private SpellChecker getSpellChecker() {
- if (mSpellChecker == null) {
- mSpellChecker = new SpellChecker(this);
- }
- return mSpellChecker;
- }
-
private long getLastTouchOffsets() {
SelectionModifierCursorController selectionController = getSelectionController();
final int minOffset = selectionController.getMinTouchOffset();
@@ -9937,7 +9928,7 @@
// There is no way to know if the word was indeed added. Re-check.
// TODO The ExtractEditText should remove the span in the original text instead
editable.removeSpan(suggestionInfo.suggestionSpan);
- updateSpellCheckSpans(spanStart, spanEnd);
+ updateSpellCheckSpans(spanStart, spanEnd, false);
} else {
// SuggestionSpans are removed by replace: save them before
SuggestionSpan[] suggestionSpans = editable.getSpans(spanStart, spanEnd,
diff --git a/core/res/res/layout-sw600dp/keyguard_screen_sim_pin_landscape.xml b/core/res/res/layout-sw600dp/keyguard_screen_sim_pin_landscape.xml
index c65dd83..0b94fc1 100644
--- a/core/res/res/layout-sw600dp/keyguard_screen_sim_pin_landscape.xml
+++ b/core/res/res/layout-sw600dp/keyguard_screen_sim_pin_landscape.xml
@@ -93,17 +93,6 @@
android:layout_marginLeft="8dip"
android:layout_marginRight="8dip">
- <Button android:id="@+id/ok"
- android:text="@android:string/ok"
- android:layout_alignParentBottom="true"
- android:layout_width="0dip"
- android:layout_height="wrap_content"
- android:layout_weight="1.0"
- android:layout_marginBottom="8dip"
- android:layout_marginRight="8dip"
- android:textSize="18sp"
- />
-
<Button android:id="@+id/emergencyCallButton"
android:text="@android:string/lockscreen_emergency_call"
android:layout_alignParentBottom="true"
@@ -112,11 +101,22 @@
android:layout_height="wrap_content"
android:layout_weight="1.0"
android:layout_marginBottom="8dip"
- android:layout_marginLeft="8dip"
+ android:layout_marginRight="8dip"
android:textSize="18sp"
android:drawableLeft="@drawable/ic_emergency"
android:drawablePadding="8dip"
/>
+
+ <Button android:id="@+id/ok"
+ android:text="@android:string/ok"
+ android:layout_alignParentBottom="true"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1.0"
+ android:layout_marginBottom="8dip"
+ android:layout_marginLeft="8dip"
+ android:textSize="18sp"
+ />
</LinearLayout>
</RelativeLayout>
diff --git a/core/res/res/layout/keyguard_screen_sim_pin_landscape.xml b/core/res/res/layout/keyguard_screen_sim_pin_landscape.xml
index 59065e1..3cb19c3 100644
--- a/core/res/res/layout/keyguard_screen_sim_pin_landscape.xml
+++ b/core/res/res/layout/keyguard_screen_sim_pin_landscape.xml
@@ -91,17 +91,6 @@
android:layout_marginLeft="8dip"
android:layout_marginRight="8dip">
- <Button android:id="@+id/ok"
- android:text="@android:string/ok"
- android:layout_alignParentBottom="true"
- android:layout_width="0dip"
- android:layout_height="wrap_content"
- android:layout_weight="1.0"
- android:layout_marginBottom="8dip"
- android:layout_marginRight="8dip"
- android:textSize="18sp"
- />
-
<Button android:id="@+id/emergencyCallButton"
android:text="@android:string/lockscreen_emergency_call"
android:layout_alignParentBottom="true"
@@ -110,11 +99,22 @@
android:layout_height="wrap_content"
android:layout_weight="1.0"
android:layout_marginBottom="8dip"
- android:layout_marginLeft="8dip"
+ android:layout_marginRight="8dip"
android:textSize="18sp"
android:drawableLeft="@drawable/ic_emergency"
android:drawablePadding="4dip"
/>
+
+ <Button android:id="@+id/ok"
+ android:text="@android:string/ok"
+ android:layout_alignParentBottom="true"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1.0"
+ android:layout_marginBottom="8dip"
+ android:layout_marginLeft="8dip"
+ android:textSize="18sp"
+ />
</LinearLayout>
</RelativeLayout>
diff --git a/core/res/res/layout/keyguard_screen_sim_puk_landscape.xml b/core/res/res/layout/keyguard_screen_sim_puk_landscape.xml
index b662e82..722dc26 100644
--- a/core/res/res/layout/keyguard_screen_sim_puk_landscape.xml
+++ b/core/res/res/layout/keyguard_screen_sim_puk_landscape.xml
@@ -153,17 +153,6 @@
android:layout_marginLeft="8dip"
android:layout_marginRight="8dip">
- <Button android:id="@+id/ok"
- android:text="@android:string/ok"
- android:layout_alignParentBottom="true"
- android:layout_width="0dip"
- android:layout_height="wrap_content"
- android:layout_weight="1.0"
- android:layout_marginBottom="8dip"
- android:layout_marginRight="8dip"
- android:textSize="18sp"
- />
-
<Button android:id="@+id/emergencyCallButton"
android:text="@android:string/lockscreen_emergency_call"
android:layout_alignParentBottom="true"
@@ -172,11 +161,22 @@
android:layout_height="wrap_content"
android:layout_weight="1.0"
android:layout_marginBottom="8dip"
- android:layout_marginLeft="8dip"
+ android:layout_marginRight="8dip"
android:textSize="18sp"
android:drawableLeft="@drawable/ic_emergency"
android:drawablePadding="4dip"
/>
+
+ <Button android:id="@+id/ok"
+ android:text="@android:string/ok"
+ android:layout_alignParentBottom="true"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1.0"
+ android:layout_marginBottom="8dip"
+ android:layout_marginLeft="8dip"
+ android:textSize="18sp"
+ />
</LinearLayout>
</RelativeLayout>
diff --git a/core/res/res/layout/twelve_key_entry.xml b/core/res/res/layout/twelve_key_entry.xml
index 46301cd..09c749d 100644
--- a/core/res/res/layout/twelve_key_entry.xml
+++ b/core/res/res/layout/twelve_key_entry.xml
@@ -144,7 +144,7 @@
android:layout_marginRight="2dip"
android:orientation="horizontal">
- <Button android:id="@+id/ok"
+ <Button android:id="@+id/cancel"
android:layout_width="0sp"
android:layout_height="fill_parent"
android:layout_weight="1"
@@ -152,7 +152,7 @@
android:layout_marginRight="2dip"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textStyle="bold"
- android:text="@android:string/ok"
+ android:text="@android:string/cancel"
/>
<Button android:id="@+id/zero"
@@ -165,7 +165,7 @@
android:textStyle="bold"
/>
- <Button android:id="@+id/cancel"
+ <Button android:id="@+id/ok"
android:layout_width="0sp"
android:layout_height="fill_parent"
android:layout_weight="1"
@@ -173,7 +173,7 @@
android:layout_marginRight="2dip"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textStyle="bold"
- android:text="@android:string/cancel"
+ android:text="@android:string/ok"
/>
</LinearLayout>
diff --git a/docs/html/sdk/android-4.0.jd b/docs/html/sdk/android-4.0.jd
index e886bdf..7161b03 100644
--- a/docs/html/sdk/android-4.0.jd
+++ b/docs/html/sdk/android-4.0.jd
@@ -65,26 +65,42 @@
<p>To determine what revision of the Android {@sdkPlatformVersion} platform you
have installed, refer to the "Installed Packages" listing in the Android SDK Manager.</p>
+<p class="caution"><strong>Important:</strong> To download the new Android
+4.0 system components from the Android SDK Manager, you must first update the
+SDK tools to revision 14 or later and restart the Android SDK Manager. If you do not,
+the Android 4.0 system components will not be available for download.</p>
<div class="toggle-content opened" style="padding-left:1em;">
<p><a href="#" onclick="return toggleContent(this)">
<img src="{@docRoot}assets/images/triangle-opened.png"
class="toggle-content-img" alt="" />
+ Android {@sdkPlatformVersion}, Revision 2</a> <em>(December 2011)</em>
+ </a></p>
+
+ <div class="toggle-content-toggleme" style="padding-left:2em;">
+ <p>Maintenance update. The system version is 4.0.2.</p>
+ <dl>
+ <dt>Dependencies:</dt>
+ <dd>SDK Tools r14 or higher is required.</dd>
+ </dl>
+ </div>
+</div>
+
+<div class="toggle-content closed" style="padding-left:1em;">
+
+ <p><a href="#" onclick="return toggleContent(this)">
+ <img src="{@docRoot}assets/images/triangle-closed.png"
+class="toggle-content-img" alt="" />
Android {@sdkPlatformVersion}, Revision 1</a> <em>(October 2011)</em>
</a></p>
<div class="toggle-content-toggleme" style="padding-left:2em;">
-
-<dl>
-<dt>Initial release. SDK Tools r14 or higher is required.
- <p class="caution"><strong>Important:</strong> To download the new Android
- 4.0 system components from the Android SDK Manager, you must first update the
- SDK tools to revision 14 or later and restart the Android SDK Manager. If you do not,
- the Android 4.0 system components will not be available for download.</p>
-</dt>
-</dl>
-
+ <p>Initial release. The system version is 4.0.1.</p>
+ <dl>
+ <dt>Dependencies:</dt>
+ <dd>SDK Tools r14 or higher is required.</dd>
+ </dl>
</div>
</div>
diff --git a/docs/html/sdk/eclipse-adt.jd b/docs/html/sdk/eclipse-adt.jd
index 50b20ce..2445bff 100644
--- a/docs/html/sdk/eclipse-adt.jd
+++ b/docs/html/sdk/eclipse-adt.jd
@@ -1,8 +1,8 @@
page.title=ADT Plugin for Eclipse
-adt.zip.version=15.0.1
-adt.zip.download=ADT-15.0.1.zip
-adt.zip.bytes=6752327
-adt.zip.checksum=2c12a71d7124aa512b8ee016e19c0e69
+adt.zip.version=16.0.0
+adt.zip.download=ADT-16.0.0.zip
+adt.zip.bytes=6999205
+adt.zip.checksum=b7e512572580291279469845386b31b6
@jd:body
@@ -109,18 +109,49 @@
</style>
-
<div class="toggleable opened">
<a href="#" onclick="return toggleDiv(this)">
<img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px"
width="9px" />
+ADT 16.0.0</a> <em>(December 2011)</em>
+ <div class="toggleme">
+<dl>
+ <dt>Dependencies:</dt>
+
+ <dd>
+ <ul>
+ <li>Eclipse Helios (Version 3.6) or higher is required for ADT
+16.0.0.</li>
+ <li>ADT 16.0.0 is designed for use with <a
+href="{@docRoot}sdk/tools-notes.html">SDK Tools r16</a>. If you haven't already installed SDK Tools
+r16 into your SDK, use the Android SDK Manager to do so.</li>
+ </ul>
+ </dd>
+
+ <dt>General improvements:</dt>
+ <dd>
+ <ul>
+ <li>Added Lint tools to detect common errors in Android projects. (<a
+href="http://tools.android.com/recent/lint">more info</a>)</li>
+ </ul>
+ </dd>
+</dl>
+
+</div>
+</div>
+
+
+<div class="toggleable closed">
+ <a href="#" onclick="return toggleDiv(this)">
+ <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-img" height="9px"
+width="9px" />
ADT 15.0.1</a> <em>(November 2011)</em>
<div class="toggleme">
<dl>
<dt>Dependencies:</dt>
<dd>ADT 15.0.1 is designed for use with <a href="{@docRoot}sdk/tools-notes.html">SDK Tools r15</a>.
- If you haven't already installed SDK Tools r15 into your SDK, use the Android SDK and AVD Manager to
+ If you haven't already installed SDK Tools r15 into your SDK, use the Android SDK Manager to
do so.</dd>
<dt>Bug fixes:</dt>
@@ -154,7 +185,7 @@
<dt>Dependencies:</dt>
<dd>ADT 15.0.0 is designed for use with <a href="{@docRoot}sdk/tools-notes.html">SDK Tools r15</a>.
-If you haven't already installed SDK Tools r15 into your SDK, use the Android SDK and AVD Manager to
+If you haven't already installed SDK Tools r15 into your SDK, use the Android SDK Manager to
do so.</dd>
<dt>Bug fixes:</dt>
@@ -185,10 +216,10 @@
<dt>Dependencies:</dt>
<dd>ADT 14.0.0 is designed for use with <a href="{@docRoot}sdk/tools-notes.html">SDK Tools r14</a>.
-If you haven't already installed SDK Tools r14 into your SDK, use the Android SDK and AVD Manager to
+If you haven't already installed SDK Tools r14 into your SDK, use the Android SDK Manager to
do so.</dd>
-<dt>Build system</dt>
+<dt>Build system:</dt>
<dd>
<ul>
<li>Changed <code>default.properties</code> to <code>project.properties</code> and
@@ -211,7 +242,7 @@
site</a>.</p>
</dd>
-<dt>General improvements</dt>
+<dt>General improvements:</dt>
<dd>
<ul>
@@ -236,7 +267,7 @@
</ul>
</dd>
-<dt>XML and Java editors</dt>
+<dt>XML and Java editors:</dt>
<dd>
<ul>
<li>Added a new XML formatter that formats all XML files according to the
@@ -255,7 +286,7 @@
</ul>
</dd>
-<dt>Layout editor</dt>
+<dt>Layout editor:</dt>
<dd>
<ul>
<li>Added tooltip feedback for dragging and resizing operations. For
@@ -281,7 +312,7 @@
</ul>
</dd>
-<dt>Bug fixes</dt>
+<dt>Bug fixes:</dt>
<dd>Fixed many bugs and added <a
href="http://tools.android.com/recent/miscellaneousrecentfixes">minor improvements</a>, in
particular some <a href="http://tools.android.com/recent/linuxfixes">critical bug fixes on
@@ -324,7 +355,7 @@
</ul>
</dd>
-<dt>Build system</dt>
+<dt>Build system:</dt>
<dd>
<ul>
<li id="build-option">A new option lets you disable the packaging step in the automatic
@@ -336,7 +367,7 @@
</ul>
</dd>
-<dt>Bug fixes</dt>
+<dt>Bug fixes:</dt>
<dd>Many bug fixes are part of this release
(<a href="http://tools.android.com/recent/adt12bugfixroundup">more info</a>).</dd>
@@ -928,7 +959,7 @@
see <a href="{@docRoot}sdk/adding-components.html">Adding SDK Components</a>.</p>
</dd>
-<dt>General Notes:</dt>
+<dt>General notes:</dt>
<dd>
<ul>
<li>AVD Launch dialog now shows scale value.</li>
@@ -974,7 +1005,7 @@
</ul>
</dd>
-<dt>DDMS Integration:</dt>
+<dt>DDMS integration:</dt>
<dd>
<ul>
<li>Includes the improvements from the standlone DDMS, revision 3.</li>
diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd
index 193066b..65a1f46 100644
--- a/docs/html/sdk/index.jd
+++ b/docs/html/sdk/index.jd
@@ -1,21 +1,21 @@
page.title=Android SDK
sdk.redirect=0
-sdk.win_installer=installer_r15-windows.exe
-sdk.win_installer_bytes=33902520
-sdk.win_installer_checksum=ee8481cb86a6646a4d963d5142902c5c
+sdk.win_installer=installer_r16-windows.exe
+sdk.win_installer_bytes=29561554
+sdk.win_installer_checksum=3521dda4904886b05980590f83cf3469
-sdk.win_download=android-sdk_r15-windows.zip
-sdk.win_bytes=33895447
-sdk.win_checksum=cc2aadf7120d12b574981461736a96e9
+sdk.win_download=android-sdk_r16-windows.zip
+sdk.win_bytes=29562413
+sdk.win_checksum=6b926d0c0a871f1a946e65259984701a
-sdk.mac_download=android-sdk_r15-macosx.zip
-sdk.mac_bytes=30469921
-sdk.mac_checksum=03d2cdd3565771e8c7a438f1c40cc8a5
+sdk.mac_download=android-sdk_r16-macosx.zip
+sdk.mac_bytes=26158334
+sdk.mac_checksum=d1dc2b6f13eed5e3ce5cf26c4e4c47aa
-sdk.linux_download=android-sdk_r15-linux.tgz
-sdk.linux_bytes=26124434
-sdk.linux_checksum=f529681fd1eda11c6e1e1d44b42c1432
+sdk.linux_download=android-sdk_r16-linux.tgz
+sdk.linux_bytes=22048174
+sdk.linux_checksum=3ba457f731d51da3741c29c8830a4583
@jd:body
diff --git a/docs/html/sdk/requirements.jd b/docs/html/sdk/requirements.jd
index f12d0aa..c970f6c 100644
--- a/docs/html/sdk/requirements.jd
+++ b/docs/html/sdk/requirements.jd
@@ -24,8 +24,8 @@
<h4 style="margin-top:.25em"><em>Eclipse IDE</em></h4>
<ul>
- <li>Eclipse 3.5 (Galileo) or greater
-<p class="note"><strong>Note:</strong> Eclipse 3.4 (Ganymede) is no longer
+ <li>Eclipse 3.6 (Helios) or greater
+<p class="note"><strong>Note:</strong> Eclipse 3.5 (Galileo) is no longer
supported with the latest version of ADT.</p></li>
<li>Eclipse <a href="http://www.eclipse.org/jdt">JDT</a> plugin (included
in most Eclipse IDE packages) </li>
@@ -37,7 +37,7 @@
packages: </p>
<ul>
<li>Eclipse IDE for Java Developers</li>
- <li>Eclipse Classic (versions 3.5.1 and higher)</li>
+ <li>Eclipse Classic</li>
<li>Eclipse IDE for Java EE Developers</li>
</ul>
</li>
diff --git a/docs/html/sdk/sdk_toc.cs b/docs/html/sdk/sdk_toc.cs
index 0ae2c6d..791e7aa 100644
--- a/docs/html/sdk/sdk_toc.cs
+++ b/docs/html/sdk/sdk_toc.cs
@@ -150,7 +150,7 @@
</li>
</ul>
<ul>
- <li><a href="<?cs var:toroot ?>sdk/tools-notes.html">SDK Tools, r15</a> <span
+ <li><a href="<?cs var:toroot ?>sdk/tools-notes.html">SDK Tools, r16</a> <span
class="new">new!</span></li>
<li><a href="<?cs var:toroot ?>sdk/win-usb.html">Google USB Driver, r4</a></li>
<li><a href="<?cs var:toroot ?>sdk/compatibility-library.html">Support Package, r4</a>
@@ -169,7 +169,7 @@
<span style="display:none" class="zh-TW"></span>
</h2>
<ul>
- <li><a href="<?cs var:toroot ?>sdk/eclipse-adt.html">ADT 15.0.1
+ <li><a href="<?cs var:toroot ?>sdk/eclipse-adt.html">ADT 16.0.0
<span style="display:none" class="de"></span>
<span style="display:none" class="es"></span>
<span style="display:none" class="fr"></span>
diff --git a/docs/html/sdk/tools-notes.jd b/docs/html/sdk/tools-notes.jd
index cd03d9f..9a63467 100644
--- a/docs/html/sdk/tools-notes.jd
+++ b/docs/html/sdk/tools-notes.jd
@@ -9,7 +9,7 @@
latest revision of the SDK Tools in the <code><sdk>/tools</code> directory.</p>
<p>If you are already using the SDK and you want to update to the latest version
-of the SDK Tools, use the <em>Android SDK and AVD Manager</em> to get the
+of the SDK Tools, use the <em>Android SDK Manager</em> to get the
update, rather than downloading a new SDK starter package. For more information
about how to update, see <a
href="{@docRoot}sdk/adding-components.html#UpdatingComponents">Updating SDK
@@ -20,8 +20,7 @@
<p>The sections below provide notes about successive releases of
the SDK Tools, as denoted by revision number. To determine what revision of the SDK
-Tools you are using, refer to the "Installed Packages" listing in the Android SDK
-and AVD Manager. </p>
+Tools you are using, refer to the "Installed Packages" listing in the Android SDK Manager. </p>
<p>For a summary of all known issues in SDK Tools, see <a
href="http://tools.android.com/knownissues">http://tools.android.com/knownissues</a>.</p>
@@ -69,7 +68,57 @@
<div class="toggleable opened">
<a href="#" onclick="return toggleDiv(this)">
<img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px"
- width="9px" />SDK Tools, Revision 15</a> <em>(October 2011)</em>
+ width="9px" />
+ SDK Tools, Revision 16</a> <em>(December 2011)</em>
+
+ <div class="toggleme">
+ <p class="caution"><strong>Important:</strong> To download the new Android
+ 4.0 system components from the Android SDK Manager, you must first update the
+ SDK tools to revision 14 or later and restart the Android SDK Manager. If you do not,
+ the Android 4.0 system components will not be available for download.</p>
+
+<dl>
+<dt>Dependencies:</dt>
+<dd>
+ <ul>
+ <li>Android SDK Platform-tools revision 9 or later.</li>
+ <li>If you are developing in Eclipse with ADT, note that the SDK Tools r16 is designed for use
+ with ADT 16.0.0 and later. If you haven't already, we highly recommend updating your
+ <a href="{@docRoot}sdk/eclipse-adt.html">ADT Plugin</a> to 16.0.0.</li>
+ <li>If you are developing outside Eclipse, you must have <a href="http://ant.apache.org/">Apache
+ Ant</a> 1.8 or later.</li>
+</ul>
+</dd>
+<dt>General notes:</dt>
+<dd>
+ <ul>
+ <li>Added Lint tools to detect common errors in Android projects. (<a
+href="http://tools.android.com/recent/lint">more info</a>)</li>
+ <li>Added sensor emulation support, which allows the emulator to read sensor data from a
+physical Android device.</li>
+ <li>Added support for using a webcam to emulate a camera on Mac OS X.</li>
+ </ul>
+</dd>
+<dt>Bug fixes:</dt>
+<dd>
+ <ul>
+ <li>Snapshots now work for Android 4.0 system images.</li>
+ <li>Fixed several small issues for the build file.
+ (<a href="http://code.google.com/p/android/issues/detail?id=21023">Issue 21023</a>,
+ <a href="http://code.google.com/p/android/issues/detail?id=21267">Issue 21267</a>,
+ <a href="http://code.google.com/p/android/issues/detail?id=21465">Issue 21465</a>,
+ <a href="http://code.google.com/p/android/issues/detail?id=21525">Issue 21525</a>).</li>
+ </ul>
+</dd>
+</dl>
+</div>
+</div>
+
+<div class="toggleable closed">
+ <a href="#" onclick="return toggleDiv(this)">
+ <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-img" height="9px"
+ width="9px" />
+ SDK Tools, Revision 15</a> <em>(October 2011)</em>
<div class="toggleme">
<p class="caution"><strong>Important:</strong> To download the new Android
@@ -116,7 +165,8 @@
<div class="toggleable closed">
<a href="#" onclick="return toggleDiv(this)">
<img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-img" height="9px"
- width="9px" />SDK Tools, Revision 14</a> <em>(October 2011)</em>
+ width="9px" />
+ SDK Tools, Revision 14</a> <em>(October 2011)</em>
<div class="toggleme">
<p class="note"><strong>Important:</strong> To download the new Android
@@ -137,10 +187,11 @@
<dt>General notes:</dt>
<dd>
<ul>
- <li>Added webcam support to Android 4.0 or later platforms to emulate rear-facing cameras when one webcam is present,
- and to emulate both rear-facing and front-facing cameras when two webcams are present. Webcam suport is for Windows and Linux only.
+ <li>Added webcam support to Android 4.0 or later platforms to emulate rear-facing cameras when
+ one webcam is present, and to emulate both rear-facing and front-facing cameras when two
+ webcams are present. Webcam support is for Windows and Linux only.
Mac support will come in a later release.</li>
- <li>Changed <code>default.properties</code> to <code>project.properties</code> and
+ <li>Changed <code>default.properties</code> to <code>project.properties</code> and
<code>build.properties</code> to <code>ant.properties</code>. Any existing
projects that you build with Ant must be updated with the <code>android update project</code>
command.</li>
@@ -428,7 +479,7 @@
for more information.</li>
<li>Fixes location control in DDMS to work in any locale not using '.' as a
decimal point.</li>
-</li>
+</ul>
</ul>
</dd>
</dl>
diff --git a/libs/hwui/Program.cpp b/libs/hwui/Program.cpp
index 972dd87..4aff23e 100644
--- a/libs/hwui/Program.cpp
+++ b/libs/hwui/Program.cpp
@@ -27,35 +27,47 @@
Program::Program(const char* vertex, const char* fragment) {
mInitialized = false;
+ mHasColorUniform = false;
- vertexShader = buildShader(vertex, GL_VERTEX_SHADER);
+ // No need to cache compiled shaders, rely instead on Android's
+ // persistent shaders cache
+ GLuint vertexShader = buildShader(vertex, GL_VERTEX_SHADER);
if (vertexShader) {
- fragmentShader = buildShader(fragment, GL_FRAGMENT_SHADER);
+ GLuint fragmentShader = buildShader(fragment, GL_FRAGMENT_SHADER);
if (fragmentShader) {
- id = glCreateProgram();
- glAttachShader(id, vertexShader);
- glAttachShader(id, fragmentShader);
- glLinkProgram(id);
+ mProgramId = glCreateProgram();
+ glAttachShader(mProgramId, vertexShader);
+ glAttachShader(mProgramId, fragmentShader);
+ glLinkProgram(mProgramId);
GLint status;
- glGetProgramiv(id, GL_LINK_STATUS, &status);
+ glGetProgramiv(mProgramId, GL_LINK_STATUS, &status);
if (status != GL_TRUE) {
LOGE("Error while linking shaders:");
GLint infoLen = 0;
- glGetProgramiv(id, GL_INFO_LOG_LENGTH, &infoLen);
+ glGetProgramiv(mProgramId, GL_INFO_LOG_LENGTH, &infoLen);
if (infoLen > 1) {
GLchar log[infoLen];
- glGetProgramInfoLog(id, infoLen, 0, &log[0]);
+ glGetProgramInfoLog(mProgramId, infoLen, 0, &log[0]);
LOGE("%s", log);
}
- glDeleteShader(vertexShader);
- glDeleteShader(fragmentShader);
- glDeleteProgram(id);
} else {
mInitialized = true;
}
+
+ glDetachShader(mProgramId, vertexShader);
+ glDetachShader(mProgramId, fragmentShader);
+
+ glDeleteShader(vertexShader);
+ glDeleteShader(fragmentShader);
+
+ if (!mInitialized) {
+ glDeleteProgram(mProgramId);
+ }
+ } else {
+ glDeleteShader(vertexShader);
}
}
@@ -69,36 +81,34 @@
Program::~Program() {
if (mInitialized) {
- glDeleteShader(vertexShader);
- glDeleteShader(fragmentShader);
- glDeleteProgram(id);
+ glDeleteProgram(mProgramId);
}
}
int Program::addAttrib(const char* name) {
- int slot = glGetAttribLocation(id, name);
- attributes.add(name, slot);
+ int slot = glGetAttribLocation(mProgramId, name);
+ mAttributes.add(name, slot);
return slot;
}
int Program::getAttrib(const char* name) {
- ssize_t index = attributes.indexOfKey(name);
+ ssize_t index = mAttributes.indexOfKey(name);
if (index >= 0) {
- return attributes.valueAt(index);
+ return mAttributes.valueAt(index);
}
return addAttrib(name);
}
int Program::addUniform(const char* name) {
- int slot = glGetUniformLocation(id, name);
- uniforms.add(name, slot);
+ int slot = glGetUniformLocation(mProgramId, name);
+ mUniforms.add(name, slot);
return slot;
}
int Program::getUniform(const char* name) {
- ssize_t index = uniforms.indexOfKey(name);
+ ssize_t index = mUniforms.indexOfKey(name);
if (index >= 0) {
- return uniforms.valueAt(index);
+ return mUniforms.valueAt(index);
}
return addUniform(name);
}
@@ -127,10 +137,11 @@
const mat4& transformMatrix, bool offset) {
mat4 t(projectionMatrix);
if (offset) {
- // offset screenspace xy by an amount that compensates for typical precision issues
- // in GPU hardware that tends to paint hor/vert lines in pixels shifted up and to the left.
- // This offset value is based on an assumption that some hardware may use as little
- // as 12.4 precision, so we offset by slightly more than 1/16.
+ // offset screenspace xy by an amount that compensates for typical precision
+ // issues in GPU hardware that tends to paint hor/vert lines in pixels shifted
+ // up and to the left.
+ // This offset value is based on an assumption that some hardware may use as
+ // little as 12.4 precision, so we offset by slightly more than 1/16.
t.translate(.375, .375, 0);
}
t.multiply(transformMatrix);
@@ -140,20 +151,24 @@
}
void Program::setColor(const float r, const float g, const float b, const float a) {
- glUniform4f(getUniform("color"), r, g, b, a);
+ if (!mHasColorUniform) {
+ mColorUniform = getUniform("color");
+ mHasColorUniform = true;
+ }
+ glUniform4f(mColorUniform, r, g, b, a);
}
void Program::use() {
- glUseProgram(id);
+ glUseProgram(mProgramId);
mUse = true;
-
glEnableVertexAttribArray(position);
}
void Program::remove() {
mUse = false;
-
- glDisableVertexAttribArray(position);
+ // TODO: Is this necessary? It should not be since all of our shaders
+ // use slot 0 for the position attrib
+ // glDisableVertexAttribArray(position);
}
}; // namespace uirenderer
diff --git a/libs/hwui/Program.h b/libs/hwui/Program.h
index 764cb05..edd1209 100644
--- a/libs/hwui/Program.h
+++ b/libs/hwui/Program.h
@@ -122,18 +122,17 @@
GLuint buildShader(const char* source, GLenum type);
// Name of the OpenGL program
- GLuint id;
-
- // Name of the shaders
- GLuint vertexShader;
- GLuint fragmentShader;
+ GLuint mProgramId;
// Keeps track of attributes and uniforms slots
- KeyedVector<const char*, int> attributes;
- KeyedVector<const char*, int> uniforms;
+ KeyedVector<const char*, int> mAttributes;
+ KeyedVector<const char*, int> mUniforms;
bool mUse;
bool mInitialized;
+
+ bool mHasColorUniform;
+ int mColorUniform;
}; // class Program
}; // namespace uirenderer
diff --git a/libs/hwui/ProgramCache.h b/libs/hwui/ProgramCache.h
index 5c7197b..441db8c 100644
--- a/libs/hwui/ProgramCache.h
+++ b/libs/hwui/ProgramCache.h
@@ -27,6 +27,7 @@
#include "Debug.h"
#include "Program.h"
+#include "Properties.h"
namespace android {
namespace uirenderer {
@@ -42,8 +43,6 @@
#define PROGRAM_LOGD(...)
#endif
-// TODO: This should be set in properties
-#define PANEL_BIT_DEPTH 20
#define COLOR_COMPONENT_THRESHOLD (1.0f - (0.5f / PANEL_BIT_DEPTH))
#define COLOR_COMPONENT_INV_THRESHOLD (0.5f / PANEL_BIT_DEPTH)
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index 8c01e3a..2eae0f1 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -73,6 +73,9 @@
#define PROPERTY_TEXT_BLACK_GAMMA_THRESHOLD "ro.text_gamma.black_threshold"
#define PROPERTY_TEXT_WHITE_GAMMA_THRESHOLD "ro.text_gamma.white_threshold"
+// TODO: This should be set by a system property
+#define PANEL_BIT_DEPTH 20
+
// Converts a number of mega-bytes into bytes
#define MB(s) s * 1024 * 1024
diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
index a3f2bf6..6d28298 100644
--- a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
@@ -242,7 +242,7 @@
// playtime mapping. Assume the first packets correspond
// to time 0.
- LOGV("This is a live stream, assuming time = 0");
+ ALOGV("This is a live stream, assuming time = 0");
info->mRTPTime = rtpTime;
info->mNormalPlaytimeUs = 0ll;
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 8405264..42f18d3 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -335,11 +335,13 @@
return UNKNOWN_ERROR;
}
- dataSource->getDrmInfo(mDecryptHandle, &mDrmManagerClient);
- if (mDecryptHandle != NULL) {
- CHECK(mDrmManagerClient);
- if (RightsStatus::RIGHTS_VALID != mDecryptHandle->status) {
- notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
+ if (extractor->getDrmFlag()) {
+ dataSource->getDrmInfo(mDecryptHandle, &mDrmManagerClient);
+ if (mDecryptHandle != NULL) {
+ CHECK(mDrmManagerClient);
+ if (RightsStatus::RIGHTS_VALID != mDecryptHandle->status) {
+ notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
+ }
}
}
@@ -2103,6 +2105,7 @@
mWVMExtractor = new WVMExtractor(dataSource);
mWVMExtractor->setAdaptiveStreamingMode(true);
+ mWVMExtractor->setDrmFlag(true);
extractor = mWVMExtractor;
} else {
extractor = MediaExtractor::Create(
@@ -2113,12 +2116,14 @@
}
}
- dataSource->getDrmInfo(mDecryptHandle, &mDrmManagerClient);
+ if (extractor->getDrmFlag()) {
+ dataSource->getDrmInfo(mDecryptHandle, &mDrmManagerClient);
- if (mDecryptHandle != NULL) {
- CHECK(mDrmManagerClient);
- if (RightsStatus::RIGHTS_VALID != mDecryptHandle->status) {
- notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
+ if (mDecryptHandle != NULL) {
+ CHECK(mDrmManagerClient);
+ if (RightsStatus::RIGHTS_VALID != mDecryptHandle->status) {
+ notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
+ }
}
}
diff --git a/media/libstagefright/MediaExtractor.cpp b/media/libstagefright/MediaExtractor.cpp
index 2171492..d65dc51 100644
--- a/media/libstagefright/MediaExtractor.cpp
+++ b/media/libstagefright/MediaExtractor.cpp
@@ -114,6 +114,9 @@
ret = new AVIExtractor(source);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_WVM)) {
ret = new WVMExtractor(source);
+ if (ret != NULL) {
+ isDrm = true;
+ }
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC_ADTS)) {
ret = new AACExtractor(source, meta);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2PS)) {
diff --git a/media/libstagefright/rtsp/AAMRAssembler.cpp b/media/libstagefright/rtsp/AAMRAssembler.cpp
index 547b202..9d72b1f 100644
--- a/media/libstagefright/rtsp/AAMRAssembler.cpp
+++ b/media/libstagefright/rtsp/AAMRAssembler.cpp
@@ -79,13 +79,17 @@
}
static size_t getFrameSize(bool isWide, unsigned FT) {
- static const size_t kFrameSizeNB[8] = {
- 95, 103, 118, 134, 148, 159, 204, 244
+ static const size_t kFrameSizeNB[9] = {
+ 95, 103, 118, 134, 148, 159, 204, 244, 39
};
- static const size_t kFrameSizeWB[9] = {
- 132, 177, 253, 285, 317, 365, 397, 461, 477
+ static const size_t kFrameSizeWB[10] = {
+ 132, 177, 253, 285, 317, 365, 397, 461, 477, 40
};
+ if (FT == 15) {
+ return 1;
+ }
+
size_t frameSize = isWide ? kFrameSizeWB[FT] : kFrameSizeNB[FT];
// Round up bits to bytes and add 1 for the header byte.
@@ -161,8 +165,8 @@
unsigned FT = (toc >> 3) & 0x0f;
if ((toc & 3) != 0
- || (mIsWide && FT > 8)
- || (!mIsWide && FT > 7)) {
+ || (mIsWide && FT > 9 && FT != 15)
+ || (!mIsWide && FT > 8 && FT != 15)) {
queue->erase(queue->begin());
++mNextExpectedSeqNo;
diff --git a/media/libstagefright/rtsp/ARTSPConnection.cpp b/media/libstagefright/rtsp/ARTSPConnection.cpp
index 0fbbb9e..d8107bc 100644
--- a/media/libstagefright/rtsp/ARTSPConnection.cpp
+++ b/media/libstagefright/rtsp/ARTSPConnection.cpp
@@ -659,6 +659,7 @@
}
AString line;
+ ssize_t lastDictIndex = -1;
for (;;) {
if (!receiveLine(&line)) {
break;
@@ -668,7 +669,21 @@
break;
}
- ALOGV("line: %s", line.c_str());
+ ALOGV("line: '%s'", line.c_str());
+
+ if (line.c_str()[0] == ' ' || line.c_str()[0] == '\t') {
+ // Support for folded header values.
+
+ if (lastDictIndex < 0) {
+ // First line cannot be a continuation of the previous one.
+ return false;
+ }
+
+ AString &value = response->mHeaders.editValueAt(lastDictIndex);
+ value.append(line);
+
+ continue;
+ }
ssize_t colonPos = line.find(":");
if (colonPos < 0) {
@@ -681,9 +696,12 @@
key.tolower();
line.erase(0, colonPos + 1);
- line.trim();
- response->mHeaders.add(key, line);
+ lastDictIndex = response->mHeaders.add(key, line);
+ }
+
+ for (size_t i = 0; i < response->mHeaders.size(); ++i) {
+ response->mHeaders.editValueAt(i).trim();
}
unsigned long contentLength = 0;
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_rotate_on.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_rotate_on.png
index 6208581..02da243 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_rotate_on.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_rotate_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_wifi_on.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_wifi_on.png
index fe4d318..d645a3c 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_wifi_on.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_wifi_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_on.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_on.png
index 2536d92..9c117ae 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_on.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_wifi_on.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_wifi_on.png
index 44e3577..4f51201 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_wifi_on.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_wifi_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_rotate_on.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_rotate_on.png
index b375396..35d85e1 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_rotate_on.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_rotate_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_wifi_on.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_wifi_on.png
index 54e3d1e..bc1628f 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_wifi_on.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_wifi_on.png
Binary files differ
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 75f1408..016dc82 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -152,8 +152,12 @@
/* Wifi disabled due to airplane mode on */
private static final int WIFI_DISABLED_AIRPLANE_ON = 3;
- private AtomicInteger mWifiState = new AtomicInteger(WIFI_DISABLED);
+ /* Persisted state that tracks the wifi & airplane interaction from settings */
+ private AtomicInteger mPersistWifiState = new AtomicInteger(WIFI_DISABLED);
+ /* Tracks current airplane mode state */
private AtomicBoolean mAirplaneModeOn = new AtomicBoolean(false);
+ /* Tracks whether wifi is enabled from WifiStateMachine's perspective */
+ private boolean mWifiEnabled;
private boolean mIsReceiverRegistered = false;
@@ -373,8 +377,8 @@
mAirplaneModeOn.set(isAirplaneModeOn());
/* On airplane mode disable, restore wifi state if necessary */
if (!mAirplaneModeOn.get() && (testAndClearWifiSavedState() ||
- mWifiState.get() == WIFI_ENABLED_AIRPLANE_OVERRIDE)) {
- persistWifiEnabled(true);
+ mPersistWifiState.get() == WIFI_ENABLED_AIRPLANE_OVERRIDE)) {
+ persistWifiState(true);
}
updateWifiState();
}
@@ -391,7 +395,12 @@
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
- // reset & clear notification on any wifi state change
+ int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
+ WifiManager.WIFI_STATE_DISABLED);
+
+ mWifiEnabled = (wifiState == WifiManager.WIFI_STATE_ENABLED);
+
+ // reset & clear notification on any wifi state change
resetNotification();
} else if (intent.getAction().equals(
WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
@@ -435,7 +444,7 @@
*/
public void checkAndStartWifi() {
mAirplaneModeOn.set(isAirplaneModeOn());
- mWifiState.set(getPersistedWifiState());
+ mPersistWifiState.set(getPersistedWifiState());
/* Start if Wi-Fi should be enabled or the saved state indicates Wi-Fi was on */
boolean wifiEnabled = shouldWifiBeEnabled() || testAndClearWifiSavedState();
Slog.i(TAG, "WifiService starting up with Wi-Fi " +
@@ -472,29 +481,30 @@
private boolean shouldWifiBeEnabled() {
if (mAirplaneModeOn.get()) {
- return mWifiState.get() == WIFI_ENABLED_AIRPLANE_OVERRIDE;
+ return mPersistWifiState.get() == WIFI_ENABLED_AIRPLANE_OVERRIDE;
} else {
- return mWifiState.get() != WIFI_DISABLED;
+ return mPersistWifiState.get() != WIFI_DISABLED;
}
}
- private void persistWifiEnabled(boolean enabled) {
+ private void persistWifiState(boolean enabled) {
final ContentResolver cr = mContext.getContentResolver();
boolean airplane = mAirplaneModeOn.get() && isAirplaneToggleable();
if (enabled) {
if (airplane) {
- mWifiState.set(WIFI_ENABLED_AIRPLANE_OVERRIDE);
+ mPersistWifiState.set(WIFI_ENABLED_AIRPLANE_OVERRIDE);
} else {
- mWifiState.set(WIFI_ENABLED);
+ mPersistWifiState.set(WIFI_ENABLED);
}
} else {
if (airplane) {
- mWifiState.set(WIFI_DISABLED_AIRPLANE_ON);
+ mPersistWifiState.set(WIFI_DISABLED_AIRPLANE_ON);
} else {
- mWifiState.set(WIFI_DISABLED);
+ mPersistWifiState.set(WIFI_DISABLED);
}
}
- Settings.Secure.putInt(cr, Settings.Secure.WIFI_ON, mWifiState.get());
+
+ Settings.Secure.putInt(cr, Settings.Secure.WIFI_ON, mPersistWifiState.get());
}
@@ -545,7 +555,6 @@
*/
public synchronized boolean setWifiEnabled(boolean enable) {
enforceChangePermission();
-
if (DBG) {
Slog.e(TAG, "Invoking mWifiStateMachine.setWifiEnabled\n");
}
@@ -559,16 +568,20 @@
* Caller might not have WRITE_SECURE_SETTINGS,
* only CHANGE_WIFI_STATE is enforced
*/
- long ident = Binder.clearCallingIdentity();
- persistWifiEnabled(enable);
- Binder.restoreCallingIdentity(ident);
+
+ /* Avoids overriding of airplane state when wifi is already in the expected state */
+ if (enable != mWifiEnabled) {
+ long ident = Binder.clearCallingIdentity();
+ persistWifiState(enable);
+ Binder.restoreCallingIdentity(ident);
+ }
if (enable) {
if (!mIsReceiverRegistered) {
registerForBroadcasts();
mIsReceiverRegistered = true;
}
- } else if (mIsReceiverRegistered){
+ } else if (mIsReceiverRegistered) {
mContext.unregisterReceiver(mReceiver);
mIsReceiverRegistered = false;
}
diff --git a/services/java/com/android/server/connectivity/Tethering.java b/services/java/com/android/server/connectivity/Tethering.java
index b1551a6..bc8ce7d 100644
--- a/services/java/com/android/server/connectivity/Tethering.java
+++ b/services/java/com/android/server/connectivity/Tethering.java
@@ -118,7 +118,7 @@
"192.168.48.2", "192.168.48.254",
};
- private String[] mDnsServers;
+ private String[] mDefaultDnsServers;
private static final String DNS_DEFAULT_SERVER1 = "8.8.8.8";
private static final String DNS_DEFAULT_SERVER2 = "8.8.4.4";
@@ -171,9 +171,9 @@
updateConfiguration();
// TODO - remove and rely on real notifications of the current iface
- mDnsServers = new String[2];
- mDnsServers[0] = DNS_DEFAULT_SERVER1;
- mDnsServers[1] = DNS_DEFAULT_SERVER2;
+ mDefaultDnsServers = new String[2];
+ mDefaultDnsServers[0] = DNS_DEFAULT_SERVER1;
+ mDefaultDnsServers[1] = DNS_DEFAULT_SERVER2;
}
void updateConfiguration() {
@@ -1244,7 +1244,7 @@
}
}
try {
- mNMService.setDnsForwarders(mDnsServers);
+ mNMService.setDnsForwarders(mDefaultDnsServers);
} catch (Exception e) {
transitionTo(mSetDnsForwardersErrorState);
return false;
@@ -1320,7 +1320,19 @@
try {
linkProperties = mConnService.getLinkProperties(upType);
} catch (RemoteException e) { }
- if (linkProperties != null) iface = linkProperties.getInterfaceName();
+ if (linkProperties != null) {
+ iface = linkProperties.getInterfaceName();
+ String[] dnsServers = mDefaultDnsServers;
+ Collection<InetAddress> dnses = linkProperties.getDnses();
+ if (dnses != null) {
+ dnsServers = NetworkUtils.makeStrings(dnses);
+ }
+ try {
+ mNMService.setDnsForwarders(dnsServers);
+ } catch (Exception e) {
+ transitionTo(mSetDnsForwardersErrorState);
+ }
+ }
}
notifyTetheredOfNewUpstreamIface(iface);
}
diff --git a/services/java/com/android/server/connectivity/Vpn.java b/services/java/com/android/server/connectivity/Vpn.java
index 55e0678..72cf512 100644
--- a/services/java/com/android/server/connectivity/Vpn.java
+++ b/services/java/com/android/server/connectivity/Vpn.java
@@ -482,6 +482,7 @@
if (state.exists()) {
throw new IllegalStateException("Cannot delete the state");
}
+ new File("/data/misc/vpn/abort").delete();
// Check if we need to restart any of the daemons.
boolean restart = false;