Merge "Added tests for WebView accessibility no JS"
diff --git a/packages/SystemUI/res/drawable-mdpi/pocket_drag_pattern.png b/packages/SystemUI/res/drawable-mdpi/pocket_drag_pattern.png
new file mode 100644
index 0000000..abde010
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/pocket_drag_pattern.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/pocket_drag_bg.xml b/packages/SystemUI/res/drawable/pocket_drag_bg.xml
new file mode 100644
index 0000000..573a702
--- /dev/null
+++ b/packages/SystemUI/res/drawable/pocket_drag_bg.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<bitmap
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:tileMode="repeat"
+ android:src="@drawable/pocket_drag_pattern"
+ />
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar.xml b/packages/SystemUI/res/layout-xlarge/status_bar.xml
index 6c173c9..b97b9ca 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar.xml
@@ -91,6 +91,15 @@
</RelativeLayout>
</FrameLayout>
+ <view
+ class="com.android.systemui.statusbar.tablet.ShirtPocket$DropZone"
+ android:id="@+id/drop_target"
+ android:layout_width="512dp"
+ android:layout_height="@*android:dimen/status_bar_height"
+ android:background="@drawable/pocket_drag_bg"
+ android:layout_gravity="right"
+ />
+
<FrameLayout
android:id="@+id/bar_shadow_holder"
android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_notification_area.xml b/packages/SystemUI/res/layout-xlarge/status_bar_notification_area.xml
index 6e3b0d7..c25a51e 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar_notification_area.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_notification_area.xml
@@ -41,6 +41,15 @@
android:src="@drawable/ic_sysbar_ime_default"
android:visibility="gone"
/>
+
+ <com.android.systemui.statusbar.tablet.ShirtPocket
+ android:id="@+id/shirt_pocket"
+ android:layout_width="@*android:dimen/status_bar_height"
+ android:layout_height="@*android:dimen/status_bar_height"
+ android:background="#FFFF0000"
+ android:visibility="gone"
+ />
+
<com.android.systemui.statusbar.tablet.NotificationIconArea
android:id="@+id/notificationIcons"
android:layout_width="wrap_content"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java
index a67f915..ddb43b8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java
@@ -16,26 +16,28 @@
package com.android.systemui.statusbar.tablet;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
-import android.content.Context;
-import android.util.Slog;
-import android.view.View;
-import android.util.AttributeSet;
-import android.widget.ImageView;
-import android.widget.TextView;
-import android.view.DragEvent;
-import android.view.MotionEvent;
import android.content.ClipData;
import android.content.ClipDescription;
-import android.graphics.Paint;
+import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
-import android.graphics.Point;
-import android.view.WindowManager;
-import android.widget.FrameLayout;
-import android.view.WindowManagerImpl;
+import android.graphics.Paint;
import android.graphics.PixelFormat;
+import android.graphics.Point;
+import android.util.AttributeSet;
+import android.util.Slog;
+import android.view.DragEvent;
import android.view.Gravity;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.WindowManager;
+import android.view.WindowManagerImpl;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.TextView;
import com.android.systemui.R;
@@ -45,10 +47,80 @@
private ClipData mClipping = null;
- private View mWindow = null;
private ImageView mPreviewIcon;
- private TextView mDescription;
- private TextView mAltText;
+
+ public static class DropZone extends View {
+ ShirtPocket mPocket;
+ public DropZone(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+ public void setPocket(ShirtPocket p) {
+ mPocket = p;
+ }
+
+ public void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ if (mPocket.holding()) {
+ show(false);
+ } else {
+ hide(false);
+ }
+ }
+
+ // Drag API notes: we must be visible to receive drag events
+ private void show(boolean animate) {
+ setTranslationY(0f);
+ if (animate) {
+ setAlpha(0f);
+ ObjectAnimator.ofFloat(this, "alpha", 0f, 1f).start();
+ } else {
+ setAlpha(1f);
+ }
+ }
+
+ private void hide(boolean animate) {
+ AnimatorListenerAdapter onEnd = new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator _a) {
+ DropZone.this.setTranslationY(getHeight() + 2);
+ DropZone.this.setAlpha(0f);
+ }
+ };
+ if (animate) {
+ Animator a = ObjectAnimator.ofFloat(this, "alpha", getAlpha(), 0f);
+ a.addListener(onEnd);
+ a.start();
+ } else {
+ onEnd.onAnimationEnd(null);
+ }
+ }
+
+ @Override
+ public boolean onDragEvent(DragEvent event) {
+ if (DEBUG) Slog.d(TAG, "onDragEvent: " + event);
+ switch (event.getAction()) {
+ // We want to appear whenever a potential drag takes off from anywhere in the UI.
+ case DragEvent.ACTION_DRAG_STARTED:
+ show(true);
+ break;
+ case DragEvent.ACTION_DRAG_ENTERED:
+ if (DEBUG) Slog.d(TAG, "entered!");
+ // XXX: TODO
+ break;
+ case DragEvent.ACTION_DRAG_EXITED:
+ if (DEBUG) Slog.d(TAG, "exited!");
+ break;
+ case DragEvent.ACTION_DROP:
+ if (DEBUG) Slog.d(TAG, "dropped!");
+ mPocket.stash(event.getClipData());
+ break;
+ case DragEvent.ACTION_DRAG_ENDED:
+ hide(true);
+ break;
+ }
+ return true; // we want everything, thank you
+ }
+ }
public ShirtPocket(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -58,74 +130,66 @@
ObjectAnimator mAnimHide, mAnimShow;
protected void onAttachedToWindow() {
- // Drag API notes: we must be visible to receive drag events
- setVisibility(View.VISIBLE);
-
- refresh();
-
- setOnClickListener(new View.OnClickListener() {
- public void onClick(View v) {
- if (mClipping != null) {
- if (mWindow.getVisibility() == View.VISIBLE) hideWindow();
- else showWindow();
- }
- }
- });
}
- private void refresh() {
- setClickable(mClipping != null);
- // XXX: TODO
- }
-
- private void showWindow() {
- getHandler().post(new Runnable() {
- public void run() {
- mWindow.setVisibility(View.VISIBLE);
- refresh();
- }
- });
- }
-
- private void hideWindow() {
- getHandler().post(new Runnable() {
- public void run() {
- mWindow.setVisibility(View.GONE);
- refresh();
- }
- });
- }
-
- private void hideWindowInJustASec() {
- getHandler().postDelayed(new Runnable() {
- public void run() {
- mWindow.setVisibility(View.GONE);
- refresh();
- }
- },
- 250);
+ public boolean holding() {
+ return (mClipping != null);
}
private void stash(ClipData clipping) {
mClipping = clipping;
if (mClipping != null) {
+ setVisibility(View.VISIBLE);
Bitmap icon = mClipping.getIcon();
- mDescription.setText(mClipping.getDescription().getLabel());
+// mDescription.setText(mClipping.getDescription().getLabel());
if (icon != null) {
- mPreviewIcon.setImageBitmap(icon);
- mPreviewIcon.setVisibility(View.VISIBLE);
- mAltText.setVisibility(View.GONE);
+ setImageBitmap(icon);
} else {
- mPreviewIcon.setVisibility(View.GONE);
- mAltText.setVisibility(View.VISIBLE);
if (mClipping.getItemCount() > 0) {
// TODO: figure out how to visualize every kind of ClipData!
- mAltText.setText(mClipping.getItemAt(0).coerceToText(getContext()));
+ //mAltText.setText(mClipping.getItemAt(0).coerceToText(getContext()));
}
}
+ } else {
+ setVisibility(View.GONE);
}
}
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+ final int action = ev.getAction();
+ if (action == MotionEvent.ACTION_DOWN) {
+ final ClipData clip = mClipping;
+ if (clip != null) {
+ final Bitmap icon = clip.getIcon();
+ DragShadowBuilder shadow;
+ if (icon != null) {
+ shadow = new DragShadowBuilder(this) {
+ public void onProvideShadowMetrics(Point shadowSize, Point shadowTouchPoint) {
+ shadowSize.set(icon.getWidth(), icon.getHeight());
+ shadowTouchPoint.set(shadowSize.x / 2, shadowSize.y / 2);
+ }
+ public void onDrawShadow(Canvas canvas) {
+ canvas.drawBitmap(icon, 0, 0, new Paint());
+ }
+ };
+ } else {
+ // uhhh, what now?
+ shadow = new DragShadowBuilder(this);
+ }
+
+ startDrag(clip, shadow, null, 0);
+
+ // TODO: only discard the clipping if it was accepted
+ stash(null);
+
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /*
private boolean isInViewContentArea(View v, int x, int y) {
final int l = v.getPaddingLeft();
final int r = v.getWidth() - v.getPaddingRight();
@@ -167,38 +231,12 @@
// TODO: only discard the clipping if it was accepted
stash(null);
- hideWindowInJustASec(); // will refresh the icon
-
return true;
}
}
return false;
}
};
-
- public boolean onDragEvent(DragEvent event) {
- if (DEBUG) Slog.d(TAG, "onDragEvent: " + event);
- switch (event.getAction()) {
- // We want to appear whenever a potential drag takes off from anywhere in the UI.
- case DragEvent.ACTION_DRAG_STARTED:
- // XXX: TODO
- break;
- case DragEvent.ACTION_DRAG_ENTERED:
- if (DEBUG) Slog.d(TAG, "entered!");
- // XXX: TODO
- break;
- case DragEvent.ACTION_DRAG_EXITED:
- if (DEBUG) Slog.d(TAG, "exited!");
- setVisibility(mClipping == null ? View.GONE : View.VISIBLE);
- break;
- case DragEvent.ACTION_DROP:
- if (DEBUG) Slog.d(TAG, "dropped!");
- stash(event.getClipData());
- break;
- case DragEvent.ACTION_DRAG_ENDED:
- break;
- }
- return true; // we want everything, thank you
- }
+ */
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index 7a13fde..bb0d3e1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -392,6 +392,11 @@
// for redirecting errant bar taps to the IME
mFakeSpaceBar = sb.findViewById(R.id.fake_space_bar);
+ // drag and drop pocket
+ ShirtPocket p = (ShirtPocket) sb.findViewById(R.id.shirt_pocket);
+ ShirtPocket.DropZone z = (ShirtPocket.DropZone) sb.findViewById(R.id.drop_target);
+ z.setPocket(p);
+
// "shadows" of the status bar features, for lights-out mode
mShadow = sb.findViewById(R.id.bar_shadow);
mShadow.setOnTouchListener(