summaryrefslogtreecommitdiffstats
path: root/core/java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/bluetooth/BluetoothAdapter.java21
-rw-r--r--core/java/android/inputmethodservice/ExtractEditText.java33
-rw-r--r--core/java/android/inputmethodservice/InputMethodService.java16
-rw-r--r--core/java/android/speech/tts/AudioPlaybackQueueItem.java80
-rw-r--r--core/java/android/speech/tts/BlockingMediaPlayer.java145
-rw-r--r--core/java/android/speech/tts/MessageParams.java47
-rw-r--r--core/java/android/speech/tts/TextToSpeechService.java9
-rw-r--r--core/java/android/text/SpannableStringBuilder.java11
-rw-r--r--core/java/android/text/method/WordIterator.java7
-rw-r--r--core/java/android/text/style/SuggestionSpan.java16
-rw-r--r--core/java/android/view/HardwareRenderer.java17
-rw-r--r--core/java/android/view/ViewRootImpl.java3
-rw-r--r--core/java/android/webkit/WebView.java7
-rw-r--r--core/java/android/webkit/WebViewCore.java2
-rw-r--r--core/java/android/webkit/ZoomManager.java18
-rw-r--r--core/java/android/widget/NumberPicker.java19
-rw-r--r--core/java/android/widget/SpellChecker.java6
-rw-r--r--core/java/android/widget/TextView.java30
18 files changed, 230 insertions, 257 deletions
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 5f5ba50..e420bfd 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -399,6 +399,25 @@ public final class BluetoothAdapter {
}
/**
+ * Get a {@link BluetoothDevice} object for the given Bluetooth hardware
+ * address.
+ * <p>Valid Bluetooth hardware addresses must be 6 bytes. This method
+ * expects the address in network byte order (MSB first).
+ * <p>A {@link BluetoothDevice} will always be returned for a valid
+ * hardware address, even if this adapter has never seen that device.
+ *
+ * @param address Bluetooth MAC address (6 bytes)
+ * @throws IllegalArgumentException if address is invalid
+ */
+ public BluetoothDevice getRemoteDevice(byte[] address) {
+ if (address == null || address.length != 6) {
+ throw new IllegalArgumentException("Bluetooth address must have 6 bytes");
+ }
+ return new BluetoothDevice(String.format("%02X:%02X:%02X:%02X:%02X:%02X",
+ address[0], address[1], address[2], address[3], address[4], address[5]));
+ }
+
+ /**
* Return true if Bluetooth is currently enabled and ready for use.
* <p>Equivalent to:
* <code>getBluetoothState() == STATE_ON</code>
@@ -1281,7 +1300,7 @@ public final class BluetoothAdapter {
}
/**
- * Validate a Bluetooth address, such as "00:43:A8:23:10:F0"
+ * Validate a String Bluetooth address, such as "00:43:A8:23:10:F0"
* <p>Alphabetic characters must be uppercase to be valid.
*
* @param address Bluetooth address as string
diff --git a/core/java/android/inputmethodservice/ExtractEditText.java b/core/java/android/inputmethodservice/ExtractEditText.java
index 72431f3..10c1195 100644
--- a/core/java/android/inputmethodservice/ExtractEditText.java
+++ b/core/java/android/inputmethodservice/ExtractEditText.java
@@ -158,25 +158,46 @@ public class ExtractEditText extends EditText {
}
/**
- * Delete the range of text, supposedly valid
+ * {@inheritDoc}
* @hide
*/
@Override
protected void deleteText_internal(int start, int end) {
- // Do not call the super method. This will change the source TextView instead, which
- // will update the ExtractTextView.
+ // Do not call the super method.
+ // This will change the source TextView instead, which will update the ExtractTextView.
mIME.onExtractedDeleteText(start, end);
}
/**
- * Replaces the range of text [start, end[ by replacement text
+ * {@inheritDoc}
* @hide
*/
@Override
protected void replaceText_internal(int start, int end, CharSequence text) {
- // Do not call the super method. This will change the source TextView instead, which
- // will update the ExtractTextView.
+ // Do not call the super method.
+ // This will change the source TextView instead, which will update the ExtractTextView.
mIME.onExtractedReplaceText(start, end, text);
}
+ /**
+ * {@inheritDoc}
+ * @hide
+ */
+ @Override
+ protected void setSpan_internal(Object span, int start, int end, int flags) {
+ // Do not call the super method.
+ // This will change the source TextView instead, which will update the ExtractTextView.
+ mIME.onExtractedSetSpan(span, start, end, flags);
+ }
+
+ /**
+ * {@inheritDoc}
+ * @hide
+ */
+ @Override
+ protected void setCursorPosition_internal(int start, int end) {
+ // Do not call the super method.
+ // This will change the source TextView instead, which will update the ExtractTextView.
+ mIME.onExtractedSelectionChanged(start, end);
+ }
}
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 02839db..53cdf21 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -2006,6 +2006,22 @@ public class InputMethodService extends AbstractInputMethodService {
}
/**
+ * @hide
+ */
+ public void onExtractedSetSpan(Object span, int start, int end, int flags) {
+ InputConnection conn = getCurrentInputConnection();
+ if (conn != null) {
+ if (!conn.setSelection(start, end)) return;
+ CharSequence text = conn.getSelectedText(InputConnection.GET_TEXT_WITH_STYLES);
+ if (text instanceof Spannable) {
+ ((Spannable) text).setSpan(span, 0, text.length(), flags);
+ conn.setComposingRegion(start, end);
+ conn.commitText(text, 1);
+ }
+ }
+ }
+
+ /**
* This is called when the user has clicked on the extracted text view,
* when running in fullscreen mode. The default implementation hides
* the candidates view when this happens, but only if the extracted text
diff --git a/core/java/android/speech/tts/AudioPlaybackQueueItem.java b/core/java/android/speech/tts/AudioPlaybackQueueItem.java
index 668b459..1a1fda8 100644
--- a/core/java/android/speech/tts/AudioPlaybackQueueItem.java
+++ b/core/java/android/speech/tts/AudioPlaybackQueueItem.java
@@ -15,27 +15,91 @@
*/
package android.speech.tts;
+import android.content.Context;
+import android.media.MediaPlayer;
+import android.net.Uri;
+import android.os.ConditionVariable;
import android.speech.tts.TextToSpeechService.UtteranceProgressDispatcher;
import android.util.Log;
class AudioPlaybackQueueItem extends PlaybackQueueItem {
- private final BlockingMediaPlayer mPlayer;
+ private static final String TAG = "TTS.AudioQueueItem";
+
+ private final Context mContext;
+ private final Uri mUri;
+ private final int mStreamType;
+
+ private final ConditionVariable mDone;
+ private MediaPlayer mPlayer;
+ private volatile boolean mFinished;
AudioPlaybackQueueItem(UtteranceProgressDispatcher dispatcher,
- Object callerIdentity, BlockingMediaPlayer player) {
+ Object callerIdentity,
+ Context context, Uri uri, int streamType) {
super(dispatcher, callerIdentity);
- mPlayer = player;
+
+ mContext = context;
+ mUri = uri;
+ mStreamType = streamType;
+
+ mDone = new ConditionVariable();
+ mPlayer = null;
+ mFinished = false;
}
@Override
public void run() {
- getDispatcher().dispatchOnStart();
- // TODO: This can be avoided. Will be fixed later in this CL.
- mPlayer.startAndWait();
- getDispatcher().dispatchOnDone();
+ final UtteranceProgressDispatcher dispatcher = getDispatcher();
+
+ dispatcher.dispatchOnStart();
+ mPlayer = MediaPlayer.create(mContext, mUri);
+ if (mPlayer == null) {
+ dispatcher.dispatchOnError();
+ return;
+ }
+
+ try {
+ mPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
+ @Override
+ public boolean onError(MediaPlayer mp, int what, int extra) {
+ Log.w(TAG, "Audio playback error: " + what + ", " + extra);
+ mDone.open();
+ return true;
+ }
+ });
+ mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
+ @Override
+ public void onCompletion(MediaPlayer mp) {
+ mFinished = true;
+ mDone.open();
+ }
+ });
+ mPlayer.setAudioStreamType(mStreamType);
+ mPlayer.start();
+ mDone.block();
+ finish();
+ } catch (IllegalArgumentException ex) {
+ Log.w(TAG, "MediaPlayer failed", ex);
+ mDone.open();
+ }
+
+ if (mFinished) {
+ dispatcher.dispatchOnDone();
+ } else {
+ dispatcher.dispatchOnError();
+ }
+ }
+
+ private void finish() {
+ try {
+ mPlayer.stop();
+ } catch (IllegalStateException ex) {
+ // Do nothing, the player is already stopped
+ }
+ mPlayer.release();
}
@Override
void stop(boolean isError) {
- mPlayer.stop();
+ mDone.open();
}
}
diff --git a/core/java/android/speech/tts/BlockingMediaPlayer.java b/core/java/android/speech/tts/BlockingMediaPlayer.java
deleted file mode 100644
index 1ccc6e4..0000000
--- a/core/java/android/speech/tts/BlockingMediaPlayer.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package android.speech.tts;
-
-import android.content.Context;
-import android.media.MediaPlayer;
-import android.net.Uri;
-import android.os.ConditionVariable;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.util.Log;
-
-/**
- * A media player that allows blocking to wait for it to finish.
- */
-class BlockingMediaPlayer {
-
- private static final String TAG = "BlockMediaPlayer";
-
- private static final String MEDIA_PLAYER_THREAD_NAME = "TTS-MediaPlayer";
-
- private final Context mContext;
- private final Uri mUri;
- private final int mStreamType;
- private final ConditionVariable mDone;
- // Only accessed on the Handler thread
- private MediaPlayer mPlayer;
- private volatile boolean mFinished;
-
- /**
- * Creates a new blocking media player.
- * Creating a blocking media player is a cheap operation.
- *
- * @param context
- * @param uri
- * @param streamType
- */
- public BlockingMediaPlayer(Context context, Uri uri, int streamType) {
- mContext = context;
- mUri = uri;
- mStreamType = streamType;
- mDone = new ConditionVariable();
- }
-
- /**
- * Starts playback and waits for it to finish.
- * Can be called from any thread.
- *
- * @return {@code true} if the playback finished normally, {@code false} if the playback
- * failed or {@link #stop} was called before the playback finished.
- */
- public boolean startAndWait() {
- HandlerThread thread = new HandlerThread(MEDIA_PLAYER_THREAD_NAME);
- thread.start();
- Handler handler = new Handler(thread.getLooper());
- mFinished = false;
- handler.post(new Runnable() {
- @Override
- public void run() {
- startPlaying();
- }
- });
- mDone.block();
- handler.post(new Runnable() {
- @Override
- public void run() {
- finish();
- // No new messages should get posted to the handler thread after this
- Looper.myLooper().quit();
- }
- });
- return mFinished;
- }
-
- /**
- * Stops playback. Can be called multiple times.
- * Can be called from any thread.
- */
- public void stop() {
- mDone.open();
- }
-
- /**
- * Starts playback.
- * Called on the handler thread.
- */
- private void startPlaying() {
- mPlayer = MediaPlayer.create(mContext, mUri);
- if (mPlayer == null) {
- Log.w(TAG, "Failed to play " + mUri);
- mDone.open();
- return;
- }
- try {
- mPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
- @Override
- public boolean onError(MediaPlayer mp, int what, int extra) {
- Log.w(TAG, "Audio playback error: " + what + ", " + extra);
- mDone.open();
- return true;
- }
- });
- mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
- @Override
- public void onCompletion(MediaPlayer mp) {
- mFinished = true;
- mDone.open();
- }
- });
- mPlayer.setAudioStreamType(mStreamType);
- mPlayer.start();
- } catch (IllegalArgumentException ex) {
- Log.w(TAG, "MediaPlayer failed", ex);
- mDone.open();
- }
- }
-
- /**
- * Stops playback and release the media player.
- * Called on the handler thread.
- */
- private void finish() {
- try {
- mPlayer.stop();
- } catch (IllegalStateException ex) {
- // Do nothing, the player is already stopped
- }
- mPlayer.release();
- }
-
-} \ No newline at end of file
diff --git a/core/java/android/speech/tts/MessageParams.java b/core/java/android/speech/tts/MessageParams.java
deleted file mode 100644
index f83b793..0000000
--- a/core/java/android/speech/tts/MessageParams.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package android.speech.tts;
-
-import android.speech.tts.TextToSpeechService.UtteranceProgressDispatcher;
-
-abstract class MessageParams {
- static final int TYPE_SYNTHESIS = 1;
- static final int TYPE_AUDIO = 2;
- static final int TYPE_SILENCE = 3;
-
- private final UtteranceProgressDispatcher mDispatcher;
- private final Object mCallerIdentity;
-
- MessageParams(UtteranceProgressDispatcher dispatcher, Object callerIdentity) {
- mDispatcher = dispatcher;
- mCallerIdentity = callerIdentity;
- }
-
- UtteranceProgressDispatcher getDispatcher() {
- return mDispatcher;
- }
-
- Object getCallerIdentity() {
- return mCallerIdentity;
- }
-
- @Override
- public String toString() {
- return "MessageParams[" + hashCode() + "]";
- }
-
- abstract int getType();
-}
diff --git a/core/java/android/speech/tts/TextToSpeechService.java b/core/java/android/speech/tts/TextToSpeechService.java
index ba8485a..4c1a0af 100644
--- a/core/java/android/speech/tts/TextToSpeechService.java
+++ b/core/java/android/speech/tts/TextToSpeechService.java
@@ -694,12 +694,12 @@ public abstract class TextToSpeechService extends Service {
}
private class AudioSpeechItem extends SpeechItem {
- private final BlockingMediaPlayer mPlayer;
-
+ private final AudioPlaybackQueueItem mItem;
public AudioSpeechItem(Object callerIdentity, int callerUid, int callerPid,
Bundle params, Uri uri) {
super(callerIdentity, callerUid, callerPid, params);
- mPlayer = new BlockingMediaPlayer(TextToSpeechService.this, uri, getStreamType());
+ mItem = new AudioPlaybackQueueItem(this, getCallerIdentity(),
+ TextToSpeechService.this, uri, getStreamType());
}
@Override
@@ -709,8 +709,7 @@ public abstract class TextToSpeechService extends Service {
@Override
protected int playImpl() {
- mAudioPlaybackHandler.enqueue(new AudioPlaybackQueueItem(
- this, getCallerIdentity(), mPlayer));
+ mAudioPlaybackHandler.enqueue(mItem);
return TextToSpeech.SUCCESS;
}
diff --git a/core/java/android/text/SpannableStringBuilder.java b/core/java/android/text/SpannableStringBuilder.java
index 231f913..b708750 100644
--- a/core/java/android/text/SpannableStringBuilder.java
+++ b/core/java/android/text/SpannableStringBuilder.java
@@ -863,6 +863,17 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable
return new String(buf);
}
+ /**
+ * Return a String containing a copy of the chars in this buffer, limited to the
+ * [start, end[ range.
+ * @hide
+ */
+ public String substring(int start, int end) {
+ char[] buf = new char[end - start];
+ getChars(start, end, buf, 0);
+ return new String(buf);
+ }
+
private TextWatcher[] sendTextWillChange(int start, int before, int after) {
TextWatcher[] recip = getSpans(start, start + before, TextWatcher.class);
int n = recip.length;
diff --git a/core/java/android/text/method/WordIterator.java b/core/java/android/text/method/WordIterator.java
index 239d9e8..11226a9 100644
--- a/core/java/android/text/method/WordIterator.java
+++ b/core/java/android/text/method/WordIterator.java
@@ -18,6 +18,7 @@
package android.text.method;
import android.text.Selection;
+import android.text.SpannableStringBuilder;
import java.text.BreakIterator;
import java.util.Locale;
@@ -58,7 +59,11 @@ public class WordIterator implements Selection.PositionIterator {
mOffsetShift = Math.max(0, start - WINDOW_WIDTH);
final int windowEnd = Math.min(charSequence.length(), end + WINDOW_WIDTH);
- mString = charSequence.toString().substring(mOffsetShift, windowEnd);
+ if (charSequence instanceof SpannableStringBuilder) {
+ mString = ((SpannableStringBuilder) charSequence).substring(mOffsetShift, windowEnd);
+ } else {
+ mString = charSequence.subSequence(mOffsetShift, windowEnd).toString();
+ }
mIterator.setText(mString);
}
diff --git a/core/java/android/text/style/SuggestionSpan.java b/core/java/android/text/style/SuggestionSpan.java
index ed2af10..0f26a34 100644
--- a/core/java/android/text/style/SuggestionSpan.java
+++ b/core/java/android/text/style/SuggestionSpan.java
@@ -92,11 +92,6 @@ public class SuggestionSpan extends CharacterStyle implements ParcelableSpan {
private float mAutoCorrectionUnderlineThickness;
private int mAutoCorrectionUnderlineColor;
- /*
- * TODO: If switching IME is required, needs to add parameters for ids of InputMethodInfo
- * and InputMethodSubtype.
- */
-
/**
* @param context Context for the application
* @param suggestions Suggestions for the string under the span
@@ -146,6 +141,16 @@ public class SuggestionSpan extends CharacterStyle implements ParcelableSpan {
}
private void initStyle(Context context) {
+ if (context == null) {
+ mMisspelledUnderlineThickness = 0;
+ mEasyCorrectUnderlineThickness = 0;
+ mAutoCorrectionUnderlineThickness = 0;
+ mMisspelledUnderlineColor = Color.BLACK;
+ mEasyCorrectUnderlineColor = Color.BLACK;
+ mAutoCorrectionUnderlineColor = Color.BLACK;
+ return;
+ }
+
int defStyle = com.android.internal.R.attr.textAppearanceMisspelledSuggestion;
TypedArray typedArray = context.obtainStyledAttributes(
null, com.android.internal.R.styleable.SuggestionSpan, defStyle, 0);
@@ -169,7 +174,6 @@ public class SuggestionSpan extends CharacterStyle implements ParcelableSpan {
com.android.internal.R.styleable.SuggestionSpan_textUnderlineThickness, 0);
mAutoCorrectionUnderlineColor = typedArray.getColor(
com.android.internal.R.styleable.SuggestionSpan_textUnderlineColor, Color.BLACK);
-
}
public SuggestionSpan(Parcel src) {
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 443acf6..3f793bb 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -441,6 +441,8 @@ public abstract class HardwareRenderer {
}
boolean mDirtyRegionsEnabled;
+ boolean mUpdateDirtyRegions;
+
final boolean mVsyncDisabled;
final int mGlVersion;
@@ -675,6 +677,12 @@ public abstract class HardwareRenderer {
initCaches();
+ enableDirtyRegions();
+
+ return mEglContext.getGL();
+ }
+
+ private void enableDirtyRegions() {
// If mDirtyRegions is set, this means we have an EGL configuration
// with EGL_SWAP_BEHAVIOR_PRESERVED_BIT set
if (sDirtyRegions) {
@@ -690,8 +698,6 @@ public abstract class HardwareRenderer {
// configuration (see RENDER_DIRTY_REGIONS)
mDirtyRegionsEnabled = GLES20Canvas.isBackBufferPreserved();
}
-
- return mEglContext.getGL();
}
abstract void initCaches();
@@ -745,6 +751,9 @@ public abstract class HardwareRenderer {
if (!createSurface(holder)) {
return;
}
+
+ mUpdateDirtyRegions = true;
+
if (mCanvas != null) {
setEnabled(true);
}
@@ -943,6 +952,10 @@ public abstract class HardwareRenderer {
fallback(true);
return SURFACE_STATE_ERROR;
} else {
+ if (mUpdateDirtyRegions) {
+ enableDirtyRegions();
+ mUpdateDirtyRegions = false;
+ }
return SURFACE_STATE_UPDATED;
}
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 7a9d82c..72966ef 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -3257,8 +3257,9 @@ public final class ViewRootImpl extends Handler implements ViewParent,
}
// If the Control modifier is held, try to interpret the key as a shortcut.
- if (event.getAction() == KeyEvent.ACTION_UP
+ if (event.getAction() == KeyEvent.ACTION_DOWN
&& event.isCtrlPressed()
+ && event.getRepeatCount() == 0
&& !KeyEvent.isModifierKey(event.getKeyCode())) {
if (mView.dispatchKeyShortcutEvent(event)) {
finishInputEvent(q, true);
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 40cb248..a284a17 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -2496,11 +2496,12 @@ public class WebView extends AbsoluteLayout
}
/**
- * Return the reading level scale of the WebView
+ * Compute the reading level scale of the WebView
+ * @param scale The current scale.
* @return The reading level scale.
*/
- /*package*/ float getReadingLevelScale() {
- return mZoomManager.getReadingLevelScale();
+ /*package*/ float computeReadingLevelScale(float scale) {
+ return mZoomManager.computeReadingLevelScale(scale);
}
/**
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 0f749bc..14da23e 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -2514,7 +2514,7 @@ public final class WebViewCore {
if (mSettings.isNarrowColumnLayout()) {
// In case of automatic text reflow in fixed view port mode.
mInitialViewState.mTextWrapScale =
- mWebView.getReadingLevelScale();
+ mWebView.computeReadingLevelScale(data.mScale);
}
} else {
// Scale is given such as when page is restored, use it.
diff --git a/core/java/android/webkit/ZoomManager.java b/core/java/android/webkit/ZoomManager.java
index 14bdc42..8ffba64 100644
--- a/core/java/android/webkit/ZoomManager.java
+++ b/core/java/android/webkit/ZoomManager.java
@@ -316,7 +316,12 @@ class ZoomManager {
* Returns the zoom scale used for reading text on a double-tap.
*/
public final float getReadingLevelScale() {
- return mDisplayDensity * mDoubleTapZoomFactor;
+ return computeScaleWithLimits(computeReadingLevelScale(getZoomOverviewScale()));
+ }
+
+ /* package */ final float computeReadingLevelScale(float scale) {
+ return Math.max(mDisplayDensity * mDoubleTapZoomFactor,
+ scale + MIN_DOUBLE_TAP_SCALE_INCREMENT);
}
public final float getInvDefaultScale() {
@@ -678,7 +683,7 @@ class ZoomManager {
}
zoomToOverview();
} else {
- zoomToReadingLevelOrMore();
+ zoomToReadingLevel();
}
}
@@ -709,9 +714,8 @@ class ZoomManager {
!mWebView.getSettings().getUseFixedViewport());
}
- private void zoomToReadingLevelOrMore() {
- final float zoomScale = Math.max(getReadingLevelScale(),
- mActualScale + MIN_DOUBLE_TAP_SCALE_INCREMENT);
+ private void zoomToReadingLevel() {
+ final float readingScale = getReadingLevelScale();
int left = mWebView.nativeGetBlockLeftEdge(mAnchorX, mAnchorY, mActualScale);
if (left != WebView.NO_LEFTEDGE) {
@@ -721,13 +725,13 @@ class ZoomManager {
// Re-calculate the zoom center so that the new scroll x will be
// on the left edge.
if (viewLeft > 0) {
- mZoomCenterX = viewLeft * zoomScale / (zoomScale - mActualScale);
+ mZoomCenterX = viewLeft * readingScale / (readingScale - mActualScale);
} else {
mWebView.scrollBy(viewLeft, 0);
mZoomCenterX = 0;
}
}
- startZoomAnimation(zoomScale,
+ startZoomAnimation(readingScale,
!mWebView.getSettings().getUseFixedViewport());
}
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index 9d541e0..7d0f98e 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -774,6 +774,7 @@ public class NumberPicker extends LinearLayout {
mBeginEditOnUpEvent = false;
mAdjustScrollerOnUpEvent = true;
if (mSelectorWheelState == SELECTOR_WHEEL_STATE_LARGE) {
+ mSelectorWheelPaint.setAlpha(SELECTOR_WHEEL_BRIGHT_ALPHA);
boolean scrollersFinished = mFlingScroller.isFinished()
&& mAdjustScroller.isFinished();
if (!scrollersFinished) {
@@ -1608,23 +1609,11 @@ public class NumberPicker extends LinearLayout {
*/
private void fling(int velocityY) {
mPreviousScrollerY = 0;
- Scroller flingScroller = mFlingScroller;
- if (mWrapSelectorWheel) {
- if (velocityY > 0) {
- flingScroller.fling(0, 0, 0, velocityY, 0, 0, 0, Integer.MAX_VALUE);
- } else {
- flingScroller.fling(0, Integer.MAX_VALUE, 0, velocityY, 0, 0, 0, Integer.MAX_VALUE);
- }
+ if (velocityY > 0) {
+ mFlingScroller.fling(0, 0, 0, velocityY, 0, 0, 0, Integer.MAX_VALUE);
} else {
- if (velocityY > 0) {
- int maxY = mTextSize * (mValue - mMinValue);
- flingScroller.fling(0, 0, 0, velocityY, 0, 0, 0, maxY);
- } else {
- int startY = mTextSize * (mMaxValue - mValue);
- int maxY = startY;
- flingScroller.fling(0, startY, 0, velocityY, 0, 0, 0, maxY);
- }
+ mFlingScroller.fling(0, Integer.MAX_VALUE, 0, velocityY, 0, 0, 0, Integer.MAX_VALUE);
}
invalidate();
diff --git a/core/java/android/widget/SpellChecker.java b/core/java/android/widget/SpellChecker.java
index 4bd7165..31da5b5 100644
--- a/core/java/android/widget/SpellChecker.java
+++ b/core/java/android/widget/SpellChecker.java
@@ -19,6 +19,7 @@ package android.widget;
import android.content.Context;
import android.text.Editable;
import android.text.Selection;
+import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.method.WordIterator;
import android.text.style.SpellCheckSpan;
@@ -220,7 +221,6 @@ public class SpellChecker implements SpellCheckerSessionListener {
TextInfo[] textInfos = new TextInfo[mLength];
int textInfosCount = 0;
- final String text = editable.toString();
for (int i = 0; i < mLength; i++) {
final SpellCheckSpan spellCheckSpan = mSpellCheckSpans[i];
if (spellCheckSpan.isSpellCheckInProgress()) continue;
@@ -230,7 +230,9 @@ public class SpellChecker implements SpellCheckerSessionListener {
// Do not check this word if the user is currently editing it
if (start >= 0 && end > start && (selectionEnd < start || selectionStart > end)) {
- final String word = text.substring(start, end);
+ final String word = (editable instanceof SpannableStringBuilder) ?
+ ((SpannableStringBuilder) editable).substring(start, end) :
+ editable.subSequence(start, end).toString();
spellCheckSpan.setSpellCheckInProgress(true);
textInfos[textInfosCount++] = new TextInfo(word, mCookie, mIds[i]);
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index babd8e7..5b73a74 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -5517,7 +5517,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* call performClick(), but that won't do anything in
* this case.)
*/
- if (hasOnClickListeners()) {
+ if (!hasOnClickListeners()) {
if (mMovement != null && mText instanceof Editable
&& mLayout != null && onCheckIsTextEditor()) {
InputMethodManager imm = InputMethodManager.peekInstance();
@@ -5554,7 +5554,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* call performClick(), but that won't do anything in
* this case.)
*/
- if (hasOnClickListeners()) {
+ if (!hasOnClickListeners()) {
View v = focusSearch(FOCUS_DOWN);
if (v != null) {
@@ -9835,7 +9835,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
highlightTextDifferences(mSuggestionInfos[i], spanUnionStart, spanUnionEnd);
}
- // Add to dictionary item is there a span with the misspelled flag
+ // Add to dictionary item if there is a span with the misspelled flag
if (misspelledSpan != null) {
final int misspelledStart = spannable.getSpanStart(misspelledSpan);
final int misspelledEnd = spannable.getSpanEnd(misspelledSpan);
@@ -9921,7 +9921,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
final int spanStart = editable.getSpanStart(suggestionInfo.suggestionSpan);
final int spanEnd = editable.getSpanEnd(suggestionInfo.suggestionSpan);
- if (spanStart < 0 || spanEnd < 0) {
+ if (spanStart < 0 || spanEnd <= spanStart) {
// Span has been removed
hide();
return;
@@ -9989,14 +9989,14 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
// way to assign them a valid range after replacement
if (suggestionSpansStarts[i] <= spanStart &&
suggestionSpansEnds[i] >= spanEnd) {
- // TODO The ExtractEditText should restore these spans in the original text
- editable.setSpan(suggestionSpans[i], suggestionSpansStarts[i],
+ setSpan_internal(suggestionSpans[i], suggestionSpansStarts[i],
suggestionSpansEnds[i] + lengthDifference, suggestionSpansFlags[i]);
}
}
// Move cursor at the end of the replaced word
- Selection.setSelection(editable, spanEnd + lengthDifference);
+ final int newCursorPosition = spanEnd + lengthDifference;
+ setCursorPosition_internal(newCursorPosition, newCursorPosition);
}
hide();
@@ -11469,6 +11469,22 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
((Editable) mText).replace(start, end, text);
}
+ /**
+ * Sets a span on the specified range of text
+ * @hide
+ */
+ protected void setSpan_internal(Object span, int start, int end, int flags) {
+ ((Editable) mText).setSpan(span, start, end, flags);
+ }
+
+ /**
+ * Moves the cursor to the specified offset position in text
+ * @hide
+ */
+ protected void setCursorPosition_internal(int start, int end) {
+ Selection.setSelection(((Editable) mText), start, end);
+ }
+
@ViewDebug.ExportedProperty(category = "text")
private CharSequence mText;
private CharSequence mTransformed;