diff options
Diffstat (limited to 'core')
15 files changed, 427 insertions, 192 deletions
diff --git a/core/java/android/hardware/camera2/CameraProperties.java b/core/java/android/hardware/camera2/CameraProperties.java index e713d21..0c39705 100644 --- a/core/java/android/hardware/camera2/CameraProperties.java +++ b/core/java/android/hardware/camera2/CameraProperties.java @@ -384,8 +384,8 @@ public final class CameraProperties extends CameraMetadata { * Needed for FOV calculation for old API * </p> */ - public static final Key<android.hardware.camera2.Size> SENSOR_INFO_PHYSICAL_SIZE = - new Key<android.hardware.camera2.Size>("android.sensor.info.physicalSize", android.hardware.camera2.Size.class); + public static final Key<float[]> SENSOR_INFO_PHYSICAL_SIZE = + new Key<float[]>("android.sensor.info.physicalSize", float[].class); /** * <p> diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java index 28225e6..8b5bf4a 100644 --- a/core/java/android/hardware/camera2/CaptureRequest.java +++ b/core/java/android/hardware/camera2/CaptureRequest.java @@ -181,6 +181,10 @@ public final class CaptureRequest extends CameraMetadata implements Parcelable { *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~*/ /** + * <p> + * When android.sensor.awbMode is not OFF, TRANSFORM_MATRIX + * should be ignored. + * </p> * @see #COLOR_CORRECTION_MODE_TRANSFORM_MATRIX * @see #COLOR_CORRECTION_MODE_FAST * @see #COLOR_CORRECTION_MODE_HIGH_QUALITY @@ -197,7 +201,8 @@ public final class CaptureRequest extends CameraMetadata implements Parcelable { * This matrix is either set by HAL when the request * android.colorCorrection.mode is not TRANSFORM_MATRIX, or * directly by the application in the request when the - * androird.colorCorrection.mode is TRANSFORM_MATRIX. + * android.colorCorrection.mode is TRANSFORM_MATRIX. + * </p><p> * In the latter case, the HAL may round the matrix to account * for precision issues; the final rounded matrix should be * reported back in this matrix result metadata. @@ -220,6 +225,11 @@ public final class CaptureRequest extends CameraMetadata implements Parcelable { * it should use the G_even value,and write G_odd equal to * G_even in the output result metadata. * </p><p> + * This array is either set by HAL when the request + * android.colorCorrection.mode is not TRANSFORM_MATRIX, or + * directly by the application in the request when the + * android.colorCorrection.mode is TRANSFORM_MATRIX. + * </p><p> * The ouput should be the gains actually applied by the HAL to * the current frame. * </p> @@ -781,7 +791,10 @@ public final class CaptureRequest extends CameraMetadata implements Parcelable { /** * <p> * Duration each pixel is exposed to - * light + * light. + * </p><p> + * If the sensor can't expose this exact duration, it should shorten the + * duration exposed to the nearest possible value (rather than expose longer). * </p> * <p> * 1/10000 - 30 sec range. No bulb mode @@ -808,6 +821,9 @@ public final class CaptureRequest extends CameraMetadata implements Parcelable { * Gain applied to image data. Must be * implemented through analog gain only if set to values * below 'maximum analog sensitivity'. + * </p><p> + * If the sensor can't apply this exact gain, it should lessen the + * gain to the nearest possible value (rather than gain more). * </p> * <p> * ISO 12232:2006 REI method @@ -839,18 +855,30 @@ public final class CaptureRequest extends CameraMetadata implements Parcelable { * Table mapping blue input values to output * values * </p> + * <p> + * Tonemapping / contrast / gamma curve for the blue + * channel, to use when android.tonemap.mode is CONTRAST_CURVE. + * </p><p> + * See android.tonemap.curveRed for more details. + * </p> */ - public static final Key<Float> TONEMAP_CURVE_BLUE = - new Key<Float>("android.tonemap.curveBlue", float.class); + public static final Key<float[]> TONEMAP_CURVE_BLUE = + new Key<float[]>("android.tonemap.curveBlue", float[].class); /** * <p> * Table mapping green input values to output * values * </p> + * <p> + * Tonemapping / contrast / gamma curve for the green + * channel, to use when android.tonemap.mode is CONTRAST_CURVE. + * </p><p> + * See android.tonemap.curveRed for more details. + * </p> */ - public static final Key<Float> TONEMAP_CURVE_GREEN = - new Key<Float>("android.tonemap.curveGreen", float.class); + public static final Key<float[]> TONEMAP_CURVE_GREEN = + new Key<float[]>("android.tonemap.curveGreen", float[].class); /** * <p> @@ -858,9 +886,17 @@ public final class CaptureRequest extends CameraMetadata implements Parcelable { * values * </p> * <p> - * .The input range must be monotonically increasing - * with N, and values between entries should be linearly - * interpolated. For example, if the array is: [0.0, 0.0, + * Tonemapping / contrast / gamma curve for the red + * channel, to use when android.tonemap.mode is CONTRAST_CURVE. + * </p><p> + * Since the input and output ranges may vary depending on + * the camera pipeline, the input and output pixel values + * are represented by normalized floating-point values + * between 0 and 1, with 0 == black and 1 == white. + * </p><p> + * The curve should be linearly interpolated between the + * defined points. The points will be listed in increasing + * order of P_IN. For example, if the array is: [0.0, 0.0, * 0.3, 0.5, 1.0, 1.0], then the input->output mapping * for a few sample points would be: 0 -> 0, 0.15 -> * 0.25, 0.3 -> 0.5, 0.5 -> 0.64 @@ -913,6 +949,13 @@ public final class CaptureRequest extends CameraMetadata implements Parcelable { * compensation, the HAL must report whether setting the * black level lock was successful in the output result * metadata. + * </p><p> + * The black level locking must happen at the sensor, and not at the ISP. + * If for some reason black level locking is no longer legal (for example, + * the analog gain has changed, which forces black levels to be + * recalculated), then the HAL is free to override this request (and it + * must report 'OFF' when this does happen) until the next time locking + * is legal again. * </p> */ public static final Key<Boolean> BLACK_LEVEL_LOCK = diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java index 31377be..ef6aaa0 100644 --- a/core/java/android/hardware/camera2/CaptureResult.java +++ b/core/java/android/hardware/camera2/CaptureResult.java @@ -138,7 +138,8 @@ public final class CaptureResult extends CameraMetadata { * This matrix is either set by HAL when the request * android.colorCorrection.mode is not TRANSFORM_MATRIX, or * directly by the application in the request when the - * androird.colorCorrection.mode is TRANSFORM_MATRIX. + * android.colorCorrection.mode is TRANSFORM_MATRIX. + * </p><p> * In the latter case, the HAL may round the matrix to account * for precision issues; the final rounded matrix should be * reported back in this matrix result metadata. @@ -161,6 +162,11 @@ public final class CaptureResult extends CameraMetadata { * it should use the G_even value,and write G_odd equal to * G_even in the output result metadata. * </p><p> + * This array is either set by HAL when the request + * android.colorCorrection.mode is not TRANSFORM_MATRIX, or + * directly by the application in the request when the + * android.colorCorrection.mode is TRANSFORM_MATRIX. + * </p><p> * The ouput should be the gains actually applied by the HAL to * the current frame. * </p> @@ -651,7 +657,10 @@ public final class CaptureResult extends CameraMetadata { /** * <p> * Duration each pixel is exposed to - * light + * light. + * </p><p> + * If the sensor can't expose this exact duration, it should shorten the + * duration exposed to the nearest possible value (rather than expose longer). * </p> * <p> * 1/10000 - 30 sec range. No bulb mode @@ -678,6 +687,9 @@ public final class CaptureResult extends CameraMetadata { * Gain applied to image data. Must be * implemented through analog gain only if set to values * below 'maximum analog sensitivity'. + * </p><p> + * If the sensor can't apply this exact gain, it should lessen the + * gain to the nearest possible value (rather than gain more). * </p> * <p> * ISO 12232:2006 REI method @@ -701,6 +713,18 @@ public final class CaptureResult extends CameraMetadata { /** * <p> + * The temperature of the sensor, sampled at the time + * exposure began for this frame. + * </p><p> + * The thermal diode being queried should be inside the sensor PCB, or + * somewhere close to it. + * </p> + */ + public static final Key<Float> SENSOR_TEMPERATURE = + new Key<Float>("android.sensor.temperature", float.class); + + /** + * <p> * State of the face detector * unit * </p> @@ -759,7 +783,8 @@ public final class CaptureResult extends CameraMetadata { * detected faces * </p> * <p> - * Only available if faceDetectMode != OFF + * Only available if faceDetectMode != OFF. The value should be + * meaningful (for example, setting 100 at all times is illegal). * </p> */ public static final Key<byte[]> STATISTICS_FACE_SCORES = @@ -776,6 +801,9 @@ public final class CaptureResult extends CameraMetadata { * of 1; all other sections should have gains above 1. * the map should be on the order of 30-40 rows, and * must be smaller than 64x64. + * </p><p> + * When android.colorCorrection.mode = TRANSFORM_MATRIX, the map + * must take into account the colorCorrection settings. * </p> */ public static final Key<float[]> STATISTICS_LENS_SHADING_MAP = @@ -794,6 +822,9 @@ public final class CaptureResult extends CameraMetadata { * </p><p> * The 4 channel gains are defined in Bayer domain, * see android.colorCorrection.gains for details. + * </p><p> + * This value should always be calculated by the AWB block, + * regardless of the android.control.* current values. * </p> */ public static final Key<float[]> STATISTICS_PREDICTED_COLOR_GAINS = @@ -817,6 +848,9 @@ public final class CaptureResult extends CameraMetadata { * </p><p> * These estimates must be provided for all frames, even if * capture settings and color transforms are set by the application. + * </p><p> + * This value should always be calculated by the AWB block, + * regardless of the android.control.* current values. * </p> */ public static final Key<Rational[]> STATISTICS_PREDICTED_COLOR_TRANSFORM = @@ -843,18 +877,30 @@ public final class CaptureResult extends CameraMetadata { * Table mapping blue input values to output * values * </p> + * <p> + * Tonemapping / contrast / gamma curve for the blue + * channel, to use when android.tonemap.mode is CONTRAST_CURVE. + * </p><p> + * See android.tonemap.curveRed for more details. + * </p> */ - public static final Key<Float> TONEMAP_CURVE_BLUE = - new Key<Float>("android.tonemap.curveBlue", float.class); + public static final Key<float[]> TONEMAP_CURVE_BLUE = + new Key<float[]>("android.tonemap.curveBlue", float[].class); /** * <p> * Table mapping green input values to output * values * </p> + * <p> + * Tonemapping / contrast / gamma curve for the green + * channel, to use when android.tonemap.mode is CONTRAST_CURVE. + * </p><p> + * See android.tonemap.curveRed for more details. + * </p> */ - public static final Key<Float> TONEMAP_CURVE_GREEN = - new Key<Float>("android.tonemap.curveGreen", float.class); + public static final Key<float[]> TONEMAP_CURVE_GREEN = + new Key<float[]>("android.tonemap.curveGreen", float[].class); /** * <p> @@ -862,9 +908,17 @@ public final class CaptureResult extends CameraMetadata { * values * </p> * <p> - * .The input range must be monotonically increasing - * with N, and values between entries should be linearly - * interpolated. For example, if the array is: [0.0, 0.0, + * Tonemapping / contrast / gamma curve for the red + * channel, to use when android.tonemap.mode is CONTRAST_CURVE. + * </p><p> + * Since the input and output ranges may vary depending on + * the camera pipeline, the input and output pixel values + * are represented by normalized floating-point values + * between 0 and 1, with 0 == black and 1 == white. + * </p><p> + * The curve should be linearly interpolated between the + * defined points. The points will be listed in increasing + * order of P_IN. For example, if the array is: [0.0, 0.0, * 0.3, 0.5, 1.0, 1.0], then the input->output mapping * for a few sample points would be: 0 -> 0, 0.15 -> * 0.25, 0.3 -> 0.5, 0.5 -> 0.64 @@ -917,6 +971,13 @@ public final class CaptureResult extends CameraMetadata { * compensation, the HAL must report whether setting the * black level lock was successful in the output result * metadata. + * </p><p> + * The black level locking must happen at the sensor, and not at the ISP. + * If for some reason black level locking is no longer legal (for example, + * the analog gain has changed, which forces black levels to be + * recalculated), then the HAL is free to override this request (and it + * must report 'OFF' when this does happen) until the next time locking + * is legal again. * </p> */ public static final Key<Boolean> BLACK_LEVEL_LOCK = diff --git a/core/java/android/hardware/camera2/impl/CameraDevice.java b/core/java/android/hardware/camera2/impl/CameraDevice.java index fa79051..1fb690e 100644 --- a/core/java/android/hardware/camera2/impl/CameraDevice.java +++ b/core/java/android/hardware/camera2/impl/CameraDevice.java @@ -24,6 +24,7 @@ import android.hardware.camera2.CameraAccessException; import android.hardware.camera2.CameraProperties; import android.hardware.camera2.CaptureRequest; import android.hardware.camera2.utils.CameraRuntimeException; +import android.hardware.camera2.utils.CameraBinderDecorator; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; @@ -67,7 +68,8 @@ public class CameraDevice implements android.hardware.camera2.CameraDevice { } public void setRemoteDevice(ICameraDeviceUser remoteDevice) { - mRemoteDevice = remoteDevice; + // TODO: Move from decorator to direct binder-mediated exceptions + mRemoteDevice = CameraBinderDecorator.newInstance(remoteDevice); } @Override diff --git a/core/java/android/net/INetworkManagementEventObserver.aidl b/core/java/android/net/INetworkManagementEventObserver.aidl index 6f4dd5f..b76e4c2 100644 --- a/core/java/android/net/INetworkManagementEventObserver.aidl +++ b/core/java/android/net/INetworkManagementEventObserver.aidl @@ -53,6 +53,27 @@ interface INetworkManagementEventObserver { */ void interfaceRemoved(String iface); + + /** + * An interface address has been added or updated + * + * @param address The address. + * @param iface The interface. + * @param flags The address flags. + * @param scope The address scope. + */ + void addressUpdated(String address, String iface, int flags, int scope); + + /** + * An interface address has been removed + * + * @param address The address. + * @param iface The interface. + * @param flags The address flags. + * @param scope The address scope. + */ + void addressRemoved(String address, String iface, int flags, int scope); + /** * A networking quota limit has been reached. The quota might not * be specific to an interface. diff --git a/core/java/android/widget/ActivityChooserView.java b/core/java/android/widget/ActivityChooserView.java index 2037c3a..c070ee4 100644 --- a/core/java/android/widget/ActivityChooserView.java +++ b/core/java/android/widget/ActivityChooserView.java @@ -33,6 +33,7 @@ import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.view.ViewTreeObserver.OnGlobalLayoutListener; +import android.view.accessibility.AccessibilityNodeInfo; import android.widget.ActivityChooserModel.ActivityChooserModelClient; /** @@ -229,6 +230,13 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod mExpandActivityOverflowButton = (FrameLayout) findViewById(R.id.expand_activities_button); mExpandActivityOverflowButton.setOnClickListener(mCallbacks); + mExpandActivityOverflowButton.setAccessibilityDelegate(new AccessibilityDelegate() { + @Override + public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) { + super.onInitializeAccessibilityNodeInfo(host, info); + info.setOpensPopup(true); + } + }); mExpandActivityOverflowButtonImage = (ImageView) mExpandActivityOverflowButton.findViewById(R.id.image); mExpandActivityOverflowButtonImage.setImageDrawable(expandActivityOverflowButtonDrawable); diff --git a/core/java/android/widget/ListPopupWindow.java b/core/java/android/widget/ListPopupWindow.java index 2b4e520..8919248 100644 --- a/core/java/android/widget/ListPopupWindow.java +++ b/core/java/android/widget/ListPopupWindow.java @@ -33,6 +33,7 @@ import android.view.MotionEvent; import android.view.View; import android.view.View.MeasureSpec; import android.view.View.OnTouchListener; +import android.view.ViewConfiguration; import android.view.ViewGroup; import android.view.ViewParent; import android.view.animation.AccelerateDecelerateInterpolator; @@ -961,33 +962,6 @@ public class ListPopupWindow { } /** - * Receives motion events forwarded from a source view. This is used - * internally to implement support for drag-to-open. - * - * @param src view from which the event was forwarded - * @param srcEvent forwarded motion event in source-local coordinates - * @param activePointerId id of the pointer that activated forwarding - * @return whether the event was handled - * @hide - */ - public boolean onForwardedEvent(View src, MotionEvent srcEvent, int activePointerId) { - final DropDownListView dst = mDropDownList; - if (dst == null || !dst.isShown()) { - return false; - } - - // Convert event to local coordinates. - final MotionEvent dstEvent = MotionEvent.obtainNoHistory(srcEvent); - src.toGlobalMotionEvent(dstEvent); - dst.toLocalMotionEvent(dstEvent); - - // Forward converted event, then recycle it. - final boolean handled = dst.onForwardedEvent(dstEvent, activePointerId); - dstEvent.recycle(); - return handled; - } - - /** * <p>Builds the popup window's content and returns the height the popup * should have. Returns -1 when the content already exists.</p> * @@ -1155,6 +1129,147 @@ public class ListPopupWindow { } /** + * Abstract class that forwards touch events to a {@link ListPopupWindow}. + * + * @hide + */ + public static abstract class ForwardingListener implements View.OnTouchListener { + /** Scaled touch slop, used for detecting movement outside bounds. */ + private final float mScaledTouchSlop; + + /** Whether this listener is currently forwarding touch events. */ + private boolean mForwarding; + + /** The id of the first pointer down in the current event stream. */ + private int mActivePointerId; + + public ForwardingListener(Context context) { + mScaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); + } + + /** + * Returns the popup to which this listener is forwarding events. + * <p> + * Override this to return the correct popup. If the popup is displayed + * asynchronously, you may also need to override + * {@link #onForwardingStopped} to prevent premature cancelation of + * forwarding. + * + * @return the popup to which this listener is forwarding events + */ + public abstract ListPopupWindow getPopup(); + + @Override + public boolean onTouch(View v, MotionEvent event) { + final boolean wasForwarding = mForwarding; + final boolean forwarding; + if (wasForwarding) { + forwarding = onTouchForwarded(v, event) || !onForwardingStopped(); + } else { + forwarding = onTouchObserved(v, event) && onForwardingStarted(); + } + + mForwarding = forwarding; + return forwarding || wasForwarding; + } + + /** + * Called when forwarding would like to start. + * <p> + * By default, this will show the popup returned by {@link #getPopup()}. + * It may be overridden to perform another action, like clicking the + * source view or preparing the popup before showing it. + * + * @return true to start forwarding, false otherwise + */ + public boolean onForwardingStarted() { + final ListPopupWindow popup = getPopup(); + if (popup != null && !popup.isShowing()) { + popup.show(); + } + return true; + } + + /** + * Called when forwarding would like to stop. + * <p> + * By default, this will dismiss the popup returned by + * {@link #getPopup()}. It may be overridden to perform some other + * action. + * + * @return true to stop forwarding, false otherwise + */ + public boolean onForwardingStopped() { + final ListPopupWindow popup = getPopup(); + if (popup != null && popup.isShowing()) { + popup.dismiss(); + } + return true; + } + + /** + * Observes motion events and determines when to start forwarding. + * + * @param src view from which the event originated + * @param srcEvent motion event in source view coordinates + * @return true to start forwarding motion events, false otherwise + */ + private boolean onTouchObserved(View src, MotionEvent srcEvent) { + if (!src.isEnabled()) { + return false; + } + + // The first pointer down is always the active pointer. + final int actionMasked = srcEvent.getActionMasked(); + if (actionMasked == MotionEvent.ACTION_DOWN) { + mActivePointerId = srcEvent.getPointerId(0); + } + + final int activePointerIndex = srcEvent.findPointerIndex(mActivePointerId); + if (activePointerIndex >= 0) { + final float x = srcEvent.getX(activePointerIndex); + final float y = srcEvent.getY(activePointerIndex); + if (!src.pointInView(x, y, mScaledTouchSlop)) { + // The pointer has moved outside of the view. + return true; + } + } + + return false; + } + + /** + * Handled forwarded motion events and determines when to stop + * forwarding. + * + * @param src view from which the event originated + * @param srcEvent motion event in source view coordinates + * @return true to continue forwarding motion events, false to cancel + */ + private boolean onTouchForwarded(View src, MotionEvent srcEvent) { + final ListPopupWindow popup = getPopup(); + if (popup == null || !popup.isShowing()) { + return false; + } + + final DropDownListView dst = popup.mDropDownList; + if (dst == null || !dst.isShown()) { + return false; + } + + // Convert event to destination-local coordinates. + final MotionEvent dstEvent = MotionEvent.obtainNoHistory(srcEvent); + src.toGlobalMotionEvent(dstEvent); + dst.toLocalMotionEvent(dstEvent); + + // Forward converted event to destination view, then recycle it. + final boolean handled = dst.onForwardedEvent(dstEvent, mActivePointerId); + dstEvent.recycle(); + return handled; + } + } + + /** * <p>Wrapper class for a ListView. This wrapper can hijack the focus to * make sure the list uses the appropriate drawables and states when * displayed on screen within a drop down. The focus is never actually diff --git a/core/java/android/widget/Spinner.java b/core/java/android/widget/Spinner.java index eec15a9..7c7df96 100644 --- a/core/java/android/widget/Spinner.java +++ b/core/java/android/widget/Spinner.java @@ -30,12 +30,14 @@ import android.os.Parcelable; import android.util.AttributeSet; import android.util.Log; import android.view.Gravity; +import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.view.ViewTreeObserver.OnGlobalLayoutListener; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; +import android.widget.ListPopupWindow.ForwardingListener; import android.widget.PopupWindow.OnDismissListener; @@ -76,7 +78,10 @@ public class Spinner extends AbsSpinner implements OnClickListener { * Use the theme-supplied value to select the dropdown mode. */ private static final int MODE_THEME = -1; - + + /** Forwarding listener used to implement drag-to-open. */ + private ForwardingListener mForwardingListener; + private SpinnerPopup mPopup; private DropDownAdapter mTempAdapter; int mDropDownWidth; @@ -173,7 +178,7 @@ public class Spinner extends AbsSpinner implements OnClickListener { } case MODE_DROPDOWN: { - DropdownPopup popup = new DropdownPopup(context, attrs, defStyle); + final DropdownPopup popup = new DropdownPopup(context, attrs, defStyle); mDropDownWidth = a.getLayoutDimension( com.android.internal.R.styleable.Spinner_dropDownWidth, @@ -193,6 +198,20 @@ public class Spinner extends AbsSpinner implements OnClickListener { } mPopup = popup; + mForwardingListener = new ForwardingListener(context) { + @Override + public ListPopupWindow getPopup() { + return popup; + } + + @Override + public boolean onForwardingStarted() { + if (!mPopup.isShowing()) { + mPopup.show(getTextDirection(), getTextAlignment()); + } + return true; + } + }; break; } } @@ -449,6 +468,15 @@ public class Spinner extends AbsSpinner implements OnClickListener { } @Override + public boolean onTouchEvent(MotionEvent event) { + if (mForwardingListener != null && mForwardingListener.onTouch(this, event)) { + return true; + } + + return super.onTouchEvent(event); + } + + @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); if (mPopup != null && MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.AT_MOST) { @@ -645,6 +673,10 @@ public class Spinner extends AbsSpinner implements OnClickListener { public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfo(info); info.setClassName(Spinner.class.getName()); + + if (mAdapter != null) { + info.setOpensPopup(true); + } } /** diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index a315546..d5fc21c 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -8173,6 +8173,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener info.addAction(AccessibilityNodeInfo.ACTION_CUT); } } + + if (!isSingleLine()) { + info.setMultiLine(true); + } } @Override diff --git a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java index 863d8cc..5d0a603 100644 --- a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java +++ b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java @@ -29,8 +29,11 @@ import android.view.SoundEffectConstants; import android.view.View; import android.view.ViewConfiguration; import android.view.View.MeasureSpec; +import android.view.accessibility.AccessibilityNodeInfo; import android.view.ViewGroup; import android.widget.ImageButton; +import android.widget.ListPopupWindow; +import android.widget.ListPopupWindow.ForwardingListener; import com.android.internal.view.ActionBarPolicy; import com.android.internal.view.menu.ActionMenuView.ActionMenuChildView; @@ -561,7 +564,36 @@ public class ActionMenuPresenter extends BaseMenuPresenter setFocusable(true); setVisibility(VISIBLE); setEnabled(true); - setOnTouchListener(new OverflowForwardListener(context)); + + setOnTouchListener(new ForwardingListener(context) { + @Override + public ListPopupWindow getPopup() { + if (mOverflowPopup == null) { + return null; + } + + return mOverflowPopup.getPopup(); + } + + @Override + public boolean onForwardingStarted() { + showOverflowMenu(); + return true; + } + + @Override + public boolean onForwardingStopped() { + // Displaying the popup occurs asynchronously, so wait for + // the runnable to finish before deciding whether to stop + // forwarding. + if (mPostedOpenRunnable != null) { + return false; + } + + hideOverflowMenu(); + return true; + } + }); } @Override @@ -594,6 +626,12 @@ public class ActionMenuPresenter extends BaseMenuPresenter } super.onMeasure(widthMeasureSpec, heightMeasureSpec); } + + @Override + public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { + super.onInitializeAccessibilityNodeInfo(info); + info.setOpensPopup(true); + } } private class OverflowPopup extends MenuPopupHelper { @@ -680,56 +718,4 @@ public class ActionMenuPresenter extends BaseMenuPresenter mPostedOpenRunnable = null; } } - - private class OverflowForwardListener extends TouchForwardingListener { - /** Scaled touch slop, used for detecting movement outside bounds. */ - private final float mScaledTouchSlop; - - private int mActivePointerId = MotionEvent.INVALID_POINTER_ID; - - public OverflowForwardListener(Context context) { - mScaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); - } - - @Override - public boolean onTouchObserved(View src, MotionEvent srcEvent) { - if (!src.isEnabled()) { - return false; - } - - // Always start forwarding events when the source view is touched. - mActivePointerId = srcEvent.getPointerId(0); - src.performClick(); - return true; - } - - @Override - public boolean onTouchForwarded(View src, MotionEvent srcEvent) { - final OverflowPopup popup = mOverflowPopup; - if (popup != null && popup.isShowing()) { - final int activePointerId = mActivePointerId; - if (activePointerId != MotionEvent.INVALID_POINTER_ID && src.isEnabled() - && popup.forwardMotionEvent(src, srcEvent, activePointerId)) { - // Handled the motion event, continue forwarding. - return true; - } - - final int activePointerIndex = srcEvent.findPointerIndex(activePointerId); - if (activePointerIndex >= 0) { - final float x = srcEvent.getX(activePointerIndex); - final float y = srcEvent.getY(activePointerIndex); - if (src.pointInView(x, y, mScaledTouchSlop)) { - // The user is touching the source view. Cancel - // forwarding, but don't dismiss the popup. - return false; - } - } - - popup.dismiss(); - } - - // Cancel forwarding. - return false; - } - } } diff --git a/core/java/com/android/internal/view/menu/ListMenuItemView.java b/core/java/com/android/internal/view/menu/ListMenuItemView.java index df579c6..85d9cbd 100644 --- a/core/java/com/android/internal/view/menu/ListMenuItemView.java +++ b/core/java/com/android/internal/view/menu/ListMenuItemView.java @@ -23,6 +23,7 @@ import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.view.accessibility.AccessibilityNodeInfo; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.ImageView; @@ -269,4 +270,13 @@ public class ListMenuItemView extends LinearLayout implements MenuView.ItemView } return mInflater; } + + @Override + public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { + super.onInitializeAccessibilityNodeInfo(info); + + if (mItemData != null && mItemData.hasSubMenu()) { + info.setOpensPopup(true); + } + } } diff --git a/core/java/com/android/internal/view/menu/MenuPopupHelper.java b/core/java/com/android/internal/view/menu/MenuPopupHelper.java index 9b266df..dbb78c2 100644 --- a/core/java/com/android/internal/view/menu/MenuPopupHelper.java +++ b/core/java/com/android/internal/view/menu/MenuPopupHelper.java @@ -108,6 +108,10 @@ public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.On } } + public ListPopupWindow getPopup() { + return mPopup; + } + public boolean tryShow() { mPopup = new ListPopupWindow(mContext, null, com.android.internal.R.attr.popupMenuStyle); mPopup.setOnDismissListener(this); @@ -159,22 +163,6 @@ public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.On return mPopup != null && mPopup.isShowing(); } - /** - * Forwards motion events from a source view to the popup window. - * - * @param src view from which the event was forwarded - * @param event forwarded motion event in source-local coordinates - * @param activePointerId id of the pointer that activated forwarding - * @return whether the event was handled - */ - public boolean forwardMotionEvent(View src, MotionEvent event, int activePointerId) { - if (mPopup == null || !mPopup.isShowing()) { - return false; - } - - return mPopup.onForwardedEvent(src, event, activePointerId); - } - @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { MenuAdapter adapter = mAdapter; diff --git a/core/java/com/android/internal/view/menu/TouchForwardingListener.java b/core/java/com/android/internal/view/menu/TouchForwardingListener.java deleted file mode 100644 index d1086de..0000000 --- a/core/java/com/android/internal/view/menu/TouchForwardingListener.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2013 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 com.android.internal.view.menu; - -import android.view.MotionEvent; -import android.view.View; - -/** - * Touch listener used to intercept touches and forward them out of a view. - */ -abstract class TouchForwardingListener implements View.OnTouchListener { - /** Whether this listener is currently forwarding touch events. */ - private boolean mForwarding; - - @Override - public boolean onTouch(View v, MotionEvent ev) { - final int actionMasked = ev.getActionMasked(); - - if (mForwarding) { - // Rejecting the event or ending the stream stops forwarding. - if (!onTouchForwarded(v, ev) || actionMasked == MotionEvent.ACTION_UP - || actionMasked == MotionEvent.ACTION_CANCEL) { - stopForwarding(); - } - } else { - if (onTouchObserved(v, ev)) { - startForwarding(); - } - } - - return mForwarding; - } - - public void startForwarding() { - mForwarding = true; - } - - public void stopForwarding() { - mForwarding = false; - } - - /** - * Attempts to start forwarding motion events. - * - * @param v The view that triggered forwarding. - * @return True to start forwarding motion events, or false to cancel. - */ - public abstract boolean onTouchObserved(View v, MotionEvent ev); - - /** - * Handles forwarded motion events. - * - * @param v The view from which the event was forwarded. - * @param ev The forwarded motion event. - * @return True to continue forwarding motion events, or false to cancel. - */ - public abstract boolean onTouchForwarded(View v, MotionEvent ev); -} diff --git a/core/java/com/android/server/net/BaseNetworkObserver.java b/core/java/com/android/server/net/BaseNetworkObserver.java index 8b2aa5d..fa54c5f 100644 --- a/core/java/com/android/server/net/BaseNetworkObserver.java +++ b/core/java/com/android/server/net/BaseNetworkObserver.java @@ -36,6 +36,16 @@ public class BaseNetworkObserver extends INetworkManagementEventObserver.Stub { } @Override + public void addressUpdated(String address, String iface, int flags, int scope) { + // default no-op + } + + @Override + public void addressRemoved(String address, String iface, int flags, int scope) { + // default no-op + } + + @Override public void interfaceLinkStateChanged(String iface, boolean up) { // default no-op } diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 33b77cc..2c8bb5d 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -108,6 +108,10 @@ <protected-broadcast android:name="android.bluetooth.device.action.PAIRING_REQUEST" /> <protected-broadcast android:name="android.bluetooth.device.action.PAIRING_CANCEL" /> <protected-broadcast android:name="android.bluetooth.device.action.CONNECTION_ACCESS_REPLY" /> + <protected-broadcast android:name="android.bluetooth.device.action.CONNECTION_ACCESS_CANCEL" /> + <protected-broadcast android:name="android.bluetooth.device.action.CONNECTION_ACCESS_REQUEST" /> + <protected-broadcast android:name="android.bluetooth.devicepicker.action.LAUNCH" /> + <protected-broadcast android:name="android.bluetooth.devicepicker.action.DEVICE_SELECTED" /> <protected-broadcast android:name="android.bluetooth.headset.profile.action.CONNECTION_STATE_CHANGED" /> <protected-broadcast @@ -121,7 +125,30 @@ <protected-broadcast android:name="android.bluetooth.input.profile.action.CONNECTION_STATE_CHANGED" /> <protected-broadcast + android:name="android.bluetooth.input.profile.action.PROTOCOL_MODE_CHANGED" /> + <protected-broadcast + android:name="android.bluetooth.input.profile.action.VIRTUAL_UNPLUG_STATUS" /> + <protected-broadcast android:name="android.bluetooth.pan.profile.action.CONNECTION_STATE_CHANGED" /> + <protected-broadcast android:name="android.bluetooth.pbap.intent.action.PBAP_STATE_CHANGED" /> + <protected-broadcast android:name="android.btopp.intent.action.INCOMING_FILE_NOTIFICATION" /> + <protected-broadcast android:name="android.btopp.intent.action.BT_OPP_HANDOVER_STARTED" /> + <protected-broadcast android:name="android.btopp.intent.action.TRANSFER_COMPLETE" /> + <protected-broadcast android:name="android.btopp.intent.action.USER_CONFIRMATION_TIMEOUT" /> + <protected-broadcast android:name="android.btopp.intent.action.BT_OPP_TRANSFER_PROGRESS" /> + <protected-broadcast android:name="android.btopp.intent.action.LIST" /> + <protected-broadcast android:name="android.btopp.intent.action.OPEN_OUTBOUND" /> + <protected-broadcast android:name="android.btopp.intent.action.HIDE_COMPLETE" /> + <protected-broadcast android:name="android.btopp.intent.action.CONFIRM" /> + <protected-broadcast android:name="android.btopp.intent.action.HIDE" /> + <protected-broadcast android:name="android.btopp.intent.action.BT_OPP_TRANSFER_DONE" /> + <protected-broadcast android:name="android.btopp.intent.action.RETRY" /> + <protected-broadcast android:name="android.btopp.intent.action.OPEN" /> + <protected-broadcast android:name="android.btopp.intent.action.OPEN_INBOUND" /> + <protected-broadcast android:name="com.android.bluetooth.pbap.authchall" /> + <protected-broadcast android:name="com.android.bluetooth.pbap.userconfirmtimeout" /> + <protected-broadcast android:name="com.android.bluetooth.pbap.authresponse" /> + <protected-broadcast android:name="com.android.bluetooth.pbap.authcancelled" /> <protected-broadcast android:name="android.hardware.display.action.WIFI_DISPLAY_STATUS_CHANGED" /> |
