summaryrefslogtreecommitdiffstats
path: root/policy
diff options
context:
space:
mode:
authorWill Haldean Brown <haldean@google.com>2014-02-12 10:23:41 -0800
committerWill Haldean Brown <haldean@google.com>2014-03-04 09:26:15 -0800
commitca6234e084a71e0c968cff404620298bcd971fcc (patch)
treebd5c5a5ba959637f34af9d70e97b5b60def2eb70 /policy
parenta4bd2cbe509911729c9f185b045e54d7528d8836 (diff)
downloadframeworks_base-ca6234e084a71e0c968cff404620298bcd971fcc.zip
frameworks_base-ca6234e084a71e0c968cff404620298bcd971fcc.tar.gz
frameworks_base-ca6234e084a71e0c968cff404620298bcd971fcc.tar.bz2
Add swipe-to-dismiss support to PhoneWindow.
This adds a new window feature -- FEATURE_SWIPE_TO_DISMISS -- and a theme attribute to activate that feature. When the feature is activated, a SwipeDismissLayout is inflated as the DecorView layout. SwipeDismissLayout intercepts touch events and steals ones that are large swipes to the right if its children don't. PhoneWindow registers handlers that listen for these swipe events, translate the window when necessary, and finish the activity at the end of the gesture. Change-Id: I512e758f3c3ffd3b353dba3b911c0e80a88d6f5f
Diffstat (limited to 'policy')
-rw-r--r--policy/src/com/android/internal/policy/impl/PhoneWindow.java69
1 files changed, 68 insertions, 1 deletions
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 44fc1f8..7c047c3 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -38,6 +38,7 @@ import com.android.internal.widget.ActionBarContainer;
import com.android.internal.widget.ActionBarContextView;
import com.android.internal.widget.ActionBarOverlayLayout;
import com.android.internal.widget.ActionBarView;
+import com.android.internal.widget.SwipeDismissLayout;
import android.app.KeyguardManager;
import android.content.Context;
@@ -267,6 +268,15 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
// Remove the action bar feature if we have no title. No title dominates.
removeFeature(FEATURE_ACTION_BAR);
}
+
+ if ((features & (1 << FEATURE_ACTION_BAR)) != 0 && featureId == FEATURE_SWIPE_TO_DISMISS) {
+ throw new AndroidRuntimeException(
+ "You cannot combine swipe dismissal and the action bar.");
+ }
+ if ((features & (1 << FEATURE_SWIPE_TO_DISMISS)) != 0 && featureId == FEATURE_ACTION_BAR) {
+ throw new AndroidRuntimeException(
+ "You cannot combine swipe dismissal and the action bar.");
+ }
return super.requestFeature(featureId);
}
@@ -2838,6 +2848,10 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
requestFeature(FEATURE_ACTION_MODE_OVERLAY);
}
+ if (a.getBoolean(com.android.internal.R.styleable.Window_windowSwipeToDismiss, false)) {
+ requestFeature(FEATURE_SWIPE_TO_DISMISS);
+ }
+
if (a.getBoolean(com.android.internal.R.styleable.Window_windowFullscreen, false)) {
setFlags(FLAG_FULLSCREEN, FLAG_FULLSCREEN & (~getForcedWindowFlags()));
}
@@ -2964,7 +2978,9 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
int layoutResource;
int features = getLocalFeatures();
// System.out.println("Features: 0x" + Integer.toHexString(features));
- if ((features & ((1 << FEATURE_LEFT_ICON) | (1 << FEATURE_RIGHT_ICON))) != 0) {
+ if ((features & (1 << FEATURE_SWIPE_TO_DISMISS)) != 0) {
+ layoutResource = com.android.internal.R.layout.screen_swipe_dismiss;
+ } else if ((features & ((1 << FEATURE_LEFT_ICON) | (1 << FEATURE_RIGHT_ICON))) != 0) {
if (mIsFloating) {
TypedValue res = new TypedValue();
getContext().getTheme().resolveAttribute(
@@ -3034,6 +3050,10 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
}
}
+ if ((features & (1 << FEATURE_SWIPE_TO_DISMISS)) != 0) {
+ registerSwipeCallbacks();
+ }
+
// Remaining setup -- of background and title -- that only applies
// to top-level windows.
if (getContainer() == null) {
@@ -3390,6 +3410,53 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
return (mRightIconView = (ImageView)findViewById(com.android.internal.R.id.right_icon));
}
+ private void registerSwipeCallbacks() {
+ SwipeDismissLayout swipeDismiss =
+ (SwipeDismissLayout) findViewById(com.android.internal.R.id.content);
+ swipeDismiss.setOnDismissedListener(new SwipeDismissLayout.OnDismissedListener() {
+ @Override
+ public void onDismissed(SwipeDismissLayout layout) {
+ Callback cb = getCallback();
+ if (cb != null) {
+ try {
+ cb.onWindowDismissed();
+ } catch (AbstractMethodError e) {
+ Log.e(TAG, "onWindowDismissed not implemented in " +
+ cb.getClass().getSimpleName(), e);
+ }
+ }
+ }
+ });
+ swipeDismiss.setOnSwipeProgressChangedListener(
+ new SwipeDismissLayout.OnSwipeProgressChangedListener() {
+ private boolean mIsTranslucent = false;
+
+ @Override
+ public void onSwipeProgressChanged(
+ SwipeDismissLayout layout, float progress, float translate) {
+ WindowManager.LayoutParams newParams = getAttributes();
+ newParams.x = (int) translate;
+ setAttributes(newParams);
+
+ int flags = 0;
+ if (newParams.x == 0) {
+ flags = FLAG_FULLSCREEN;
+ } else {
+ flags = FLAG_LAYOUT_NO_LIMITS;
+ }
+ setFlags(flags, FLAG_FULLSCREEN | FLAG_LAYOUT_NO_LIMITS);
+ }
+
+ @Override
+ public void onSwipeCancelled(SwipeDismissLayout layout) {
+ WindowManager.LayoutParams newParams = getAttributes();
+ newParams.x = 0;
+ setAttributes(newParams);
+ setFlags(FLAG_FULLSCREEN, FLAG_FULLSCREEN | FLAG_LAYOUT_NO_LIMITS);
+ }
+ });
+ }
+
/**
* Helper method for calling the {@link Callback#onPanelClosed(int, Menu)}
* callback. This method will grab whatever extra state is needed for the