summaryrefslogtreecommitdiffstats
path: root/core/java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java')
-rwxr-xr-xcore/java/android/hardware/input/InputManager.java4
-rw-r--r--core/java/android/os/Build.java4
-rw-r--r--core/java/android/text/style/TextAppearanceSpan.java41
-rw-r--r--core/java/android/util/TimeUtils.java19
-rw-r--r--core/java/android/view/GLES20DisplayList.java3
-rw-r--r--core/java/android/view/TextureView.java12
-rw-r--r--core/java/android/view/VelocityTracker.java18
-rw-r--r--core/java/android/view/View.java101
-rw-r--r--core/java/android/webkit/HTML5VideoFullScreen.java18
-rw-r--r--core/java/android/webkit/HTML5VideoInline.java14
-rw-r--r--core/java/android/webkit/HTML5VideoView.java86
-rw-r--r--core/java/android/webkit/HTML5VideoViewProxy.java23
-rw-r--r--core/java/android/webkit/WebViewInputDispatcher.java2
-rw-r--r--core/java/android/widget/SpellChecker.java44
-rw-r--r--core/java/android/widget/TextView.java34
15 files changed, 326 insertions, 97 deletions
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index 5ba1850..6448b55 100755
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -96,14 +96,14 @@ public final class InputManager {
* <keyboard-layouts xmlns:android="http://schemas.android.com/apk/res/android">
* <keyboard-layout android:name="keyboard_layout_english_us"
* android:label="@string/keyboard_layout_english_us_label"
- * android:kcm="@raw/keyboard_layout_english_us" />
+ * android:keyboardLayout="@raw/keyboard_layout_english_us" />
* </keyboard-layouts>
* </p><p>
* The <code>android:name</code> attribute specifies an identifier by which
* the keyboard layout will be known in the package.
* The <code>android:label</code> attributes specifies a human-readable descriptive
* label to describe the keyboard layout in the user interface, such as "English (US)".
- * The <code>android:kcm</code> attribute refers to a
+ * The <code>android:keyboardLayout</code> attribute refers to a
* <a href="http://source.android.com/tech/input/key-character-map-files.html">
* key character map</a> resource that defines the keyboard layout.
* </p>
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 63275cf..2d5b625 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -370,7 +370,7 @@ public class Build {
public static final int ICE_CREAM_SANDWICH_MR1 = 15;
/**
- * Next up on Android!
+ * Android 4.1.
*
* <p>Applications targeting this or a later release will get these
* new changes in behavior:</p>
@@ -381,7 +381,7 @@ public class Build {
* exist in the application's manifest.
* </ul>
*/
- public static final int JELLY_BEAN = CUR_DEVELOPMENT;
+ public static final int JELLY_BEAN = 16;
}
/** The type of build, like "user" or "eng". */
diff --git a/core/java/android/text/style/TextAppearanceSpan.java b/core/java/android/text/style/TextAppearanceSpan.java
index 5fd7c57..ecbf4bc 100644
--- a/core/java/android/text/style/TextAppearanceSpan.java
+++ b/core/java/android/text/style/TextAppearanceSpan.java
@@ -68,24 +68,29 @@ public class TextAppearanceSpan extends MetricAffectingSpan implements Parcelabl
TextAppearance_textSize, -1);
mStyle = a.getInt(com.android.internal.R.styleable.TextAppearance_textStyle, 0);
- int tf = a.getInt(com.android.internal.R.styleable.TextAppearance_typeface, 0);
-
- switch (tf) {
- case 1:
- mTypeface = "sans";
- break;
-
- case 2:
- mTypeface = "serif";
- break;
-
- case 3:
- mTypeface = "monospace";
- break;
-
- default:
- mTypeface = null;
- break;
+ String family = a.getString(com.android.internal.R.styleable.TextAppearance_fontFamily);
+ if (family != null) {
+ mTypeface = family;
+ } else {
+ int tf = a.getInt(com.android.internal.R.styleable.TextAppearance_typeface, 0);
+
+ switch (tf) {
+ case 1:
+ mTypeface = "sans";
+ break;
+
+ case 2:
+ mTypeface = "serif";
+ break;
+
+ case 3:
+ mTypeface = "monospace";
+ break;
+
+ default:
+ mTypeface = null;
+ break;
+ }
}
a.recycle();
diff --git a/core/java/android/util/TimeUtils.java b/core/java/android/util/TimeUtils.java
index 2883eca..c4ebec4 100644
--- a/core/java/android/util/TimeUtils.java
+++ b/core/java/android/util/TimeUtils.java
@@ -26,6 +26,7 @@ import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Calendar;
import java.util.Collection;
import java.util.TimeZone;
import java.util.Date;
@@ -381,4 +382,22 @@ public class TimeUtils {
}
formatDuration(time-now, pw, 0);
}
+
+ /**
+ * Convert a System.currentTimeMillis() value to a time of day value like
+ * that printed in logs. MM-DD HH:MM:SS.MMM
+ *
+ * @param millis since the epoch (1/1/1970)
+ * @return String representation of the time.
+ * @hide
+ */
+ public static String logTimeOfDay(long millis) {
+ Calendar c = Calendar.getInstance();
+ if (millis >= 0) {
+ c.setTimeInMillis(millis);
+ return String.format("%tm-%td %tH:%tM:%tS.%tL", c, c, c, c, c, c);
+ } else {
+ return Long.toString(millis);
+ }
+ }
}
diff --git a/core/java/android/view/GLES20DisplayList.java b/core/java/android/view/GLES20DisplayList.java
index f3618eb..0154556 100644
--- a/core/java/android/view/GLES20DisplayList.java
+++ b/core/java/android/view/GLES20DisplayList.java
@@ -131,7 +131,8 @@ class GLES20DisplayList extends DisplayList {
@Override
public void setAnimationMatrix(Matrix matrix) {
try {
- nSetAnimationMatrix(getNativeDisplayList(), matrix.native_instance);
+ nSetAnimationMatrix(getNativeDisplayList(),
+ (matrix != null) ? matrix.native_instance : 0);
} catch (IllegalStateException e) {
// invalid DisplayList okay: we'll set current values the next time we render to it
}
diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java
index 651be2e..2048de2 100644
--- a/core/java/android/view/TextureView.java
+++ b/core/java/android/view/TextureView.java
@@ -561,7 +561,17 @@ public class TextureView extends View {
applyUpdate();
applyTransformMatrix();
- mLayer.copyInto(bitmap);
+ // This case can happen if the app invokes setSurfaceTexture() before
+ // we are able to create the hardware layer. We can safely initialize
+ // the layer here thanks to the validate() call at the beginning of
+ // this method
+ if (mLayer == null && mUpdateSurface) {
+ getHardwareLayer();
+ }
+
+ if (mLayer != null) {
+ mLayer.copyInto(bitmap);
+ }
}
return bitmap;
}
diff --git a/core/java/android/view/VelocityTracker.java b/core/java/android/view/VelocityTracker.java
index 1c35e31..f703e34 100644
--- a/core/java/android/view/VelocityTracker.java
+++ b/core/java/android/view/VelocityTracker.java
@@ -298,6 +298,24 @@ public final class VelocityTracker implements Poolable<VelocityTracker> {
return estimate(time, yCoeff);
}
+ /**
+ * Gets the X coefficient with the specified index.
+ * @param index The index of the coefficient to return.
+ * @return The X coefficient, or 0 if the index is greater than the degree.
+ */
+ public float getXCoeff(int index) {
+ return index <= degree ? xCoeff[index] : 0;
+ }
+
+ /**
+ * Gets the Y coefficient with the specified index.
+ * @param index The index of the coefficient to return.
+ * @return The Y coefficient, or 0 if the index is greater than the degree.
+ */
+ public float getYCoeff(int index) {
+ return index <= degree ? yCoeff[index] : 0;
+ }
+
private float estimate(float time, float[] c) {
float a = 0;
float scale = 1;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index bf7d037..55ea938 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -2128,6 +2128,20 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
*/
static final int ACCESSIBILITY_STATE_CHANGED = 0x00000080 << IMPORTANT_FOR_ACCESSIBILITY_SHIFT;
+ /**
+ * Flag indicating that view has an animation set on it. This is used to track whether an
+ * animation is cleared between successive frames, in order to tell the associated
+ * DisplayList to clear its animation matrix.
+ */
+ static final int VIEW_IS_ANIMATING_TRANSFORM = 0x10000000;
+
+ /**
+ * Flag indicating whether a view failed the quickReject() check in draw(). This condition
+ * is used to check whether later changes to the view's transform should invalidate the
+ * view to force the quickReject test to run again.
+ */
+ static final int VIEW_QUICK_REJECTED = 0x20000000;
+
/* End of masks for mPrivateFlags2 */
static final int DRAG_MASK = DRAG_CAN_ACCEPT | DRAG_HOVERED;
@@ -8560,6 +8574,10 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
if (mDisplayList != null) {
mDisplayList.setCameraDistance(-Math.abs(distance) / dpi);
}
+ if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) {
+ // View was rejected last time it was drawn by its parent; this may have changed
+ invalidateParentIfNeeded();
+ }
}
/**
@@ -8602,6 +8620,10 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
if (mDisplayList != null) {
mDisplayList.setRotation(rotation);
}
+ if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) {
+ // View was rejected last time it was drawn by its parent; this may have changed
+ invalidateParentIfNeeded();
+ }
}
}
@@ -8649,6 +8671,10 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
if (mDisplayList != null) {
mDisplayList.setRotationY(rotationY);
}
+ if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) {
+ // View was rejected last time it was drawn by its parent; this may have changed
+ invalidateParentIfNeeded();
+ }
}
}
@@ -8696,6 +8722,10 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
if (mDisplayList != null) {
mDisplayList.setRotationX(rotationX);
}
+ if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) {
+ // View was rejected last time it was drawn by its parent; this may have changed
+ invalidateParentIfNeeded();
+ }
}
}
@@ -8735,6 +8765,10 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
if (mDisplayList != null) {
mDisplayList.setScaleX(scaleX);
}
+ if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) {
+ // View was rejected last time it was drawn by its parent; this may have changed
+ invalidateParentIfNeeded();
+ }
}
}
@@ -8774,6 +8808,10 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
if (mDisplayList != null) {
mDisplayList.setScaleY(scaleY);
}
+ if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) {
+ // View was rejected last time it was drawn by its parent; this may have changed
+ invalidateParentIfNeeded();
+ }
}
}
@@ -8821,6 +8859,10 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
if (mDisplayList != null) {
mDisplayList.setPivotX(pivotX);
}
+ if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) {
+ // View was rejected last time it was drawn by its parent; this may have changed
+ invalidateParentIfNeeded();
+ }
}
}
@@ -8867,6 +8909,10 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
if (mDisplayList != null) {
mDisplayList.setPivotY(pivotY);
}
+ if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) {
+ // View was rejected last time it was drawn by its parent; this may have changed
+ invalidateParentIfNeeded();
+ }
}
}
@@ -9025,6 +9071,10 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
}
mBackgroundSizeChanged = true;
invalidateParentIfNeeded();
+ if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) {
+ // View was rejected last time it was drawn by its parent; this may have changed
+ invalidateParentIfNeeded();
+ }
}
}
@@ -9094,6 +9144,10 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
}
mBackgroundSizeChanged = true;
invalidateParentIfNeeded();
+ if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) {
+ // View was rejected last time it was drawn by its parent; this may have changed
+ invalidateParentIfNeeded();
+ }
}
}
@@ -9157,6 +9211,10 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
}
mBackgroundSizeChanged = true;
invalidateParentIfNeeded();
+ if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) {
+ // View was rejected last time it was drawn by its parent; this may have changed
+ invalidateParentIfNeeded();
+ }
}
}
@@ -9217,6 +9275,10 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
}
mBackgroundSizeChanged = true;
invalidateParentIfNeeded();
+ if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) {
+ // View was rejected last time it was drawn by its parent; this may have changed
+ invalidateParentIfNeeded();
+ }
}
}
@@ -9301,6 +9363,10 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
if (mDisplayList != null) {
mDisplayList.setTranslationX(translationX);
}
+ if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) {
+ // View was rejected last time it was drawn by its parent; this may have changed
+ invalidateParentIfNeeded();
+ }
}
}
@@ -9338,6 +9404,10 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
if (mDisplayList != null) {
mDisplayList.setTranslationY(translationY);
}
+ if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) {
+ // View was rejected last time it was drawn by its parent; this may have changed
+ invalidateParentIfNeeded();
+ }
}
}
@@ -12777,16 +12847,27 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
if (a != null) {
more = drawAnimation(parent, drawingTime, a, scalingRequired);
concatMatrix = a.willChangeTransformationMatrix();
+ if (concatMatrix) {
+ mPrivateFlags2 |= VIEW_IS_ANIMATING_TRANSFORM;
+ }
transformToApply = parent.mChildTransformation;
- } else if (!useDisplayListProperties &&
- (flags & ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) {
- final boolean hasTransform =
- parent.getChildStaticTransformation(this, parent.mChildTransformation);
- if (hasTransform) {
- final int transformType = parent.mChildTransformation.getTransformationType();
- transformToApply = transformType != Transformation.TYPE_IDENTITY ?
- parent.mChildTransformation : null;
- concatMatrix = (transformType & Transformation.TYPE_MATRIX) != 0;
+ } else {
+ if ((mPrivateFlags2 & VIEW_IS_ANIMATING_TRANSFORM) == VIEW_IS_ANIMATING_TRANSFORM &&
+ mDisplayList != null) {
+ // No longer animating: clear out old animation matrix
+ mDisplayList.setAnimationMatrix(null);
+ mPrivateFlags2 &= ~VIEW_IS_ANIMATING_TRANSFORM;
+ }
+ if (!useDisplayListProperties &&
+ (flags & ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) {
+ final boolean hasTransform =
+ parent.getChildStaticTransformation(this, parent.mChildTransformation);
+ if (hasTransform) {
+ final int transformType = parent.mChildTransformation.getTransformationType();
+ transformToApply = transformType != Transformation.TYPE_IDENTITY ?
+ parent.mChildTransformation : null;
+ concatMatrix = (transformType & Transformation.TYPE_MATRIX) != 0;
+ }
}
}
@@ -12798,8 +12879,10 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
if (!concatMatrix && canvas.quickReject(mLeft, mTop, mRight, mBottom, Canvas.EdgeType.BW) &&
(mPrivateFlags & DRAW_ANIMATION) == 0) {
+ mPrivateFlags2 |= VIEW_QUICK_REJECTED;
return more;
}
+ mPrivateFlags2 &= ~VIEW_QUICK_REJECTED;
if (hardwareAccelerated) {
// Clear INVALIDATED flag to allow invalidation to occur during rendering, but
diff --git a/core/java/android/webkit/HTML5VideoFullScreen.java b/core/java/android/webkit/HTML5VideoFullScreen.java
index 730ad08..62bc502 100644
--- a/core/java/android/webkit/HTML5VideoFullScreen.java
+++ b/core/java/android/webkit/HTML5VideoFullScreen.java
@@ -104,7 +104,9 @@ public class HTML5VideoFullScreen extends HTML5VideoView
// After we return from this we can't use the surface any more.
// The current Video View will be destroy when we play a new video.
pauseAndDispatch(mProxy);
+ // TODO: handle full screen->inline mode transition without a reload.
mPlayer.release();
+ mPlayer = null;
mSurfaceHolder = null;
if (mMediaController != null) {
mMediaController.hide();
@@ -128,12 +130,12 @@ public class HTML5VideoFullScreen extends HTML5VideoView
return mVideoSurfaceView;
}
- HTML5VideoFullScreen(Context context, int videoLayerId, int position) {
+ HTML5VideoFullScreen(Context context, int videoLayerId, int position, boolean skipPrepare) {
mVideoSurfaceView = new VideoSurfaceView(context);
mFullScreenMode = FULLSCREEN_OFF;
mVideoWidth = 0;
mVideoHeight = 0;
- init(videoLayerId, position);
+ init(videoLayerId, position, skipPrepare);
}
private void setMediaController(MediaController m) {
@@ -156,8 +158,6 @@ public class HTML5VideoFullScreen extends HTML5VideoView
}
private void prepareForFullScreen() {
- // So in full screen, we reset the MediaPlayer
- mPlayer.reset();
MediaController mc = new FullScreenMediaController(mProxy.getContext(), mLayout);
mc.setSystemUiVisibility(mLayout.getSystemUiVisibility());
setMediaController(mc);
@@ -198,6 +198,7 @@ public class HTML5VideoFullScreen extends HTML5VideoView
// after reading the MetaData
if (mMediaController != null) {
mMediaController.setEnabled(true);
+ mMediaController.show();
}
if (mProgressView != null) {
@@ -243,7 +244,7 @@ public class HTML5VideoFullScreen extends HTML5VideoView
// Don't show the controller after exiting the full screen.
mMediaController = null;
- mCurrentState = STATE_RELEASED;
+ mCurrentState = STATE_RESETTED;
}
};
@@ -320,6 +321,13 @@ public class HTML5VideoFullScreen extends HTML5VideoView
return 0;
}
+ @Override
+ public void showControllerInFullScreen() {
+ if (mMediaController != null) {
+ mMediaController.show(0);
+ }
+ }
+
// Other listeners functions:
private MediaPlayer.OnBufferingUpdateListener mBufferingUpdateListener =
new MediaPlayer.OnBufferingUpdateListener() {
diff --git a/core/java/android/webkit/HTML5VideoInline.java b/core/java/android/webkit/HTML5VideoInline.java
index 62e812e..2c7ea5d 100644
--- a/core/java/android/webkit/HTML5VideoInline.java
+++ b/core/java/android/webkit/HTML5VideoInline.java
@@ -21,7 +21,7 @@ public class HTML5VideoInline extends HTML5VideoView{
// associated with the surface texture can be used for showing the screen
// shot when paused, so they are not singleton.
private static SurfaceTexture mSurfaceTexture = null;
- private int[] mTextureNames;
+ private static int[] mTextureNames = null;
// Every time when the VideoLayer Id change, we need to recreate the
// SurfaceTexture in order to delete the old video's decoder memory.
private static int mVideoLayerUsingSurfaceTexture = -1;
@@ -35,8 +35,7 @@ public class HTML5VideoInline extends HTML5VideoView{
}
HTML5VideoInline(int videoLayerId, int position) {
- init(videoLayerId, position);
- mTextureNames = null;
+ init(videoLayerId, position, false);
}
@Override
@@ -69,15 +68,14 @@ public class HTML5VideoInline extends HTML5VideoView{
// Inline Video specific FUNCTIONS:
- @Override
- public SurfaceTexture getSurfaceTexture(int videoLayerId) {
+ public static SurfaceTexture getSurfaceTexture(int videoLayerId) {
// Create the surface texture.
if (videoLayerId != mVideoLayerUsingSurfaceTexture
|| mSurfaceTexture == null
|| mTextureNames == null) {
- if (mTextureNames != null) {
- GLES20.glDeleteTextures(1, mTextureNames, 0);
- }
+ // The GL texture will store in the VideoLayerManager at native side.
+ // They will be clean up when requested.
+ // The reason we recreated GL texture name is for screen shot support.
mTextureNames = new int[1];
GLES20.glGenTextures(1, mTextureNames, 0);
mSurfaceTexture = new SurfaceTexture(mTextureNames[0]);
diff --git a/core/java/android/webkit/HTML5VideoView.java b/core/java/android/webkit/HTML5VideoView.java
index 0d3b755..371feea 100644
--- a/core/java/android/webkit/HTML5VideoView.java
+++ b/core/java/android/webkit/HTML5VideoView.java
@@ -31,11 +31,10 @@ public class HTML5VideoView implements MediaPlayer.OnPreparedListener {
// NOTE: these values are in sync with VideoLayerAndroid.h in webkit side.
// Please keep them in sync when changed.
static final int STATE_INITIALIZED = 0;
- static final int STATE_NOTPREPARED = 1;
+ static final int STATE_PREPARING = 1;
static final int STATE_PREPARED = 2;
static final int STATE_PLAYING = 3;
- static final int STATE_RELEASED = 4;
- protected int mCurrentState;
+ static final int STATE_RESETTED = 4;
protected HTML5VideoViewProxy mProxy;
@@ -46,11 +45,11 @@ public class HTML5VideoView implements MediaPlayer.OnPreparedListener {
// This is used to find the VideoLayer on the native side.
protected int mVideoLayerId;
- // Every video will have one MediaPlayer. Given the fact we only have one
- // SurfaceTexture, there is only one MediaPlayer in action. Every time we
- // switch videos, a new instance of MediaPlayer will be created in reset().
- // Switching between inline and full screen will also create a new instance.
- protected MediaPlayer mPlayer;
+ // Given the fact we only have one SurfaceTexture, we cannot support multiple
+ // player at the same time. We may recreate a new one and abandon the old
+ // one at transition time.
+ protected static MediaPlayer mPlayer = null;
+ protected static int mCurrentState = -1;
// We need to save such info.
protected Uri mUri;
@@ -60,10 +59,12 @@ public class HTML5VideoView implements MediaPlayer.OnPreparedListener {
// See http://www.whatwg.org/specs/web-apps/current-work/#event-media-timeupdate
protected static Timer mTimer;
+ protected boolean mPauseDuringPreparing;
+
// The spec says the timer should fire every 250 ms or less.
private static final int TIMEUPDATE_PERIOD = 250; // ms
+ private boolean mSkipPrepare = false;
- protected boolean mPauseDuringPreparing;
// common Video control FUNCTIONS:
public void start() {
if (mCurrentState == STATE_PREPARED) {
@@ -83,7 +84,7 @@ public class HTML5VideoView implements MediaPlayer.OnPreparedListener {
public void pause() {
if (isPlaying()) {
mPlayer.pause();
- } else if (mCurrentState == STATE_NOTPREPARED) {
+ } else if (mCurrentState == STATE_PREPARING) {
mPauseDuringPreparing = true;
}
// Delete the Timer to stop it since there is no stop call.
@@ -124,11 +125,11 @@ public class HTML5VideoView implements MediaPlayer.OnPreparedListener {
}
}
- public void release() {
- if (mCurrentState != STATE_RELEASED) {
- mPlayer.release();
+ public void reset() {
+ if (mCurrentState != STATE_RESETTED) {
+ mPlayer.reset();
}
- mCurrentState = STATE_RELEASED;
+ mCurrentState = STATE_RESETTED;
}
public void stopPlayback() {
@@ -142,9 +143,16 @@ public class HTML5VideoView implements MediaPlayer.OnPreparedListener {
}
// Every time we start a new Video, we create a VideoView and a MediaPlayer
- public void init(int videoLayerId, int position) {
- mPlayer = new MediaPlayer();
- mCurrentState = STATE_INITIALIZED;
+ public void init(int videoLayerId, int position, boolean skipPrepare) {
+ if (mPlayer == null) {
+ mPlayer = new MediaPlayer();
+ mCurrentState = STATE_INITIALIZED;
+ }
+ mSkipPrepare = skipPrepare;
+ // If we want to skip the prepare, then we keep the state.
+ if (!mSkipPrepare) {
+ mCurrentState = STATE_INITIALIZED;
+ }
mProxy = null;
mVideoLayerId = videoLayerId;
mSaveSeekTime = position;
@@ -195,17 +203,28 @@ public class HTML5VideoView implements MediaPlayer.OnPreparedListener {
}
public void prepareDataCommon(HTML5VideoViewProxy proxy) {
- try {
- mPlayer.setDataSource(proxy.getContext(), mUri, mHeaders);
- mPlayer.prepareAsync();
- } catch (IllegalArgumentException e) {
- e.printStackTrace();
- } catch (IllegalStateException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
+ if (!mSkipPrepare) {
+ try {
+ mPlayer.reset();
+ mPlayer.setDataSource(proxy.getContext(), mUri, mHeaders);
+ mPlayer.prepareAsync();
+ } catch (IllegalArgumentException e) {
+ e.printStackTrace();
+ } catch (IllegalStateException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ mCurrentState = STATE_PREPARING;
+ } else {
+ // If we skip prepare and the onPrepared happened in inline mode, we
+ // don't need to call prepare again, we just need to call onPrepared
+ // to refresh the state here.
+ if (mCurrentState >= STATE_PREPARED) {
+ onPrepared(mPlayer);
+ }
+ mSkipPrepare = false;
}
- mCurrentState = STATE_NOTPREPARED;
}
public void reprepareData(HTML5VideoViewProxy proxy) {
@@ -294,10 +313,6 @@ public class HTML5VideoView implements MediaPlayer.OnPreparedListener {
return false;
}
- public SurfaceTexture getSurfaceTexture(int videoLayerId) {
- return null;
- }
-
public void deleteSurfaceTexture() {
}
@@ -332,14 +347,17 @@ public class HTML5VideoView implements MediaPlayer.OnPreparedListener {
return false;
}
- private boolean m_startWhenPrepared = false;
+ private boolean mStartWhenPrepared = false;
public void setStartWhenPrepared(boolean willPlay) {
- m_startWhenPrepared = willPlay;
+ mStartWhenPrepared = willPlay;
}
public boolean getStartWhenPrepared() {
- return m_startWhenPrepared;
+ return mStartWhenPrepared;
+ }
+
+ public void showControllerInFullScreen() {
}
}
diff --git a/core/java/android/webkit/HTML5VideoViewProxy.java b/core/java/android/webkit/HTML5VideoViewProxy.java
index 5fa4bad..90db308 100644
--- a/core/java/android/webkit/HTML5VideoViewProxy.java
+++ b/core/java/android/webkit/HTML5VideoViewProxy.java
@@ -112,13 +112,14 @@ class HTML5VideoViewProxy extends Handler
mBaseLayer = layer;
int currentVideoLayerId = mHTML5VideoView.getVideoLayerId();
- SurfaceTexture surfTexture = mHTML5VideoView.getSurfaceTexture(currentVideoLayerId);
+ SurfaceTexture surfTexture =
+ HTML5VideoInline.getSurfaceTexture(currentVideoLayerId);
int textureName = mHTML5VideoView.getTextureName();
if (layer != 0 && surfTexture != null && currentVideoLayerId != -1) {
int playerState = mHTML5VideoView.getCurrentState();
if (mHTML5VideoView.getPlayerBuffering())
- playerState = HTML5VideoView.STATE_NOTPREPARED;
+ playerState = HTML5VideoView.STATE_PREPARING;
boolean foundInTree = nativeSendSurfaceTexture(surfTexture,
layer, currentVideoLayerId, textureName,
playerState);
@@ -145,6 +146,7 @@ class HTML5VideoViewProxy extends Handler
HTML5VideoViewProxy proxy, WebViewClassic webView) {
// Save the inline video info and inherit it in the full screen
int savePosition = 0;
+ boolean canSkipPrepare = false;
if (mHTML5VideoView != null) {
// We don't allow enter full screen mode while the previous
// full screen video hasn't finished yet.
@@ -156,15 +158,20 @@ class HTML5VideoViewProxy extends Handler
// save the current position.
if (layerId == mHTML5VideoView.getVideoLayerId()) {
savePosition = mHTML5VideoView.getCurrentPosition();
+ int playerState = mHTML5VideoView.getCurrentState();
+ canSkipPrepare = (playerState == HTML5VideoView.STATE_PREPARING
+ || playerState == HTML5VideoView.STATE_PREPARED
+ || playerState == HTML5VideoView.STATE_PLAYING)
+ && !mHTML5VideoView.isFullScreenMode();
+ }
+ if (!canSkipPrepare) {
+ mHTML5VideoView.reset();
}
- mHTML5VideoView.release();
}
mHTML5VideoView = new HTML5VideoFullScreen(proxy.getContext(),
- layerId, savePosition);
+ layerId, savePosition, canSkipPrepare);
mCurrentProxy = proxy;
-
mHTML5VideoView.setVideoURI(url, mCurrentProxy);
-
mHTML5VideoView.enterFullScreenVideoState(layerId, proxy, webView);
}
@@ -217,8 +224,7 @@ class HTML5VideoViewProxy extends Handler
if (!backFromFullScreenMode) {
mHTML5VideoView.pauseAndDispatch(mCurrentProxy);
}
- // release the media player to avoid finalize error
- mHTML5VideoView.release();
+ mHTML5VideoView.reset();
}
mCurrentProxy = proxy;
mHTML5VideoView = new HTML5VideoInline(videoLayerId, time);
@@ -273,6 +279,7 @@ class HTML5VideoViewProxy extends Handler
}
public static void end() {
+ mHTML5VideoView.showControllerInFullScreen();
if (mCurrentProxy != null) {
if (isVideoSelfEnded)
mCurrentProxy.dispatchOnEnded();
diff --git a/core/java/android/webkit/WebViewInputDispatcher.java b/core/java/android/webkit/WebViewInputDispatcher.java
index 9541435..9328d8c 100644
--- a/core/java/android/webkit/WebViewInputDispatcher.java
+++ b/core/java/android/webkit/WebViewInputDispatcher.java
@@ -334,6 +334,7 @@ final class WebViewInputDispatcher {
DispatchEvent d = obtainDispatchEventLocked(eventToEnqueue, eventType, 0,
webKitXOffset, webKitYOffset, webKitScale);
+ updateStateTrackersLocked(d, event);
enqueueEventLocked(d);
}
return true;
@@ -787,7 +788,6 @@ final class WebViewInputDispatcher {
flags = d.mFlags;
- updateStateTrackersLocked(d, event);
if (event == d.mEvent) {
d.mEvent = null; // retain ownership of event, don't recycle it yet
}
diff --git a/core/java/android/widget/SpellChecker.java b/core/java/android/widget/SpellChecker.java
index ebf8a4a..7ca02e1 100644
--- a/core/java/android/widget/SpellChecker.java
+++ b/core/java/android/widget/SpellChecker.java
@@ -343,6 +343,36 @@ public class SpellChecker implements SpellCheckerSessionListener {
if (!isInDictionary && looksLikeTypo) {
createMisspelledSuggestionSpan(
editable, suggestionsInfo, spellCheckSpan, offset, length);
+ } else {
+ // Valid word -- isInDictionary || !looksLikeTypo
+ if (mIsSentenceSpellCheckSupported) {
+ // Allow the spell checker to remove existing misspelled span by
+ // overwriting the span over the same place
+ final int spellCheckSpanStart = editable.getSpanStart(spellCheckSpan);
+ final int spellCheckSpanEnd = editable.getSpanEnd(spellCheckSpan);
+ final int start;
+ final int end;
+ if (offset != USE_SPAN_RANGE && length != USE_SPAN_RANGE) {
+ start = spellCheckSpanStart + offset;
+ end = start + length;
+ } else {
+ start = spellCheckSpanStart;
+ end = spellCheckSpanEnd;
+ }
+ if (spellCheckSpanStart >= 0 && spellCheckSpanEnd > spellCheckSpanStart
+ && end > start) {
+ final Long key = Long.valueOf(TextUtils.packRangeInLong(start, end));
+ final SuggestionSpan tempSuggestionSpan = mSuggestionSpanCache.get(key);
+ if (tempSuggestionSpan != null) {
+ if (DBG) {
+ Log.i(TAG, "Remove existing misspelled span. "
+ + editable.subSequence(start, end));
+ }
+ editable.removeSpan(tempSuggestionSpan);
+ mSuggestionSpanCache.remove(key);
+ }
+ }
+ }
}
return spellCheckSpan;
}
@@ -473,8 +503,16 @@ public class SpellChecker implements SpellCheckerSessionListener {
private Object mRange = new Object();
public void parse(int start, int end) {
- if (end > start) {
- setRangeSpan((Editable) mTextView.getText(), start, end);
+ final int max = mTextView.length();
+ final int parseEnd;
+ if (end > max) {
+ Log.w(TAG, "Parse invalid region, from " + start + " to " + end);
+ parseEnd = max;
+ } else {
+ parseEnd = end;
+ }
+ if (parseEnd > start) {
+ setRangeSpan((Editable) mTextView.getText(), start, parseEnd);
parse();
}
}
@@ -612,6 +650,8 @@ public class SpellChecker implements SpellCheckerSessionListener {
break;
}
if (spellCheckEnd <= spellCheckStart) {
+ Log.w(TAG, "Trying to spellcheck invalid region, from "
+ + start + " to " + end);
break;
}
if (createSpellCheckSpan) {
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 555c974..098a034 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -154,6 +154,7 @@ import java.util.Locale;
* @attr ref android.R.styleable#TextView_textColorLink
* @attr ref android.R.styleable#TextView_textSize
* @attr ref android.R.styleable#TextView_textScaleX
+ * @attr ref android.R.styleable#TextView_fontFamily
* @attr ref android.R.styleable#TextView_typeface
* @attr ref android.R.styleable#TextView_textStyle
* @attr ref android.R.styleable#TextView_cursorVisible
@@ -464,6 +465,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
ColorStateList textColorHint = null;
ColorStateList textColorLink = null;
int textSize = 15;
+ String fontFamily = null;
int typefaceIndex = -1;
int styleIndex = -1;
boolean allCaps = false;
@@ -516,6 +518,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
typefaceIndex = appearance.getInt(attr, -1);
break;
+ case com.android.internal.R.styleable.TextAppearance_fontFamily:
+ fontFamily = appearance.getString(attr);
+ break;
+
case com.android.internal.R.styleable.TextAppearance_textStyle:
styleIndex = appearance.getInt(attr, -1);
break;
@@ -781,6 +787,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
styleIndex = a.getInt(attr, styleIndex);
break;
+ case com.android.internal.R.styleable.TextView_fontFamily:
+ fontFamily = a.getString(attr);
+ break;
+
case com.android.internal.R.styleable.TextView_password:
password = a.getBoolean(attr, password);
break;
@@ -1051,7 +1061,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
typefaceIndex = MONOSPACE;
}
- setTypefaceByIndex(typefaceIndex, styleIndex);
+ setTypefaceFromAttrs(fontFamily, typefaceIndex, styleIndex);
if (shadowcolor != 0) {
setShadowLayer(r, dx, dy, shadowcolor);
@@ -1111,8 +1121,15 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
}
- private void setTypefaceByIndex(int typefaceIndex, int styleIndex) {
+ private void setTypefaceFromAttrs(String familyName, int typefaceIndex, int styleIndex) {
Typeface tf = null;
+ if (familyName != null) {
+ tf = Typeface.create(familyName, styleIndex);
+ if (tf != null) {
+ setTypeface(tf);
+ return;
+ }
+ }
switch (typefaceIndex) {
case SANS:
tf = Typeface.SANS_SERIF;
@@ -2160,14 +2177,17 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
setLinkTextColor(colors);
}
+ String familyName;
int typefaceIndex, styleIndex;
+ familyName = appearance.getString(com.android.internal.R.styleable.
+ TextAppearance_fontFamily);
typefaceIndex = appearance.getInt(com.android.internal.R.styleable.
TextAppearance_typeface, -1);
styleIndex = appearance.getInt(com.android.internal.R.styleable.
TextAppearance_textStyle, -1);
- setTypefaceByIndex(typefaceIndex, styleIndex);
+ setTypefaceFromAttrs(familyName, typefaceIndex, styleIndex);
if (appearance.getBoolean(com.android.internal.R.styleable.TextAppearance_textAllCaps,
false)) {
@@ -2269,6 +2289,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*
* @see #getTypeface()
*
+ * @attr ref android.R.styleable#TextView_fontFamily
* @attr ref android.R.styleable#TextView_typeface
* @attr ref android.R.styleable#TextView_textStyle
*/
@@ -2290,6 +2311,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*
* @see #setTypeface(Typeface)
*
+ * @attr ref android.R.styleable#TextView_fontFamily
* @attr ref android.R.styleable#TextView_typeface
* @attr ref android.R.styleable#TextView_textStyle
*/
@@ -3690,15 +3712,15 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
boolean forceUpdate = false;
if (isPassword) {
setTransformationMethod(PasswordTransformationMethod.getInstance());
- setTypefaceByIndex(MONOSPACE, 0);
+ setTypefaceFromAttrs(null /* fontFamily */, MONOSPACE, 0);
} else if (isVisiblePassword) {
if (mTransformation == PasswordTransformationMethod.getInstance()) {
forceUpdate = true;
}
- setTypefaceByIndex(MONOSPACE, 0);
+ setTypefaceFromAttrs(null /* fontFamily */, MONOSPACE, 0);
} else if (wasPassword || wasVisiblePassword) {
// not in password mode, clean up typeface and transformation
- setTypefaceByIndex(-1, -1);
+ setTypefaceFromAttrs(null /* fontFamily */, -1, -1);
if (mTransformation == PasswordTransformationMethod.getInstance()) {
forceUpdate = true;
}