diff options
Diffstat (limited to 'core/java')
26 files changed, 413 insertions, 307 deletions
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java index 850fe48..044c0c2 100644 --- a/core/java/android/accessibilityservice/AccessibilityService.java +++ b/core/java/android/accessibilityservice/AccessibilityService.java @@ -371,7 +371,7 @@ public abstract class AccessibilityService extends Service { * * <strong>Note:</strong> To receive gestures an accessibility service must * request that the device is in touch exploration mode by setting the - * {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_INCLUDE_NOT_IMPORTANT_VIEWS} + * {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_REQUEST_TOUCH_EXPLORATION_MODE} * flag. * * @param gestureId The unique id of the performed gesture. @@ -565,10 +565,8 @@ public abstract class AccessibilityService extends Service { mCaller.sendMessage(message); } - public void onGesture(int gestureId, IAccessibilityServiceClientCallback callback, - int interactionId) { - Message message = mCaller.obtainMessageIIO(DO_ON_GESTURE, gestureId, interactionId, - callback); + public void onGesture(int gestureId) { + Message message = mCaller.obtainMessageI(DO_ON_GESTURE, gestureId); mCaller.sendMessage(message); } @@ -601,15 +599,7 @@ public abstract class AccessibilityService extends Service { return; case DO_ON_GESTURE : final int gestureId = message.arg1; - final int interactionId = message.arg2; - IAccessibilityServiceClientCallback callback = - (IAccessibilityServiceClientCallback) message.obj; - final boolean handled = mCallback.onGesture(gestureId); - try { - callback.setGestureResult(gestureId, handled, interactionId); - } catch (RemoteException re) { - Log.e(LOG_TAG, "Error calling back with the gesture resut.", re); - } + mCallback.onGesture(gestureId); return; default : Log.w(LOG_TAG, "Unknown message type " + message.what); diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl index 0257aa4..d459fd5 100644 --- a/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl +++ b/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl @@ -16,7 +16,6 @@ package android.accessibilityservice; -import android.accessibilityservice.IAccessibilityServiceClientCallback; import android.accessibilityservice.IAccessibilityServiceConnection; import android.view.accessibility.AccessibilityEvent; @@ -33,5 +32,5 @@ import android.view.accessibility.AccessibilityEvent; void onInterrupt(); - void onGesture(int gesture, in IAccessibilityServiceClientCallback callback, int interactionId); + void onGesture(int gesture); } diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceClientCallback.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceClientCallback.aidl deleted file mode 100644 index 9061398..0000000 --- a/core/java/android/accessibilityservice/IAccessibilityServiceClientCallback.aidl +++ /dev/null @@ -1,30 +0,0 @@ -/* -** Copyright 2012, 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.accessibilityservice; - -import android.accessibilityservice.IAccessibilityServiceConnection; -import android.view.accessibility.AccessibilityEvent; - -/** - * Callback for IAccessibilityServiceClient. - * - * @hide - */ - oneway interface IAccessibilityServiceClientCallback { - - void setGestureResult(int gestureId, boolean handled, int interactionId); -} diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index e2ebeba..5085b1e 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -275,7 +275,7 @@ public final class ActivityThread { } public String toString() { - ComponentName componentName = intent.getComponent(); + ComponentName componentName = intent != null ? intent.getComponent() : null; return "ActivityRecord{" + Integer.toHexString(System.identityHashCode(this)) + " token=" + token + " " + (componentName == null diff --git a/core/java/android/preference/VolumePreference.java b/core/java/android/preference/VolumePreference.java index fe5e76c..caf55d7 100644 --- a/core/java/android/preference/VolumePreference.java +++ b/core/java/android/preference/VolumePreference.java @@ -239,9 +239,7 @@ public class VolumePreference extends SeekBarDialogPreference implements public void onChange(boolean selfChange) { super.onChange(selfChange); if (mSeekBar != null && mAudioManager != null) { - int volume = mAudioManager.isStreamMute(mStreamType) ? - mAudioManager.getLastAudibleStreamVolume(mStreamType) - : mAudioManager.getStreamVolume(mStreamType); + int volume = mAudioManager.getStreamVolume(mStreamType); mSeekBar.setProgress(volume); } } diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index 9d36677..3e0942c 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -154,7 +154,6 @@ public abstract class WallpaperService extends Service { int mCurWindowPrivateFlags = mWindowPrivateFlags; final Rect mVisibleInsets = new Rect(); final Rect mWinFrame = new Rect(); - final Rect mSystemInsets = new Rect(); final Rect mContentInsets = new Rect(); final Configuration mConfiguration = new Configuration(); @@ -254,7 +253,7 @@ public abstract class WallpaperService extends Service { final BaseIWindow mWindow = new BaseIWindow() { @Override - public void resized(int w, int h, Rect systemInsets, Rect contentInsets, + public void resized(int w, int h, Rect contentInsets, Rect visibleInsets, boolean reportDraw, Configuration newConfig) { Message msg = mCaller.obtainMessageI(MSG_WINDOW_RESIZED, reportDraw ? 1 : 0); @@ -621,7 +620,7 @@ public abstract class WallpaperService extends Service { final int relayoutResult = mSession.relayout( mWindow, mWindow.mSeq, mLayout, mWidth, mHeight, - View.VISIBLE, 0, mWinFrame, mSystemInsets, mContentInsets, + View.VISIBLE, 0, mWinFrame, mContentInsets, mVisibleInsets, mConfiguration, mSurfaceHolder.mSurface); if (DEBUG) Log.v(TAG, "New surface: " + mSurfaceHolder.mSurface diff --git a/core/java/android/view/IWindow.aidl b/core/java/android/view/IWindow.aidl index 555f306..b4caad3 100644 --- a/core/java/android/view/IWindow.aidl +++ b/core/java/android/view/IWindow.aidl @@ -45,7 +45,7 @@ oneway interface IWindow { */ void executeCommand(String command, String parameters, in ParcelFileDescriptor descriptor); - void resized(int w, int h, in Rect systemInsets, in Rect contentInsets, + void resized(int w, int h, in Rect contentInsets, in Rect visibleInsets, boolean reportDraw, in Configuration newConfig); void dispatchAppVisibility(boolean visible); void dispatchGetNewSurface(); diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl index f26d5e1..d4a03ce 100644 --- a/core/java/android/view/IWindowSession.aidl +++ b/core/java/android/view/IWindowSession.aidl @@ -58,10 +58,6 @@ interface IWindowSession { * {@link WindowManagerImpl#RELAYOUT_DEFER_SURFACE_DESTROY}. * @param outFrame Rect in which is placed the new position/size on * screen. - * @param outSystemInsets Rect in which is placed the offsets from - * <var>outFrame</var> over which any core system UI elements are - * currently covering the window. This is not generally used for - * layout, but just to know where the window is obscured. * @param outContentInsets Rect in which is placed the offsets from * <var>outFrame</var> in which the content of the window should be * placed. This can be used to modify the window layout to ensure its @@ -83,7 +79,7 @@ interface IWindowSession { */ int relayout(IWindow window, int seq, in WindowManager.LayoutParams attrs, int requestedWidth, int requestedHeight, int viewVisibility, - int flags, out Rect outFrame, out Rect outSystemInsets, + int flags, out Rect outFrame, out Rect outContentInsets, out Rect outVisibleInsets, out Configuration outConfig, out Surface outSurface); diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index ee322f8..fd302dc 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -98,7 +98,6 @@ public class SurfaceView extends View { MyWindow mWindow; final Rect mVisibleInsets = new Rect(); final Rect mWinFrame = new Rect(); - final Rect mSystemInsets = new Rect(); final Rect mContentInsets = new Rect(); final Configuration mConfiguration = new Configuration(); @@ -231,7 +230,17 @@ public class SurfaceView extends View { public void setVisibility(int visibility) { super.setVisibility(visibility); mViewVisibility = visibility == VISIBLE; - mRequestedVisible = mWindowVisibility && mViewVisibility; + boolean newRequestedVisible = mWindowVisibility && mViewVisibility; + if (newRequestedVisible != mRequestedVisible) { + // our base class (View) invalidates the layout only when + // we go from/to the GONE state. However, SurfaceView needs + // to request a re-layout when the visibility changes at all. + // This is needed because the transparent region is computed + // as part of the layout phase, and it changes (obviously) when + // the visibility changes. + requestLayout(); + } + mRequestedVisible = newRequestedVisible; updateWindow(false, false); } @@ -472,7 +481,7 @@ public class SurfaceView extends View { mWindow, mWindow.mSeq, mLayout, mWidth, mHeight, visible ? VISIBLE : GONE, WindowManagerImpl.RELAYOUT_DEFER_SURFACE_DESTROY, - mWinFrame, mSystemInsets, mContentInsets, + mWinFrame, mContentInsets, mVisibleInsets, mConfiguration, mNewSurface); if ((relayoutResult&WindowManagerImpl.RELAYOUT_RES_FIRST_TIME) != 0) { mReportDrawNeeded = true; @@ -606,7 +615,7 @@ public class SurfaceView extends View { mSurfaceView = new WeakReference<SurfaceView>(surfaceView); } - public void resized(int w, int h, Rect systemInsets, Rect contentInsets, + public void resized(int w, int h, Rect contentInsets, Rect visibleInsets, boolean reportDraw, Configuration newConfig) { SurfaceView surfaceView = mSurfaceView.get(); if (surfaceView != null) { diff --git a/core/java/android/view/VelocityTracker.java b/core/java/android/view/VelocityTracker.java index f703e34..f5870e1 100644 --- a/core/java/android/view/VelocityTracker.java +++ b/core/java/android/view/VelocityTracker.java @@ -60,8 +60,7 @@ public final class VelocityTracker implements Poolable<VelocityTracker> { private static native void nativeComputeCurrentVelocity(int ptr, int units, float maxVelocity); private static native float nativeGetXVelocity(int ptr, int id); private static native float nativeGetYVelocity(int ptr, int id); - private static native boolean nativeGetEstimator(int ptr, int id, - int degree, int horizonMillis, Estimator outEstimator); + private static native boolean nativeGetEstimator(int ptr, int id, Estimator outEstimator); /** * Retrieve a new VelocityTracker object to watch the velocity of a @@ -227,21 +226,17 @@ public final class VelocityTracker implements Poolable<VelocityTracker> { * this method. * * @param id Which pointer's velocity to return. - * @param degree The desired polynomial degree. The actual estimator may have - * a lower degree than what is requested here. If -1, uses the default degree. - * @param horizonMillis The maximum age of the oldest sample to consider, in milliseconds. - * If -1, uses the default horizon. * @param outEstimator The estimator to populate. * @return True if an estimator was obtained, false if there is no information * available about the pointer. * * @hide For internal use only. Not a final API. */ - public boolean getEstimator(int id, int degree, int horizonMillis, Estimator outEstimator) { + public boolean getEstimator(int id, Estimator outEstimator) { if (outEstimator == null) { throw new IllegalArgumentException("outEstimator must not be null"); } - return nativeGetEstimator(mPtr, id, degree, horizonMillis, outEstimator); + return nativeGetEstimator(mPtr, id, outEstimator); } /** diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 42fd63f..14523d3 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -4737,11 +4737,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal getBoundsOnScreen(bounds); info.setBoundsInScreen(bounds); - if ((mPrivateFlags & IS_ROOT_NAMESPACE) == 0) { - ViewParent parent = getParentForAccessibility(); - if (parent instanceof View) { - info.setParent((View) parent); - } + ViewParent parent = getParentForAccessibility(); + if (parent instanceof View) { + info.setParent((View) parent); } info.setVisibleToUser(isVisibleToUser()); @@ -6519,6 +6517,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal * that is interesting for accessilility purposes. */ public void notifyAccessibilityStateChanged() { + if (!AccessibilityManager.getInstance(mContext).isEnabled()) { + return; + } if ((mPrivateFlags2 & ACCESSIBILITY_STATE_CHANGED) == 0) { mPrivateFlags2 |= ACCESSIBILITY_STATE_CHANGED; if (mParent != null) { @@ -15282,10 +15283,12 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal /** * Sets the next animation to play for this view. * If you want the animation to play immediately, use - * startAnimation. This method provides allows fine-grained + * {@link #startAnimation(android.view.animation.Animation)} instead. + * This method provides allows fine-grained * control over the start time and invalidation, but you * must make sure that 1) the animation has a start time set, and - * 2) the view will be invalidated when the animation is supposed to + * 2) the view's parent (which controls animations on its children) + * will be invalidated when the animation is supposed to * start. * * @param animation The next animation, or null. @@ -17163,12 +17166,6 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal boolean mUse32BitDrawingCache; /** - * Describes the parts of the window that are currently completely - * obscured by system UI elements. - */ - final Rect mSystemInsets = new Rect(); - - /** * For windows that are full-screen but using insets to layout inside * of the screen decorations, these are the current insets for the * content of the window. diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index a4c0258..b95ca5e 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -1633,8 +1633,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager final int childrenCount = children.getChildCount(); for (int i = 0; i < childrenCount; i++) { View child = children.getChildAt(i); - if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE - && (child.mPrivateFlags & IS_ROOT_NAMESPACE) == 0) { + if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE) { if (child.includeForAccessibility()) { childrenForAccessibility.add(child); } else { diff --git a/core/java/android/view/ViewPropertyAnimator.java b/core/java/android/view/ViewPropertyAnimator.java index 2012db2..ce6f4c5 100644 --- a/core/java/android/view/ViewPropertyAnimator.java +++ b/core/java/android/view/ViewPropertyAnimator.java @@ -342,6 +342,7 @@ public class ViewPropertyAnimator { * otherwise), then this method can be used. */ public void start() { + mView.removeCallbacks(mAnimationStarter); startAnimation(); } diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 0eee17d..f86e036 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -262,7 +262,6 @@ public final class ViewRootImpl implements ViewParent, final Rect mPendingVisibleInsets = new Rect(); final Rect mPendingContentInsets = new Rect(); - final Rect mPendingSystemInsets = new Rect(); final ViewTreeObserver.InternalInsetsInfo mLastGivenInsets = new ViewTreeObserver.InternalInsetsInfo(); @@ -272,7 +271,6 @@ public final class ViewRootImpl implements ViewParent, final Configuration mPendingConfiguration = new Configuration(); class ResizedInfo { - Rect systemInsets; Rect contentInsets; Rect visibleInsets; Configuration newConfig; @@ -568,7 +566,6 @@ public final class ViewRootImpl implements ViewParent, if (mTranslator != null) { mTranslator.translateRectInScreenToAppWindow(mAttachInfo.mContentInsets); } - mPendingSystemInsets.set(0, 0, 0, 0); mPendingContentInsets.set(mAttachInfo.mContentInsets); mPendingVisibleInsets.set(0, 0, 0, 0); if (DEBUG_LAYOUT) Log.v(TAG, "Added window " + mWindow); @@ -1235,7 +1232,6 @@ public final class ViewRootImpl implements ViewParent, getRunQueue().executeActions(attachInfo.mHandler); boolean insetsChanged = false; - boolean activeRectChanged = false; boolean layoutRequested = mLayoutRequested && !mStopped; if (layoutRequested) { @@ -1247,12 +1243,7 @@ public final class ViewRootImpl implements ViewParent, // to opposite of the added touch mode. mAttachInfo.mInTouchMode = !mAddedTouchMode; ensureTouchModeLocally(mAddedTouchMode); - activeRectChanged = true; } else { - if (!mPendingSystemInsets.equals(mAttachInfo.mSystemInsets)) { - mAttachInfo.mSystemInsets.set(mPendingSystemInsets); - activeRectChanged = true; - } if (!mPendingContentInsets.equals(mAttachInfo.mContentInsets)) { insetsChanged = true; } @@ -1406,10 +1397,6 @@ public final class ViewRootImpl implements ViewParent, mPendingConfiguration.seq = 0; } - if (!mPendingSystemInsets.equals(mAttachInfo.mSystemInsets)) { - activeRectChanged = true; - mAttachInfo.mSystemInsets.set(mPendingSystemInsets); - } contentInsetsChanged = !mPendingContentInsets.equals( mAttachInfo.mContentInsets); visibleInsetsChanged = !mPendingVisibleInsets.equals( @@ -1512,7 +1499,6 @@ public final class ViewRootImpl implements ViewParent, // before actually drawing them, so it can display then // all at once. newSurface = true; - activeRectChanged = true; mFullRedrawNeeded = true; mPreviousTransparentRegion.setEmpty(); @@ -1578,7 +1564,6 @@ public final class ViewRootImpl implements ViewParent, // window size we asked for. We should avoid this by getting a maximum size from // the window session beforehand. if (mWidth != frame.width() || mHeight != frame.height()) { - activeRectChanged = true; mWidth = frame.width(); mHeight = frame.height(); } @@ -2836,7 +2821,6 @@ public final class ViewRootImpl implements ViewParent, ResizedInfo ri = (ResizedInfo)msg.obj; if (mWinFrame.width() == msg.arg1 && mWinFrame.height() == msg.arg2 - && mPendingSystemInsets.equals(ri.systemInsets) && mPendingContentInsets.equals(ri.contentInsets) && mPendingVisibleInsets.equals(ri.visibleInsets) && ((ResizedInfo)msg.obj).newConfig == null) { @@ -2853,7 +2837,6 @@ public final class ViewRootImpl implements ViewParent, mWinFrame.right = msg.arg1; mWinFrame.top = 0; mWinFrame.bottom = msg.arg2; - mPendingSystemInsets.set(((ResizedInfo)msg.obj).systemInsets); mPendingContentInsets.set(((ResizedInfo)msg.obj).contentInsets); mPendingVisibleInsets.set(((ResizedInfo)msg.obj).visibleInsets); if (msg.what == MSG_RESIZED_REPORT) { @@ -3888,7 +3871,7 @@ public final class ViewRootImpl implements ViewParent, (int) (mView.getMeasuredWidth() * appScale + 0.5f), (int) (mView.getMeasuredHeight() * appScale + 0.5f), viewVisibility, insetsPending ? WindowManagerImpl.RELAYOUT_INSETS_PENDING : 0, - mWinFrame, mPendingSystemInsets, mPendingContentInsets, mPendingVisibleInsets, + mWinFrame, mPendingContentInsets, mPendingVisibleInsets, mPendingConfiguration, mSurface); //Log.d(TAG, "<<<<<< BACK FROM relayout"); if (restore) { @@ -4084,11 +4067,10 @@ public final class ViewRootImpl implements ViewParent, mHandler.sendMessage(msg); } - public void dispatchResized(int w, int h, Rect systemInsets, Rect contentInsets, + public void dispatchResized(int w, int h, Rect contentInsets, Rect visibleInsets, boolean reportDraw, Configuration newConfig) { if (DEBUG_LAYOUT) Log.v(TAG, "Resizing " + this + ": w=" + w - + " h=" + h + " systemInsets=" + systemInsets.toShortString() - + " contentInsets=" + contentInsets.toShortString() + + " h=" + h + " contentInsets=" + contentInsets.toShortString() + " visibleInsets=" + visibleInsets.toShortString() + " reportDraw=" + reportDraw); Message msg = mHandler.obtainMessage(reportDraw ? MSG_RESIZED_REPORT :MSG_RESIZED); @@ -4101,7 +4083,6 @@ public final class ViewRootImpl implements ViewParent, msg.arg1 = w; msg.arg2 = h; ResizedInfo ri = new ResizedInfo(); - ri.systemInsets = new Rect(systemInsets); ri.contentInsets = new Rect(contentInsets); ri.visibleInsets = new Rect(visibleInsets); ri.newConfig = newConfig; @@ -4757,11 +4738,11 @@ public final class ViewRootImpl implements ViewParent, mViewAncestor = new WeakReference<ViewRootImpl>(viewAncestor); } - public void resized(int w, int h, Rect systemInsets, Rect contentInsets, + public void resized(int w, int h, Rect contentInsets, Rect visibleInsets, boolean reportDraw, Configuration newConfig) { final ViewRootImpl viewAncestor = mViewAncestor.get(); if (viewAncestor != null) { - viewAncestor.dispatchResized(w, h, systemInsets, contentInsets, + viewAncestor.dispatchResized(w, h, contentInsets, visibleInsets, reportDraw, newConfig); } } diff --git a/core/java/android/view/VolumePanel.java b/core/java/android/view/VolumePanel.java index 110c239..78984e0 100644 --- a/core/java/android/view/VolumePanel.java +++ b/core/java/android/view/VolumePanel.java @@ -296,41 +296,33 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie private boolean isMuted(int streamType) { if (streamType == STREAM_MASTER) { - return mAudioService.isMasterMute(); + return mAudioManager.isMasterMute(); } else { - return mAudioService.isStreamMute(streamType); + return mAudioManager.isStreamMute(streamType); } } private int getStreamMaxVolume(int streamType) { if (streamType == STREAM_MASTER) { - return mAudioService.getMasterMaxVolume(); + return mAudioManager.getMasterMaxVolume(); } else { - return mAudioService.getStreamMaxVolume(streamType); + return mAudioManager.getStreamMaxVolume(streamType); } } private int getStreamVolume(int streamType) { if (streamType == STREAM_MASTER) { - return mAudioService.getMasterVolume(); + return mAudioManager.getMasterVolume(); } else { - return mAudioService.getStreamVolume(streamType); + return mAudioManager.getStreamVolume(streamType); } } private void setStreamVolume(int streamType, int index, int flags) { if (streamType == STREAM_MASTER) { - mAudioService.setMasterVolume(index, flags); + mAudioManager.setMasterVolume(index, flags); } else { - mAudioService.setStreamVolume(streamType, index, flags); - } - } - - private int getLastAudibleStreamVolume(int streamType) { - if (streamType == STREAM_MASTER) { - return mAudioService.getLastAudibleMasterVolume(); - } else { - return mAudioService.getLastAudibleStreamVolume(streamType); + mAudioManager.setStreamVolume(streamType, index, flags); } } @@ -399,13 +391,18 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie /** Update the mute and progress state of a slider */ private void updateSlider(StreamControl sc) { - sc.seekbarView.setProgress(getLastAudibleStreamVolume(sc.streamType)); + sc.seekbarView.setProgress(getStreamVolume(sc.streamType)); final boolean muted = isMuted(sc.streamType); sc.icon.setImageResource(muted ? sc.iconMuteRes : sc.iconRes); - if (sc.streamType == AudioManager.STREAM_RING && muted - && mAudioManager.shouldVibrate(AudioManager.VIBRATE_TYPE_RINGER)) { + if (sc.streamType == AudioManager.STREAM_RING && + mAudioManager.getRingerMode() == AudioManager.RINGER_MODE_VIBRATE) { sc.icon.setImageResource(R.drawable.ic_audio_ring_notif_vibrate); } + if (sc.streamType != mAudioManager.getMasterStreamType() && muted) { + sc.seekbarView.setEnabled(false); + } else { + sc.seekbarView.setEnabled(true); + } } private boolean isExpanded() { @@ -510,9 +507,7 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie } protected void onShowVolumeChanged(int streamType, int flags) { - int index = isMuted(streamType) ? - getLastAudibleStreamVolume(streamType) - : getStreamVolume(streamType); + int index = getStreamVolume(streamType); mRingIsSilent = false; @@ -592,6 +587,11 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie sc.seekbarView.setMax(max); } sc.seekbarView.setProgress(index); + if (streamType != mAudioManager.getMasterStreamType() && isMuted(streamType)) { + sc.seekbarView.setEnabled(false); + } else { + sc.seekbarView.setEnabled(true); + } } if (!mDialog.isShowing()) { @@ -607,8 +607,7 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie // Do a little vibrate if applicable (only when going into vibrate mode) if ((flags & AudioManager.FLAG_VIBRATE) != 0 && mAudioService.isStreamAffectedByRingerMode(streamType) && - mAudioService.getRingerMode() == AudioManager.RINGER_MODE_VIBRATE && - mAudioService.shouldVibrate(AudioManager.VIBRATE_TYPE_RINGER)) { + mAudioManager.getRingerMode() == AudioManager.RINGER_MODE_VIBRATE) { sendMessageDelayed(obtainMessage(MSG_VIBRATE), VIBRATE_DELAY); } } @@ -646,7 +645,7 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie protected void onVibrate() { // Make sure we ended up in vibrate ringer mode - if (mAudioService.getRingerMode() != AudioManager.RINGER_MODE_VIBRATE) { + if (mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_VIBRATE) { return; } diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java index bc38368..0c5d6ea 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java @@ -145,10 +145,6 @@ public interface WindowManagerPolicy { * @param displayFrame The frame of the overall display in which this * window can appear, used for constraining the overall dimensions * of the window. - * @param systemFrame The frame within the display that any system - * elements are currently covering. These indicate which parts of - * the window should be considered completely obscured by the screen - * decorations. * @param contentFrame The frame within the display in which we would * like active content to appear. This will cause windows behind to * be resized to match the given content frame. @@ -160,7 +156,7 @@ public interface WindowManagerPolicy { * are visible. */ public void computeFrameLw(Rect parentFrame, Rect displayFrame, - Rect systemFrame, Rect contentFrame, Rect visibleFrame); + Rect contentFrame, Rect visibleFrame); /** * Retrieve the current frame of the window that has been assigned by @@ -188,14 +184,6 @@ public interface WindowManagerPolicy { public Rect getDisplayFrameLw(); /** - * Retrieve the frame of the system elements that last covered the window. - * Must be called with the window manager lock held. - * - * @return Rect The rectangle holding the system frame. - */ - public Rect getSystemFrameLw(); - - /** * Retrieve the frame of the content area that this window was last * laid out in. This is the area in which the content of the window * should be placed. It will be smaller than the display frame to @@ -773,6 +761,21 @@ public interface WindowManagerPolicy { public void beginLayoutLw(int displayWidth, int displayHeight, int displayRotation); /** + * Return the rectangle of the screen currently covered by system decorations. + * This will be called immediately after {@link #layoutWindowLw}. It can + * fill in the rectangle to indicate any part of the screen that it knows + * for sure is covered by system decor such as the status bar. The rectangle + * is initially set to the actual size of the screen, indicating nothing is + * covered. + * + * @param systemRect The rectangle of the screen that is not covered by + * system decoration. + * @return Returns the layer above which the system rectangle should + * not be applied. + */ + public int getSystemDecorRectLw(Rect systemRect); + + /** * Called for each window attached to the window manager as layout is * proceeding. The implementation of this function must take care of * setting the window's frame, either here or in finishLayout(). @@ -797,7 +800,7 @@ public interface WindowManagerPolicy { * */ public void getContentInsetHintLw(WindowManager.LayoutParams attrs, Rect contentInset); - + /** * Called when layout of the windows is finished. After this function has * returned, all windows given to layoutWindow() <em>must</em> have had a diff --git a/core/java/android/view/accessibility/AccessibilityInteractionClient.java b/core/java/android/view/accessibility/AccessibilityInteractionClient.java index 24e90fd..bd341d0 100644 --- a/core/java/android/view/accessibility/AccessibilityInteractionClient.java +++ b/core/java/android/view/accessibility/AccessibilityInteractionClient.java @@ -441,10 +441,6 @@ public final class AccessibilityInteractionClient sAccessibilityNodeInfoCache.clear(); } - public void removeCachedNode(long accessibilityNodeId) { - sAccessibilityNodeInfoCache.remove(accessibilityNodeId); - } - public void onAccessibilityEvent(AccessibilityEvent event) { sAccessibilityNodeInfoCache.onAccessibilityEvent(event); } @@ -630,7 +626,7 @@ public final class AccessibilityInteractionClient applyCompatibilityScaleIfNeeded(info, windowScale); info.setConnectionId(connectionId); info.setSealed(true); - sAccessibilityNodeInfoCache.put(info.getSourceNodeId(), info); + sAccessibilityNodeInfoCache.add(info); } } diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java b/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java index d2609bb..52b7772 100644 --- a/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java +++ b/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java @@ -16,10 +16,15 @@ package android.view.accessibility; +import android.os.Build; import android.util.Log; import android.util.LongSparseArray; import android.util.SparseLongArray; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.Queue; + /** * Simple cache for AccessibilityNodeInfos. The cache is mapping an * accessibility id to an info. The cache allows storing of @@ -36,10 +41,14 @@ public class AccessibilityNodeInfoCache { private static final boolean DEBUG = false; + private static final boolean CHECK_INTEGRITY = true; + private final Object mLock = new Object(); private final LongSparseArray<AccessibilityNodeInfo> mCacheImpl; + private int mWindowId; + public AccessibilityNodeInfoCache() { if (ENABLED) { mCacheImpl = new LongSparseArray<AccessibilityNodeInfo>(); @@ -59,21 +68,49 @@ public class AccessibilityNodeInfoCache { final int eventType = event.getEventType(); switch (eventType) { case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED: { + // New window so we clear the cache. + mWindowId = event.getWindowId(); clear(); } break; + case AccessibilityEvent.TYPE_VIEW_HOVER_ENTER: + case AccessibilityEvent.TYPE_VIEW_HOVER_EXIT: { + final int windowId = event.getWindowId(); + if (mWindowId != windowId) { + // New window so we clear the cache. + mWindowId = windowId; + clear(); + } + } break; case AccessibilityEvent.TYPE_VIEW_FOCUSED: + case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED: case AccessibilityEvent.TYPE_VIEW_SELECTED: case AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED: case AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED: { - final long accessibilityNodeId = event.getSourceNodeId(); - remove(accessibilityNodeId); + // Since we prefetch the descendants of a node we + // just remove the entire subtree since when the node + // is fetched we will gets its descendant anyway. + synchronized (mLock) { + final long sourceId = event.getSourceNodeId(); + clearSubTreeLocked(sourceId); + if (eventType == AccessibilityEvent.TYPE_VIEW_FOCUSED) { + clearSubtreeWithOldInputFocusLocked(sourceId); + } + if (eventType == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED) { + clearSubtreeWithOldAccessibilityFocusLocked(sourceId); + } + } } break; case AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED: case AccessibilityEvent.TYPE_VIEW_SCROLLED: { - final long accessibilityNodeId = event.getSourceNodeId(); - clearSubTree(accessibilityNodeId); + synchronized (mLock) { + final long accessibilityNodeId = event.getSourceNodeId(); + clearSubTreeLocked(accessibilityNodeId); + } } break; } + if (Build.IS_DEBUGGABLE && CHECK_INTEGRITY) { + checkIntegrity(); + } } } @@ -105,51 +142,45 @@ public class AccessibilityNodeInfoCache { /** * Caches an {@link AccessibilityNodeInfo} given its accessibility node id. * - * @param accessibilityNodeId The info accessibility node id. * @param info The {@link AccessibilityNodeInfo} to cache. */ - public void put(long accessibilityNodeId, AccessibilityNodeInfo info) { + public void add(AccessibilityNodeInfo info) { if (ENABLED) { synchronized(mLock) { if (DEBUG) { - Log.i(LOG_TAG, "put(" + accessibilityNodeId + ", " + info + ")"); + Log.i(LOG_TAG, "add(" + info + ")"); } - // Cache a copy since the client calls to AccessibilityNodeInfo#recycle() - // will wipe the data of the cached info. - AccessibilityNodeInfo clone = AccessibilityNodeInfo.obtain(info); - mCacheImpl.put(accessibilityNodeId, clone); - } - } - } - /** - * Returns whether the cache contains an accessibility node id key. - * - * @param accessibilityNodeId The key for which to check. - * @return True if the key is in the cache. - */ - public boolean containsKey(long accessibilityNodeId) { - if (ENABLED) { - synchronized(mLock) { - return (mCacheImpl.indexOfKey(accessibilityNodeId) >= 0); - } - } else { - return false; - } - } + final long sourceId = info.getSourceNodeId(); + AccessibilityNodeInfo oldInfo = mCacheImpl.get(sourceId); + if (oldInfo != null) { + // If the added node is in the cache we have to be careful if + // the new one represents a source state where some of the + // children have been removed to avoid having disconnected + // subtrees in the cache. + SparseLongArray oldChildrenIds = oldInfo.getChildNodeIds(); + SparseLongArray newChildrenIds = info.getChildNodeIds(); + final int oldChildCount = oldChildrenIds.size(); + for (int i = 0; i < oldChildCount; i++) { + final long oldChildId = oldChildrenIds.valueAt(i); + if (newChildrenIds.indexOfValue(oldChildId) < 0) { + clearSubTreeLocked(oldChildId); + } + } - /** - * Removes a cached {@link AccessibilityNodeInfo}. - * - * @param accessibilityNodeId The info accessibility node id. - */ - public void remove(long accessibilityNodeId) { - if (ENABLED) { - synchronized(mLock) { - if (DEBUG) { - Log.i(LOG_TAG, "remove(" + accessibilityNodeId + ")"); + // Also be careful if the parent has changed since the new + // parent may be a predecessor of the old parent which will + // make the cached tree cyclic. + final long oldParentId = oldInfo.getParentNodeId(); + if (info.getParentNodeId() != oldParentId) { + clearSubTreeLocked(oldParentId); + } } - mCacheImpl.remove(accessibilityNodeId); + + // Cache a copy since the client calls to AccessibilityNodeInfo#recycle() + // will wipe the data of the cached info. + AccessibilityNodeInfo clone = AccessibilityNodeInfo.obtain(info); + mCacheImpl.put(sourceId, clone); } } } @@ -179,7 +210,7 @@ public class AccessibilityNodeInfoCache { * * @param rootNodeId The root id. */ - private void clearSubTree(long rootNodeId) { + private void clearSubTreeLocked(long rootNodeId) { AccessibilityNodeInfo current = mCacheImpl.get(rootNodeId); if (current == null) { return; @@ -189,7 +220,124 @@ public class AccessibilityNodeInfoCache { final int childCount = childNodeIds.size(); for (int i = 0; i < childCount; i++) { final long childNodeId = childNodeIds.valueAt(i); - clearSubTree(childNodeId); + clearSubTreeLocked(childNodeId); + } + } + + /** + * We are enforcing the invariant for a single input focus. + * + * @param currentInputFocusId The current input focused node. + */ + private void clearSubtreeWithOldInputFocusLocked(long currentInputFocusId) { + final int cacheSize = mCacheImpl.size(); + for (int i = 0; i < cacheSize; i++) { + AccessibilityNodeInfo info = mCacheImpl.valueAt(i); + final long infoSourceId = info.getSourceNodeId(); + if (infoSourceId != currentInputFocusId && info.isFocused()) { + clearSubTreeLocked(infoSourceId); + return; + } + } + } + + /** + * We are enforcing the invariant for a single accessibility focus. + * + * @param currentInputFocusId The current input focused node. + */ + private void clearSubtreeWithOldAccessibilityFocusLocked(long currentAccessibilityFocusId) { + final int cacheSize = mCacheImpl.size(); + for (int i = 0; i < cacheSize; i++) { + AccessibilityNodeInfo info = mCacheImpl.valueAt(i); + final long infoSourceId = info.getSourceNodeId(); + if (infoSourceId != currentAccessibilityFocusId && info.isAccessibilityFocused()) { + clearSubTreeLocked(infoSourceId); + return; + } + } + } + + /** + * Check the integrity of the cache which is it does not have nodes + * from more than one window, there are no duplicates, all nodes are + * connected, there is a single input focused node, and there is a + * single accessibility focused node. + */ + private void checkIntegrity() { + synchronized (mLock) { + // Get the root. + if (mCacheImpl.size() <= 0) { + return; + } + + // If the cache is a tree it does not matter from + // which node we start to search for the root. + AccessibilityNodeInfo root = mCacheImpl.valueAt(0); + AccessibilityNodeInfo parent = root; + while (parent != null) { + root = parent; + parent = mCacheImpl.get(parent.getParentNodeId()); + } + + // Traverse the tree and do some checks. + final int windowId = root.getWindowId(); + AccessibilityNodeInfo accessFocus = null; + AccessibilityNodeInfo inputFocus = null; + HashSet<AccessibilityNodeInfo> seen = new HashSet<AccessibilityNodeInfo>(); + Queue<AccessibilityNodeInfo> fringe = new LinkedList<AccessibilityNodeInfo>(); + fringe.add(root); + + while (!fringe.isEmpty()) { + AccessibilityNodeInfo current = fringe.poll(); + // Check for duplicates + if (!seen.add(current)) { + Log.e(LOG_TAG, "Duplicate node: " + current); + return; + } + + // Check for one accessibility focus. + if (current.isAccessibilityFocused()) { + if (accessFocus != null) { + Log.e(LOG_TAG, "Duplicate accessibility focus:" + current); + } else { + accessFocus = current; + } + } + + // Check for one input focus. + if (current.isFocused()) { + if (inputFocus != null) { + Log.e(LOG_TAG, "Duplicate input focus: " + current); + } else { + inputFocus = current; + } + } + + SparseLongArray childIds = current.getChildNodeIds(); + final int childCount = childIds.size(); + for (int i = 0; i < childCount; i++) { + final long childId = childIds.valueAt(i); + AccessibilityNodeInfo child = mCacheImpl.get(childId); + if (child != null) { + fringe.add(child); + } + } + } + + // Check for disconnected nodes or ones from another window. + final int cacheSize = mCacheImpl.size(); + for (int i = 0; i < cacheSize; i++) { + AccessibilityNodeInfo info = mCacheImpl.valueAt(i); + if (!seen.contains(info)) { + if (info.getWindowId() == windowId) { + Log.e(LOG_TAG, "Disconneced node: "); + } else { + Log.e(LOG_TAG, "Node from: " + info.getWindowId() + " not from:" + + windowId + " " + info); + } + } + } } } } diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java index eb6b7e3..f4796d5 100644 --- a/core/java/android/webkit/WebViewClassic.java +++ b/core/java/android/webkit/WebViewClassic.java @@ -88,7 +88,6 @@ import android.view.ViewConfiguration; import android.view.ViewGroup; import android.view.ViewParent; import android.view.ViewRootImpl; -import android.view.ViewTreeObserver; import android.view.WindowManager; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; @@ -888,20 +887,18 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc private Point mSelectHandleLeftOffset; private Point mSelectHandleRightOffset; private Point mSelectHandleCenterOffset; - private Point mSelectCursorBase = new Point(); - private int mSelectCursorBaseLayerId; - private QuadF mSelectCursorBaseTextQuad = new QuadF(); - private Point mSelectCursorExtent = new Point(); - private int mSelectCursorExtentLayerId; - private QuadF mSelectCursorExtentTextQuad = new QuadF(); + private Point mSelectCursorLeft = new Point(); + private int mSelectCursorLeftLayerId; + private QuadF mSelectCursorLeftTextQuad = new QuadF(); + private Point mSelectCursorRight = new Point(); + private int mSelectCursorRightLayerId; + private QuadF mSelectCursorRightTextQuad = new QuadF(); private Point mSelectDraggingCursor; private Point mSelectDraggingOffset; private QuadF mSelectDraggingTextQuad; private boolean mIsCaretSelection; - static final int HANDLE_ID_START = 0; - static final int HANDLE_ID_END = 1; - static final int HANDLE_ID_BASE = 2; - static final int HANDLE_ID_EXTENT = 3; + static final int HANDLE_ID_LEFT = 0; + static final int HANDLE_ID_RIGHT = 1; // the color used to highlight the touch rectangles static final int HIGHLIGHT_COLOR = 0x6633b5e5; @@ -3722,13 +3719,13 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc return; } if (mSelectingText) { - if (mSelectCursorBaseLayerId == mCurrentScrollingLayerId) { - mSelectCursorBase.offset(dx, dy); - mSelectCursorBaseTextQuad.offset(dx, dy); + if (mSelectCursorLeftLayerId == mCurrentScrollingLayerId) { + mSelectCursorLeft.offset(dx, dy); + mSelectCursorLeftTextQuad.offset(dx, dy); } - if (mSelectCursorExtentLayerId == mCurrentScrollingLayerId) { - mSelectCursorExtent.offset(dx, dy); - mSelectCursorExtentTextQuad.offset(dx, dy); + if (mSelectCursorRightLayerId == mCurrentScrollingLayerId) { + mSelectCursorRight.offset(dx, dy); + mSelectCursorRightTextQuad.offset(dx, dy); } } else if (mHandleAlpha.getAlpha() > 0) { // stop fading as we're not going to move with the layer. @@ -3829,6 +3826,9 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc // reset the flag since we set to true in if need after // loading is see onPageFinished(Url) mAccessibilityScriptInjected = false; + + // Don't start out editing. + mIsEditingText = false; } /** @@ -4589,18 +4589,10 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc * startX, startY, endX, endY */ private void getSelectionHandles(int[] handles) { - handles[0] = mSelectCursorBase.x; - handles[1] = mSelectCursorBase.y; - handles[2] = mSelectCursorExtent.x; - handles[3] = mSelectCursorExtent.y; - if (!nativeIsBaseFirst(mNativeClass)) { - int swap = handles[0]; - handles[0] = handles[2]; - handles[2] = swap; - swap = handles[1]; - handles[1] = handles[3]; - handles[3] = swap; - } + handles[0] = mSelectCursorLeft.x; + handles[1] = mSelectCursorLeft.y; + handles[2] = mSelectCursorRight.x; + handles[3] = mSelectCursorRight.y; } // draw history @@ -5107,8 +5099,8 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc ClipboardManager cm = (ClipboardManager)(mContext .getSystemService(Context.CLIPBOARD_SERVICE)); if (cm.hasPrimaryClip()) { - Point cursorPoint = new Point(contentToViewX(mSelectCursorBase.x), - contentToViewY(mSelectCursorBase.y)); + Point cursorPoint = new Point(contentToViewX(mSelectCursorLeft.x), + contentToViewY(mSelectCursorLeft.y)); Point cursorTop = calculateCaretTop(); cursorTop.set(contentToViewX(cursorTop.x), contentToViewY(cursorTop.y)); @@ -5158,12 +5150,12 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc * calculates the top of a caret. */ private Point calculateCaretTop() { - float scale = scaleAlongSegment(mSelectCursorBase.x, mSelectCursorBase.y, - mSelectCursorBaseTextQuad.p4, mSelectCursorBaseTextQuad.p3); + float scale = scaleAlongSegment(mSelectCursorLeft.x, mSelectCursorLeft.y, + mSelectCursorLeftTextQuad.p4, mSelectCursorLeftTextQuad.p3); int x = Math.round(scaleCoordinate(scale, - mSelectCursorBaseTextQuad.p1.x, mSelectCursorBaseTextQuad.p2.x)); + mSelectCursorLeftTextQuad.p1.x, mSelectCursorLeftTextQuad.p2.x)); int y = Math.round(scaleCoordinate(scale, - mSelectCursorBaseTextQuad.p1.y, mSelectCursorBaseTextQuad.p2.y)); + mSelectCursorLeftTextQuad.p1.y, mSelectCursorLeftTextQuad.p2.y)); return new Point(x, y); } @@ -5174,46 +5166,40 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc } private void syncSelectionCursors() { - mSelectCursorBaseLayerId = - nativeGetHandleLayerId(mNativeClass, HANDLE_ID_BASE, - mSelectCursorBase, mSelectCursorBaseTextQuad); - mSelectCursorExtentLayerId = - nativeGetHandleLayerId(mNativeClass, HANDLE_ID_EXTENT, - mSelectCursorExtent, mSelectCursorExtentTextQuad); + mSelectCursorLeftLayerId = + nativeGetHandleLayerId(mNativeClass, HANDLE_ID_LEFT, + mSelectCursorLeft, mSelectCursorLeftTextQuad); + mSelectCursorRightLayerId = + nativeGetHandleLayerId(mNativeClass, HANDLE_ID_RIGHT, + mSelectCursorRight, mSelectCursorRightTextQuad); } private void adjustSelectionCursors() { - boolean wasDraggingStart = (mSelectDraggingCursor == mSelectCursorBase); + if (mIsCaretSelection) { + return; // no need to swap left and right handles. + } + + boolean wasDraggingLeft = (mSelectDraggingCursor == mSelectCursorLeft); int oldX = mSelectDraggingCursor.x; int oldY = mSelectDraggingCursor.y; - int oldStartX = mSelectCursorBase.x; - int oldStartY = mSelectCursorBase.y; - int oldEndX = mSelectCursorExtent.x; - int oldEndY = mSelectCursorExtent.y; - + int oldLeftX = mSelectCursorLeft.x; + int oldLeftY = mSelectCursorLeft.y; + int oldRightX = mSelectCursorRight.x; + int oldRightY = mSelectCursorRight.y; syncSelectionCursors(); - boolean dragChanged = oldX != mSelectDraggingCursor.x || - oldY != mSelectDraggingCursor.y; - if (dragChanged && !mIsCaretSelection) { - boolean draggingStart; - if (wasDraggingStart) { - float endStart = distanceSquared(oldEndX, oldEndY, - mSelectCursorBase); - float endEnd = distanceSquared(oldEndX, oldEndY, - mSelectCursorExtent); - draggingStart = endStart > endEnd; - } else { - float startStart = distanceSquared(oldStartX, oldStartY, - mSelectCursorBase); - float startEnd = distanceSquared(oldStartX, oldStartY, - mSelectCursorExtent); - draggingStart = startStart > startEnd; - } - mSelectDraggingCursor = (draggingStart - ? mSelectCursorBase : mSelectCursorExtent); - mSelectDraggingTextQuad = (draggingStart - ? mSelectCursorBaseTextQuad : mSelectCursorExtentTextQuad); - mSelectDraggingOffset = (draggingStart + + boolean rightChanged = (oldRightX != mSelectCursorRight.x + || oldRightY != mSelectCursorRight.y); + boolean leftChanged = (oldLeftX != mSelectCursorLeft.x + || oldLeftY != mSelectCursorLeft.y); + if (leftChanged && rightChanged) { + // Left and right switched places, so swap dragging cursor + boolean draggingLeft = !wasDraggingLeft; + mSelectDraggingCursor = (draggingLeft + ? mSelectCursorLeft : mSelectCursorRight); + mSelectDraggingTextQuad = (draggingLeft + ? mSelectCursorLeftTextQuad : mSelectCursorRightTextQuad); + mSelectDraggingOffset = (draggingLeft ? mSelectHandleLeftOffset : mSelectHandleRightOffset); } mSelectDraggingCursor.set(oldX, oldY); @@ -5239,14 +5225,11 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc private void updateWebkitSelection() { int[] handles = null; if (mIsCaretSelection) { - mSelectCursorExtent.set(mSelectCursorBase.x, mSelectCursorBase.y); + mSelectCursorRight.set(mSelectCursorLeft.x, mSelectCursorLeft.y); } if (mSelectingText) { handles = new int[4]; - handles[0] = mSelectCursorBase.x; - handles[1] = mSelectCursorBase.y; - handles[2] = mSelectCursorExtent.x; - handles[3] = mSelectCursorExtent.y; + getSelectionHandles(handles); } else { nativeSetTextSelection(mNativeClass, 0); } @@ -5610,21 +5593,21 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc Point caretTop = calculateCaretTop(); if (visibleRect.width() < mEditTextContentBounds.width()) { // The whole edit won't fit in the width, so use the caret rect - if (mSelectCursorBase.x < caretTop.x) { - showRect.left = Math.max(0, mSelectCursorBase.x - buffer); + if (mSelectCursorLeft.x < caretTop.x) { + showRect.left = Math.max(0, mSelectCursorLeft.x - buffer); showRect.right = caretTop.x + buffer; } else { showRect.left = Math.max(0, caretTop.x - buffer); - showRect.right = mSelectCursorBase.x + buffer; + showRect.right = mSelectCursorLeft.x + buffer; } } if (visibleRect.height() < mEditTextContentBounds.height()) { // The whole edit won't fit in the height, so use the caret rect - if (mSelectCursorBase.y > caretTop.y) { + if (mSelectCursorLeft.y > caretTop.y) { showRect.top = Math.max(0, caretTop.y - buffer); - showRect.bottom = mSelectCursorBase.y + buffer; + showRect.bottom = mSelectCursorLeft.y + buffer; } else { - showRect.top = Math.max(0, mSelectCursorBase.y - buffer); + showRect.top = Math.max(0, mSelectCursorLeft.y - buffer); showRect.bottom = caretTop.y + buffer; } } @@ -5885,25 +5868,25 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc if (mSelectHandleCenter != null && mSelectHandleCenter.getBounds() .contains(shiftedX, shiftedY)) { mSelectionStarted = true; - mSelectDraggingCursor = mSelectCursorBase; + mSelectDraggingCursor = mSelectCursorLeft; mSelectDraggingOffset = mSelectHandleCenterOffset; - mSelectDraggingTextQuad = mSelectCursorBaseTextQuad; + mSelectDraggingTextQuad = mSelectCursorLeftTextQuad; mPrivateHandler.removeMessages(CLEAR_CARET_HANDLE); hidePasteButton(); } else if (mSelectHandleLeft != null && mSelectHandleLeft.getBounds() .contains(shiftedX, shiftedY)) { - mSelectionStarted = true; - mSelectDraggingCursor = mSelectCursorBase; - mSelectDraggingOffset = mSelectHandleLeftOffset; - mSelectDraggingTextQuad = mSelectCursorBaseTextQuad; + mSelectionStarted = true; + mSelectDraggingOffset = mSelectHandleLeftOffset; + mSelectDraggingCursor = mSelectCursorLeft; + mSelectDraggingTextQuad = mSelectCursorLeftTextQuad; } else if (mSelectHandleRight != null && mSelectHandleRight.getBounds() .contains(shiftedX, shiftedY)) { mSelectionStarted = true; - mSelectDraggingCursor = mSelectCursorExtent; mSelectDraggingOffset = mSelectHandleRightOffset; - mSelectDraggingTextQuad = mSelectCursorExtentTextQuad; + mSelectDraggingCursor = mSelectCursorRight; + mSelectDraggingTextQuad = mSelectCursorRightTextQuad; } else if (mIsCaretSelection) { selectionDone(); } @@ -8648,7 +8631,6 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc private native void nativeUpdateDrawGLFunction(int nativeInstance, Rect invScreenRect, Rect screenRect, RectF visibleContentRect, float scale); private native String nativeGetSelection(); - private native Rect nativeLayerBounds(int layer); private native void nativeSetHeightCanMeasure(boolean measure); private native boolean nativeSetBaseLayer(int nativeInstance, int layer, boolean showVisualIndicator, boolean isPictureAfterFirstLayout); @@ -8691,7 +8673,6 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc private static native void nativeSetTextSelection(int instance, int selection); private static native int nativeGetHandleLayerId(int instance, int handle, Point cursorLocation, QuadF textQuad); - private static native boolean nativeIsBaseFirst(int instance); private static native void nativeMapLayerRect(int instance, int layerId, Rect rect); // Returns 1 if a layer sync is needed, else 0 diff --git a/core/java/android/widget/CheckedTextView.java b/core/java/android/widget/CheckedTextView.java index 278192c..61935c2 100644 --- a/core/java/android/widget/CheckedTextView.java +++ b/core/java/android/widget/CheckedTextView.java @@ -93,6 +93,7 @@ public class CheckedTextView extends TextView implements Checkable { if (mChecked != checked) { mChecked = checked; refreshDrawableState(); + notifyAccessibilityStateChanged(); } } diff --git a/core/java/android/widget/CompoundButton.java b/core/java/android/widget/CompoundButton.java index 02c4c4f..0a71c5a 100644 --- a/core/java/android/widget/CompoundButton.java +++ b/core/java/android/widget/CompoundButton.java @@ -114,6 +114,7 @@ public abstract class CompoundButton extends Button implements Checkable { if (mChecked != checked) { mChecked = checked; refreshDrawableState(); + notifyAccessibilityStateChanged(); // Avoid infinite recursions if setChecked() is called from a listener if (mBroadcasting) { diff --git a/core/java/android/widget/GridLayout.java b/core/java/android/widget/GridLayout.java index cb10d0a..60a1d15 100644 --- a/core/java/android/widget/GridLayout.java +++ b/core/java/android/widget/GridLayout.java @@ -581,7 +581,7 @@ public class GridLayout extends ViewGroup { } private int getDefaultMargin(View c, boolean isAtEdge, boolean horizontal, boolean leading) { - return /*isAtEdge ? DEFAULT_CONTAINER_MARGIN :*/ getDefaultMargin(c, horizontal, leading); + return isAtEdge ? DEFAULT_CONTAINER_MARGIN : getDefaultMargin(c, horizontal, leading); } private int getDefaultMargin(View c, LayoutParams p, boolean horizontal, boolean leading) { @@ -733,6 +733,11 @@ public class GridLayout extends ViewGroup { @Override protected void onSetLayoutParams(View child, ViewGroup.LayoutParams layoutParams) { super.onSetLayoutParams(child, layoutParams); + + if (!checkLayoutParams(layoutParams)) { + handleInvalidParams("supplied LayoutParams are of the wrong type"); + } + invalidateStructure(); } @@ -740,6 +745,43 @@ public class GridLayout extends ViewGroup { return (LayoutParams) c.getLayoutParams(); } + private static void handleInvalidParams(String msg) { + throw new IllegalArgumentException(msg + ". "); + } + + private void checkLayoutParams(LayoutParams lp, boolean horizontal) { + String groupName = horizontal ? "column" : "row"; + Spec spec = horizontal ? lp.columnSpec : lp.rowSpec; + Interval span = spec.span; + if (span.min != UNDEFINED && span.min < 0) { + handleInvalidParams(groupName + " indices must be positive"); + } + Axis axis = horizontal ? horizontalAxis : verticalAxis; + int count = axis.definedCount; + if (count != UNDEFINED) { + if (span.max > count) { + handleInvalidParams(groupName + + " indices (start + span) mustn't exceed the " + groupName + " count"); + } + if (span.size() > count) { + handleInvalidParams(groupName + " span mustn't exceed the " + groupName + " count"); + } + } + } + + @Override + protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { + if (!(p instanceof LayoutParams)) { + return false; + } + LayoutParams lp = (LayoutParams) p; + + checkLayoutParams(lp, true); + checkLayoutParams(lp, false); + + return true; + } + @Override protected LayoutParams generateDefaultLayoutParams() { return new LayoutParams(); @@ -1143,6 +1185,7 @@ public class GridLayout extends ViewGroup { Interval span = spec.span; result = max(result, span.min); result = max(result, span.max); + result = max(result, span.size()); } return result == -1 ? UNDEFINED : result; } @@ -1159,6 +1202,11 @@ public class GridLayout extends ViewGroup { } public void setCount(int count) { + if (count != UNDEFINED && count < getMaxIndex()) { + handleInvalidParams((horizontal ? "column" : "row") + + "Count must be greater than or equal to the maximum of all grid indices " + + "(and spans) defined in the LayoutParams of each child"); + } this.definedCount = count; } @@ -1478,20 +1526,6 @@ public class GridLayout extends ViewGroup { This is a special case of the Linear Programming problem that is, in turn, equivalent to the single-source shortest paths problem on a digraph, for which the O(n^2) Bellman-Ford algorithm the most commonly used general solution. - - Other algorithms are faster in the case where no arcs have negative weights - but allowing negative weights turns out to be the same as accommodating maximum - size requirements as well as minimum ones. - - Bellman-Ford works by iteratively 'relaxing' constraints over all nodes (an O(N) - process) and performing this step N times. Proof of correctness hinges on the - fact that there can be no negative weight chains of length > N - unless a - 'negative weight loop' exists. The algorithm catches this case in a final - checking phase that reports failure. - - By topologically sorting the nodes and checking this condition at each step - typical layout problems complete after the first iteration and the algorithm - completes in O(N) steps with very low constants. */ private void solve(Arc[] arcs, int[] locations) { String axisName = horizontal ? "horizontal" : "vertical"; diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 56eca01..abf2eb2 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -1472,6 +1472,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } setText(mText); + + if (hasPasswordTransformationMethod()) { + notifyAccessibilityStateChanged(); + } } /** diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java index fbed485..4c34d73 100644 --- a/core/java/com/android/internal/view/BaseIWindow.java +++ b/core/java/com/android/internal/view/BaseIWindow.java @@ -33,7 +33,7 @@ public class BaseIWindow extends IWindow.Stub { mSession = session; } - public void resized(int w, int h, Rect systemInsets, Rect contentInsets, + public void resized(int w, int h, Rect contentInsets, Rect visibleInsets, boolean reportDraw, Configuration newConfig) { if (reportDraw) { try { diff --git a/core/java/com/android/internal/view/menu/MenuBuilder.java b/core/java/com/android/internal/view/menu/MenuBuilder.java index 9fbca82..458ea2f 100644 --- a/core/java/com/android/internal/view/menu/MenuBuilder.java +++ b/core/java/com/android/internal/view/menu/MenuBuilder.java @@ -873,15 +873,20 @@ public class MenuBuilder implements Menu { boolean invoked = itemImpl.invoke(); + final ActionProvider provider = item.getActionProvider(); + final boolean providerHasSubMenu = provider != null && provider.hasSubMenu(); if (itemImpl.hasCollapsibleActionView()) { invoked |= itemImpl.expandActionView(); if (invoked) close(true); - } else if (item.hasSubMenu()) { + } else if (itemImpl.hasSubMenu() || providerHasSubMenu) { close(false); - final SubMenuBuilder subMenu = (SubMenuBuilder) item.getSubMenu(); - final ActionProvider provider = item.getActionProvider(); - if (provider != null && provider.hasSubMenu()) { + if (!itemImpl.hasSubMenu()) { + itemImpl.setSubMenu(new SubMenuBuilder(getContext(), this, itemImpl)); + } + + final SubMenuBuilder subMenu = (SubMenuBuilder) itemImpl.getSubMenu(); + if (providerHasSubMenu) { provider.onPrepareSubMenu(subMenu); } invoked |= dispatchSubMenuSelected(subMenu); diff --git a/core/java/com/android/internal/widget/PointerLocationView.java b/core/java/com/android/internal/widget/PointerLocationView.java index 1d6af90..85e6c16 100644 --- a/core/java/com/android/internal/widget/PointerLocationView.java +++ b/core/java/com/android/internal/widget/PointerLocationView.java @@ -527,7 +527,7 @@ public class PointerLocationView extends View implements InputDeviceListener { ps.addTrace(coords.x, coords.y); ps.mXVelocity = mVelocity.getXVelocity(id); ps.mYVelocity = mVelocity.getYVelocity(id); - mVelocity.getEstimator(id, -1, -1, ps.mEstimator); + mVelocity.getEstimator(id, ps.mEstimator); ps.mToolType = event.getToolType(i); } } |
