diff options
author | Jens Doll <jens.doll@gmail.com> | 2013-04-17 17:34:47 +0200 |
---|---|---|
committer | Danny Baumann <dannybaumann@web.de> | 2013-05-15 13:44:39 +0200 |
commit | d4bb3bc99c6ba13f7fd7738926aba3e6524d1419 (patch) | |
tree | 65f375f794536798443bfc205ab8b43dcfb6544e /packages/SystemUI/src | |
parent | 9f11bd11a1389bb98d54f6e6114028f4e39f90e1 (diff) | |
download | frameworks_base-d4bb3bc99c6ba13f7fd7738926aba3e6524d1419.zip frameworks_base-d4bb3bc99c6ba13f7fd7738926aba3e6524d1419.tar.gz frameworks_base-d4bb3bc99c6ba13f7fd7738926aba3e6524d1419.tar.bz2 |
Pie controls: A new way of activation
Based on "Pie controls: Introducing a pie delivery service" this
commit binds the pie controls to the newly created pie service.
Patch Set #2:
* Fixed glitch when displaying the search panel at the lock
screen.
Patch Set #5:
* Switch Position to com.android.internal.util.pie.Position
* Removed legacy and unused code
Patch Set #6:
* Fixed lock screen glitch, finally!
Patch Set #7:
* Rebase
Patch Set #9:
* Moved almost all of the pie logic to PieController
Patch Set #10:
* Remove window completely from WindowManager when not shown
Patch Set #13:
* Fixed Taichi's bug
* Removed observers in PieView
Patch Set #14 & #15:
* Rebase
Change-Id: I352f198068807694d95699618597d0927da3f324
Diffstat (limited to 'packages/SystemUI/src')
-rw-r--r-- | packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java | 309 | ||||
-rw-r--r-- | packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java | 18 | ||||
-rw-r--r-- | packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java | 17 | ||||
-rw-r--r-- | packages/SystemUI/src/com/android/systemui/statusbar/pie/PieItem.java | 20 | ||||
-rw-r--r-- | packages/SystemUI/src/com/android/systemui/statusbar/pie/PieSliceContainer.java | 24 | ||||
-rw-r--r-- | packages/SystemUI/src/com/android/systemui/statusbar/pie/PieSysInfo.java | 11 | ||||
-rw-r--r-- | packages/SystemUI/src/com/android/systemui/statusbar/pie/PieView.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/pie/PieLayout.java) | 90 | ||||
-rw-r--r-- | packages/SystemUI/src/com/android/systemui/statusbar/policy/PieController.java | 318 |
8 files changed, 272 insertions, 535 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index 7799ce9..bedc68d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -28,10 +28,8 @@ import com.android.systemui.SystemUI; import com.android.systemui.recent.RecentTasksLoader; import com.android.systemui.recent.RecentsActivity; import com.android.systemui.recent.TaskDescription; -import com.android.systemui.statusbar.pie.PieLayout; import com.android.systemui.statusbar.policy.NotificationRowLayout; import com.android.systemui.statusbar.policy.PieController; -import com.android.systemui.statusbar.policy.PieController.Position; import com.android.systemui.statusbar.tablet.StatusBarPanel; import android.app.ActivityManager; @@ -46,7 +44,6 @@ import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Configuration; @@ -54,7 +51,6 @@ import android.content.res.Resources; import android.database.ContentObserver; import android.graphics.Bitmap; import android.graphics.Paint; -import android.graphics.PixelFormat; import android.graphics.Rect; import android.net.Uri; import android.os.Build; @@ -65,6 +61,7 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.os.UserHandle; import android.provider.Settings; +import android.service.pie.PieManager; import android.text.TextUtils; import android.util.DisplayMetrics; import android.util.Log; @@ -92,7 +89,6 @@ public abstract class BaseStatusBar extends SystemUI implements CommandQueue.Callbacks { public static final String TAG = "StatusBar"; public static final boolean DEBUG = false; - public static final boolean DEBUG_INPUT = false; public static final boolean MULTIUSER_DEBUG = false; protected static final int MSG_TOGGLE_RECENTS_PANEL = 1020; @@ -134,7 +130,6 @@ public abstract class BaseStatusBar extends SystemUI implements protected FrameLayout mStatusBarContainer; - /** * An interface for navigation key bars to allow status bars to signal which keys are * currently of interest to the user.<br> @@ -162,95 +157,7 @@ public abstract class BaseStatusBar extends SystemUI implements new ArrayList<NavigationBarCallback>(); // Pie Control - protected int mExpandedDesktopState; protected PieController mPieController; - protected PieLayout mPieContainer; - private int mPieTriggerSlots; - private int mPieTriggerMask = Position.LEFT.FLAG - | Position.BOTTOM.FLAG - | Position.RIGHT.FLAG - | Position.TOP.FLAG; - private View[] mPieTrigger = new View[Position.values().length]; - private PieSettingsObserver mSettingsObserver; - - private View.OnTouchListener mPieTriggerOnTouchHandler = new View.OnTouchListener() { - @Override - public boolean onTouch(View v, MotionEvent event) { - final int action = event.getAction(); - final PieController.Tracker tracker = (PieController.Tracker)v.getTag(); - - if (tracker == null) { - if (DEBUG_INPUT) { - Slog.v(TAG, "Pie trigger onTouch: action: " + action + ", (" - + event.getAxisValue(MotionEvent.AXIS_X) + "," - + event.getAxisValue(MotionEvent.AXIS_Y) + ") position: NULL returning: false"); - } - return false; - } - - if (!mPieController.isShowing()) { - if (event.getPointerCount() > 1) { - if (DEBUG_INPUT) { - Slog.v(TAG, "Pie trigger onTouch: action: " + action - + ", (to many pointers) position: " + tracker.position.name() - + " returning: false"); - } - return false; - } - - switch (action) { - case MotionEvent.ACTION_DOWN: - tracker.start(event); - break; - case MotionEvent.ACTION_MOVE: - if (tracker.move(event)) { - if (DEBUG) { - Slog.v(TAG, "Pie control activated on: (" - + event.getAxisValue(MotionEvent.AXIS_X) + "," - + event.getAxisValue(MotionEvent.AXIS_Y) + ") with position: " - + tracker.position.name()); - } - if (tracker.position == Position.BOTTOM - && mPieController.isSearchLightEnabled()) { - // if we are at the bottom and nothing else is there, use a - // search light! - showSearchPanel(); - } else { - // set the snap points depending on current trigger and mask - mPieContainer.setSnapPoints(mPieTriggerMask & ~mPieTriggerSlots); - // send the activation to the controller - mPieController.activateFromTrigger(v, event, tracker.position); - // forward a spoofed ACTION_DOWN event - MotionEvent echo = event.copy(); - echo.setAction(MotionEvent.ACTION_DOWN); - return mPieContainer.onTouch(v, echo); - } - } - break; - default: - // whatever it was, we are giving up on this one - tracker.active = false; - break; - } - } else { - if (DEBUG_INPUT) { - Slog.v(TAG, "Pie trigger onTouch: action: " + action + ", (" - + event.getAxisValue(MotionEvent.AXIS_X) + "," - + event.getAxisValue(MotionEvent.AXIS_Y) - + ") position: " + tracker.position.name() + " delegating"); - } - return mPieContainer.onTouch(v, event); - } - if (DEBUG_INPUT) { - Slog.v(TAG, "Pie trigger onTouch: action: " + action + ", (" - + event.getAxisValue(MotionEvent.AXIS_X) + "," - + event.getAxisValue(MotionEvent.AXIS_Y) + ") position: " - + tracker.position.name() + " returning: " + tracker.active); - } - return tracker.active; - } - - }; // UI-specific methods @@ -411,11 +318,11 @@ public abstract class BaseStatusBar extends SystemUI implements } }, filter); - mSettingsObserver = new PieSettingsObserver(new Handler()); - - // this calls attachPie() implicitly - mSettingsObserver.onChange(true); - mSettingsObserver.observe(); + if (PieManager.getInstance().isPresent()) { + mPieController = new PieController(mContext); + mPieController.attachStatusBar(this); + addNavigationBarCallback(mPieController); + } } public void userSwitched(int newUserId) { @@ -803,30 +710,12 @@ public abstract class BaseStatusBar extends SystemUI implements if (DEBUG) Slog.d(TAG, "opening search panel"); if (mSearchPanelView != null) { mSearchPanelView.show(true, true); - - View bottom = mPieTrigger[Position.BOTTOM.INDEX]; - if (bottom != null) { - WindowManager.LayoutParams lp = - (android.view.WindowManager.LayoutParams) bottom.getLayoutParams(); - lp.flags &= ~WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; - lp.flags |= WindowManager.LayoutParams.FLAG_SLIPPERY; - mWindowManager.updateViewLayout(bottom, lp); - } } break; case MSG_CLOSE_SEARCH_PANEL: if (DEBUG) Slog.d(TAG, "closing search panel"); if (mSearchPanelView != null && mSearchPanelView.isShowing()) { mSearchPanelView.show(false, true); - - View bottom = mPieTrigger[Position.BOTTOM.INDEX]; - if (bottom != null) { - WindowManager.LayoutParams lp = - (android.view.WindowManager.LayoutParams) bottom.getLayoutParams(); - lp.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; - lp.flags &= ~WindowManager.LayoutParams.FLAG_SLIPPERY; - mWindowManager.updateViewLayout(bottom, lp); - } } break; } @@ -1304,6 +1193,16 @@ public abstract class BaseStatusBar extends SystemUI implements return km.inKeyguardRestrictedInputMode(); } + public int getExpandedDesktopMode() { + ContentResolver resolver = mContext.getContentResolver(); + boolean expanded = Settings.System.getInt(resolver, + Settings.System.EXPANDED_DESKTOP_STATE, 0) == 1; + if (expanded) { + return Settings.System.getInt(resolver, Settings.System.EXPANDED_DESKTOP_STYLE, 0); + } + return 0; + } + public void addNavigationBarCallback(NavigationBarCallback callback) { mNavigationCallbacks.add(callback); } @@ -1328,181 +1227,9 @@ public abstract class BaseStatusBar extends SystemUI implements // Pie Controls - @Override - protected void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - - if (DEBUG) Slog.d(TAG, "Configuration changed! Update pie triggers"); - - attachPie(); - } - - private final class PieSettingsObserver extends ContentObserver { - PieSettingsObserver(Handler handler) { - super(handler); - } - - void observe() { - ContentResolver resolver = mContext.getContentResolver(); - resolver.registerContentObserver(Settings.System.getUriFor( - Settings.System.PIE_CONTROLS), false, this); - resolver.registerContentObserver(Settings.System.getUriFor( - Settings.System.PIE_POSITIONS), false, this); - resolver.registerContentObserver(Settings.System.getUriFor( - Settings.System.EXPANDED_DESKTOP_STATE), false, this); - resolver.registerContentObserver(Settings.System.getUriFor( - Settings.System.EXPANDED_DESKTOP_STYLE), false, this); - } - - @Override - public void onChange(boolean selfChange) { - ContentResolver resolver = mContext.getContentResolver(); - - mPieTriggerSlots = Settings.System.getInt(resolver, - Settings.System.PIE_POSITIONS, Position.BOTTOM.FLAG); - - boolean expanded = Settings.System.getInt(resolver, - Settings.System.EXPANDED_DESKTOP_STATE, 0) == 1; - if (expanded) { - mExpandedDesktopState = Settings.System.getInt(resolver, - Settings.System.EXPANDED_DESKTOP_STYLE, 0); - } else { - mExpandedDesktopState = 0; - } - - attachPie(); - } - } - - private boolean isPieEnabled() { - int pie = Settings.System.getInt(mContext.getContentResolver(), - Settings.System.PIE_CONTROLS, 0); - - return (pie == 1 && mExpandedDesktopState != 0) || pie == 2; - } - - private void attachPie() { - if (isPieEnabled()) { - - // Create our container, if it does not exist already - if (mPieContainer == null) { - mPieContainer = new PieLayout(mContext); - WindowManager.LayoutParams lp = new WindowManager.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT, - WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL, - WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN - | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL - | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE - | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON - | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, - PixelFormat.TRANSLUCENT); - // This title is for debugging only. See: dumpsys window - lp.setTitle("PieControlPanel"); - lp.windowAnimations = android.R.style.Animation; - lp.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_BEHIND; - - mWindowManager.addView(mPieContainer, lp); - // once we need a pie controller, we create one and keep it forever ... - if (mPieController == null) { - mPieController = new PieController(mContext); - mPieController.attachStatusBar(this); - addNavigationBarCallback(mPieController); - } - mPieController.attachContainer(mPieContainer); - } - - // add or update pie triggers - if (DEBUG) { - Slog.d(TAG, "AttachPie with trigger position flags: " - + mPieTriggerSlots + " masked: " + (mPieTriggerSlots & mPieTriggerMask)); - } - - refreshPieTriggers(); - - } else { - for (int i = 0; i < mPieTrigger.length; i++) { - if (mPieTrigger[i] != null) { - mWindowManager.removeView(mPieTrigger[i]); - mPieTrigger[i] = null; - } - } - // detach from the pie container and unregister observers and receivers - if (mPieController != null) { - mPieController.detachContainer(); - mPieContainer = null; - } - } - } - public void updatePieTriggerMask(int newMask) { - int oldState = mPieTriggerSlots & mPieTriggerMask; - mPieTriggerMask = newMask; - - // first we check, if it would make a change - if ((mPieTriggerSlots & mPieTriggerMask) != oldState) { - if (isPieEnabled()) { - refreshPieTriggers(); - } - } - } - - // This should only be called, when is is clear that the pie controls are active - private void refreshPieTriggers() { - for (Position g : Position.values()) { - View trigger = mPieTrigger[g.INDEX]; - if (trigger == null && (mPieTriggerSlots & mPieTriggerMask & g.FLAG) != 0) { - trigger = new View(mContext); - trigger.setClickable(false); - trigger.setLongClickable(false); - trigger.setTag(mPieController.buildTracker(g)); - trigger.setOnTouchListener(mPieTriggerOnTouchHandler); - - if (DEBUG) { - trigger.setVisibility(View.VISIBLE); - trigger.setBackgroundColor(0x77ff0000); - Slog.d(TAG, "addPieTrigger on " + g.INDEX - + " with position: " + g + " : " + trigger.toString()); - } - mWindowManager.addView(trigger, getPieTriggerLayoutParams(g)); - mPieTrigger[g.INDEX] = trigger; - } else if (trigger != null && (mPieTriggerSlots & mPieTriggerMask & g.FLAG) == 0) { - mWindowManager.removeView(trigger); - mPieTrigger[g.INDEX] = null; - } else if (trigger != null) { - mWindowManager.updateViewLayout(trigger, getPieTriggerLayoutParams(g)); - } + if (mPieController != null) { + mPieController.updatePieTriggerMask(newMask); } } - - private WindowManager.LayoutParams getPieTriggerLayoutParams(Position position) { - final Resources res = mContext.getResources(); - - int width = (int) (res.getDisplayMetrics().widthPixels * 0.8f); - int height = (int) (res.getDisplayMetrics().heightPixels * 0.8f); - int triggerThickness = (int) (res.getDimensionPixelSize(R.dimen.pie_trigger_height)); - WindowManager.LayoutParams lp = new WindowManager.LayoutParams( - (position == Position.TOP || position == Position.BOTTOM - ? width : triggerThickness), - (position == Position.LEFT || position == Position.RIGHT - ? height : triggerThickness), - WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL, - WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL - | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE - | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH - /* | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM */, - PixelFormat.TRANSLUCENT); - // This title is for debugging only. See: dumpsys window - lp.setTitle("PieTrigger" + position.name()); - if (position == Position.LEFT || position == Position.RIGHT) { - lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED - | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; - } else { - lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED - | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING; - } - lp.gravity = position.ANDROID_GRAVITY; - return lp; - } - } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index b3c1f07..befa422 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -88,6 +88,7 @@ import android.widget.TextView; import com.android.internal.statusbar.StatusBarIcon; import com.android.internal.statusbar.StatusBarNotification; +import com.android.internal.util.pie.PiePosition; import com.android.systemui.R; import com.android.systemui.statusbar.BaseStatusBar; import com.android.systemui.statusbar.CommandQueue; @@ -106,7 +107,6 @@ import com.android.systemui.statusbar.policy.NetworkController; import com.android.systemui.statusbar.policy.NotificationRowLayout; import com.android.systemui.statusbar.policy.OnSizeChangedListener; import com.android.systemui.statusbar.policy.Prefs; -import com.android.systemui.statusbar.policy.PieController.Position; import com.android.systemui.statusbar.powerwidget.PowerWidget; public class PhoneStatusBar extends BaseStatusBar { @@ -1598,7 +1598,7 @@ public class PhoneStatusBar extends BaseStatusBar { } // don't allow expanding via e.g. service call while status bar is hidden // due to expanded desktop - if (mExpandedDesktopState == 2) { + if (getExpandedDesktopMode() == 2) { return; } @@ -1670,7 +1670,7 @@ public class PhoneStatusBar extends BaseStatusBar { } // don't allow expanding via e.g. service call while status bar is hidden // due to expanded desktop - if (mExpandedDesktopState == 2) { + if (getExpandedDesktopMode() == 2) { return; } @@ -2238,13 +2238,13 @@ public class PhoneStatusBar extends BaseStatusBar { // hide pie triggers when keyguard is visible try { if (mWindowManagerService.isKeyguardLocked()) { - updatePieTriggerMask(Position.BOTTOM.FLAG - | Position.TOP.FLAG); + updatePieTriggerMask(PiePosition.BOTTOM.FLAG + | PiePosition.TOP.FLAG); } else { - updatePieTriggerMask(Position.LEFT.FLAG - | Position.BOTTOM.FLAG - | Position.RIGHT.FLAG - | Position.TOP.FLAG); + updatePieTriggerMask(PiePosition.LEFT.FLAG + | PiePosition.BOTTOM.FLAG + | PiePosition.RIGHT.FLAG + | PiePosition.TOP.FLAG); } } catch (RemoteException e) { // nothing else to do ... diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java index 1e94e97..f5fff53 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java @@ -26,8 +26,9 @@ import android.util.Slog; import android.view.MotionEvent; import android.view.View; import android.view.accessibility.AccessibilityEvent; + +import com.android.internal.util.pie.PiePosition; import com.android.systemui.R; -import com.android.systemui.statusbar.policy.PieController.Position; public class PhoneStatusBarView extends PanelBar { private static final String TAG = "PhoneStatusBarView"; @@ -167,10 +168,10 @@ public class PhoneStatusBarView extends PanelBar { mLastFullyOpenedPanel = null; // show up you pie controls - mBar.updatePieTriggerMask(Position.LEFT.FLAG - | Position.TOP.FLAG - | Position.RIGHT.FLAG - | Position.TOP.FLAG); + mBar.updatePieTriggerMask(PiePosition.LEFT.FLAG + | PiePosition.TOP.FLAG + | PiePosition.RIGHT.FLAG + | PiePosition.TOP.FLAG); } @Override @@ -182,9 +183,9 @@ public class PhoneStatusBarView extends PanelBar { // back off you pie controls! if (mShouldFade) { - mBar.updatePieTriggerMask(Position.LEFT.FLAG - | Position.RIGHT.FLAG - | Position.TOP.FLAG); + mBar.updatePieTriggerMask(PiePosition.LEFT.FLAG + | PiePosition.RIGHT.FLAG + | PiePosition.TOP.FLAG); } mFadingPanel = openPanel; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pie/PieItem.java b/packages/SystemUI/src/com/android/systemui/statusbar/pie/PieItem.java index 6b64008..ce41278 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pie/PieItem.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pie/PieItem.java @@ -28,9 +28,9 @@ import android.graphics.PorterDuff.Mode; import android.view.View; import android.widget.ImageView; +import com.android.internal.util.pie.PiePosition; import com.android.systemui.R; -import com.android.systemui.statusbar.pie.PieLayout.PieDrawable; -import com.android.systemui.statusbar.policy.PieController.Position; +import com.android.systemui.statusbar.pie.PieView.PieDrawable; /** * A clickable pie menu item. @@ -38,9 +38,9 @@ import com.android.systemui.statusbar.policy.PieController.Position; * This is the actual end point for user interaction.<br> * ( == This is what a user clicks on.) */ -public class PieItem extends PieLayout.PieDrawable { +public class PieItem extends PieView.PieDrawable { - private PieLayout mPieLayout; + private PieView mPieLayout; private Paint mBackgroundPaint = new Paint(); private Paint mSelectedPaint = new Paint(); @@ -87,7 +87,7 @@ public class PieItem extends PieLayout.PieDrawable { */ public final static int CAN_LONG_PRESS = 0x400; - public PieItem(Context context, PieLayout parent, int flags, int width, Object tag, View view) { + public PieItem(Context context, PieView parent, int flags, int width, Object tag, View view) { mView = view; mPieLayout = parent; this.tag = tag; @@ -129,9 +129,9 @@ public class PieItem extends PieLayout.PieDrawable { public void show(boolean show) { if (show) { - flags |= PieLayout.PieDrawable.VISIBLE; + flags |= PieView.PieDrawable.VISIBLE; } else { - flags &= ~PieLayout.PieDrawable.VISIBLE; + flags &= ~PieView.PieDrawable.VISIBLE; } } @@ -168,7 +168,7 @@ public class PieItem extends PieLayout.PieDrawable { } @Override - public void prepare(Position position, float scale) { + public void prepare(PiePosition position, float scale) { mPath = getOutline(scale); if (mView != null) { mView.measure(mView.getLayoutParams().width, mView.getLayoutParams().height); @@ -188,7 +188,7 @@ public class PieItem extends PieLayout.PieDrawable { } @Override - public void draw(Canvas canvas, Position position) { + public void draw(Canvas canvas, PiePosition position) { if ((flags & SELECTED) != 0) { Paint paint = (flags & LONG_PRESSED) == 0 ? mSelectedPaint : mLongPressPaint; @@ -202,7 +202,7 @@ public class PieItem extends PieLayout.PieDrawable { int state = canvas.save(); canvas.translate(mView.getLeft(), mView.getTop()); // keep icons "upright" if we get displayed on TOP position - if (position != Position.TOP) { + if (position != PiePosition.TOP) { canvas.rotate(mStart + mSweep / 2 - 270); } else { canvas.rotate(mStart + mSweep / 2 - 90); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pie/PieSliceContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/pie/PieSliceContainer.java index c3a277a..90882e4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pie/PieSliceContainer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pie/PieSliceContainer.java @@ -18,8 +18,8 @@ package com.android.systemui.statusbar.pie; import android.graphics.Canvas; import android.util.Slog; -import com.android.systemui.statusbar.pie.PieLayout.PieDrawable; -import com.android.systemui.statusbar.policy.PieController.Position; +import com.android.internal.util.pie.PiePosition; +import com.android.systemui.statusbar.pie.PieView.PieDrawable; import java.util.ArrayList; import java.util.List; @@ -27,19 +27,19 @@ import java.util.List; /** * A generic container for {@link PieItems}. */ -public class PieSliceContainer extends PieLayout.PieSlice { +public class PieSliceContainer extends PieView.PieSlice { - protected PieLayout mPieLayout; + protected PieView mPieLayout; private List<PieItem> mItems = new ArrayList<PieItem>(); - public PieSliceContainer(PieLayout parent, int initialFlags) { + public PieSliceContainer(PieView parent, int initialFlags) { mPieLayout = parent; - flags = initialFlags | PieLayout.PieDrawable.VISIBLE; + flags = initialFlags | PieView.PieDrawable.VISIBLE; } @Override - public void prepare(Position position, float scale) { + public void prepare(PiePosition position, float scale) { if (hasItems()) { int totalWidth = 0; for (PieItem item : mItems) { @@ -55,11 +55,11 @@ public class PieSliceContainer extends PieLayout.PieSlice { float gapMinder = ((totalWidth * GAP * 2.0f) / (mOuter + mInner)); float deltaSweep = mSweep / totalWidth; - int width = position != Position.TOP ? 0 : totalWidth; + int width = position != PiePosition.TOP ? 0 : totalWidth; int viewMask = PieDrawable.VISIBLE | position.FLAG; - boolean top = position == Position.TOP; + boolean top = position == PiePosition.TOP; for (PieItem item : mItems) { if ((item.flags & viewMask) == viewMask) { if (top) width -= item.width; @@ -68,8 +68,8 @@ public class PieSliceContainer extends PieLayout.PieSlice { item.width * deltaSweep, mInner, mOuter); item.setGap(deltaSweep * gapMinder); - if (PieLayout.DEBUG) { - Slog.d(PieLayout.TAG, "Layout " + item.tag + " : (" + if (PieView.DEBUG) { + Slog.d(PieView.TAG, "Layout " + item.tag + " : (" + (mStart + deltaSweep * width) + "," + (item.width * deltaSweep) + ")"); } @@ -81,7 +81,7 @@ public class PieSliceContainer extends PieLayout.PieSlice { } @Override - public void draw(Canvas canvas, Position gravity) { + public void draw(Canvas canvas, PiePosition gravity) { } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pie/PieSysInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/pie/PieSysInfo.java index 547a0a6..d5085da 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pie/PieSysInfo.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pie/PieSysInfo.java @@ -30,10 +30,9 @@ import android.net.wifi.WifiSsid; import android.text.TextUtils; import android.text.format.DateFormat; +import com.android.internal.util.pie.PiePosition; import com.android.systemui.R; -import com.android.systemui.statusbar.pie.PieLayout.PieDrawable; import com.android.systemui.statusbar.policy.PieController; -import com.android.systemui.statusbar.policy.PieController.Position; import java.text.SimpleDateFormat; import java.util.Date; @@ -66,7 +65,7 @@ public class PieSysInfo extends PieSliceContainer implements ValueAnimator.Anima private String mTimeFormatString; private SimpleDateFormat mTimeFormat; - public PieSysInfo(Context context, PieLayout parent, + public PieSysInfo(Context context, PieView parent, PieController controller, int initialFlags) { super(parent, initialFlags); mController = controller; @@ -84,7 +83,7 @@ public class PieSysInfo extends PieSliceContainer implements ValueAnimator.Anima } @Override - public void prepare(Position position, float scale) { + public void prepare(PiePosition position, float scale) { // We are updating data later when we starting to get visible. // This does not save work on the main thread, but for fast gestures @@ -97,8 +96,6 @@ public class PieSysInfo extends PieSliceContainer implements ValueAnimator.Anima mInfoPaint.setAlpha(0); final Resources res = mContext.getResources(); - final RectF innerBB = new RectF(-mInner * scale, -mInner * scale, - mInner * scale, mInner * scale); int textsize = res.getDimensionPixelSize(R.dimen.pie_textsize); mInfoPaint.setTextSize(textsize * scale); @@ -120,7 +117,7 @@ public class PieSysInfo extends PieSliceContainer implements ValueAnimator.Anima } @Override - public void draw(Canvas canvas, Position position) { + public void draw(Canvas canvas, PiePosition position) { // as long as there is no new data, we don't need to draw anything. if (mStaleData) { return; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pie/PieLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/pie/PieView.java index c828dea..c850722 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pie/PieLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pie/PieView.java @@ -31,9 +31,8 @@ import android.util.Slog; import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; -import android.widget.FrameLayout; -import com.android.systemui.statusbar.policy.PieController.Position; +import com.android.internal.util.pie.PiePosition; import com.android.systemui.R; import java.util.ArrayList; @@ -46,7 +45,7 @@ import java.util.List; * processing the input events from the user.<br> * (It handles the events for the snap points, too.) */ -public class PieLayout extends FrameLayout implements View.OnTouchListener { +public class PieView extends View implements View.OnTouchListener { public static final String TAG = "PieLayout"; public static final boolean DEBUG = false; public static final boolean DEBUG_INPUT = false; @@ -55,9 +54,6 @@ public class PieLayout extends FrameLayout implements View.OnTouchListener { private long mActivateStartDebug = 0; private static final int TIME_FADEIN = 300; - private static final int TIME_FADEIN_DELAY = 400; - - private static final int COLOR_BACKGROUND = 0xee000000; private Paint mBackgroundPaint = new Paint(); private float mBackgroundFraction; @@ -76,8 +72,8 @@ public class PieLayout extends FrameLayout implements View.OnTouchListener { private boolean mActive = false; private int mPointerId; private Point mCenter = new Point(0, 0); - private Position mPosition = Position.BOTTOM; - private Position mLayoutDoneForPosition; + private PiePosition mPosition = PiePosition.BOTTOM; + private PiePosition mLayoutDoneForPosition; private Handler mHandler; private Runnable mLongPressRunnable = new Runnable() { @@ -109,7 +105,7 @@ public class PieLayout extends FrameLayout implements View.OnTouchListener { } // animation updates occur on the main thread. it is save to call invalidate here. - PieLayout.this.invalidate(); + PieView.this.invalidate(); } }; @@ -119,8 +115,8 @@ public class PieLayout extends FrameLayout implements View.OnTouchListener { * <p> * This defines the basic geometry of a pie thing and provides the * interface to trigger positioning and draw preparations - * ({@link #prepare(Position, float)}), drawing - * ({@link #draw(Canvas, Position)}) as well as user interaction + * ({@link #prepare(PiePosition, float)}), drawing + * ({@link #draw(Canvas, PiePosition)}) as well as user interaction * ({@link #interact(float, int)}). */ public abstract static class PieDrawable { @@ -129,9 +125,9 @@ public class PieLayout extends FrameLayout implements View.OnTouchListener { protected int mInner; protected int mOuter; - abstract public void prepare(Position position, float scale); + abstract public void prepare(PiePosition position, float scale); - abstract public void draw(Canvas canvas, Position position); + abstract public void draw(Canvas canvas, PiePosition position); abstract public PieItem interact(float alpha, int radius); @@ -143,14 +139,14 @@ public class PieLayout extends FrameLayout implements View.OnTouchListener { } // Display on all positions - public final static int DISPLAY_ALL = Position.LEFT.FLAG - | Position.BOTTOM.FLAG - | Position.RIGHT.FLAG - | Position.TOP.FLAG; + public final static int DISPLAY_ALL = PiePosition.LEFT.FLAG + | PiePosition.BOTTOM.FLAG + | PiePosition.RIGHT.FLAG + | PiePosition.TOP.FLAG; // Display on all except the TOP position - public final static int DISPLAY_NOT_AT_TOP = Position.LEFT.FLAG - | Position.BOTTOM.FLAG - | Position.RIGHT.FLAG; + public final static int DISPLAY_NOT_AT_TOP = PiePosition.LEFT.FLAG + | PiePosition.BOTTOM.FLAG + | PiePosition.RIGHT.FLAG; // The PieDrawable is visible, note that slice visibility overrides item visibility public final static int VISIBLE = 0x10; @@ -168,7 +164,7 @@ public class PieLayout extends FrameLayout implements View.OnTouchListener { public final static float GAP = 3.0f; /** - * The slice will be considerer as important - {@link PieLayout} will try to keep + * The slice will be considerer as important - {@link PieView} will try to keep * these slices on screen, when placing the pie control. * @see PieDrawable#flags */ @@ -191,7 +187,7 @@ public class PieLayout extends FrameLayout implements View.OnTouchListener { private int mY; private float mActivity; - public SnapPoint(int x, int y, Position gravity) { + public SnapPoint(int x, int y, PiePosition gravity) { mX = x; mY = y; mActivity = 0.0f; @@ -219,7 +215,7 @@ public class PieLayout extends FrameLayout implements View.OnTouchListener { public boolean interact(float x, float y) { float distanceSqr = (x - mX) * (x - mX) + (y - mY) * (y - mY); if (distanceSqr - mSnapRadiusSqr < mSnapThresholdSqr) { - PieLayout.this.invalidate(); + PieView.this.invalidate(); if (distanceSqr < mSnapRadiusSqr) { if (DEBUG) { @@ -236,29 +232,34 @@ public class PieLayout extends FrameLayout implements View.OnTouchListener { return false; } - public final Position position; + public final PiePosition position; } private int mSnapPointMask = 0; - private SnapPoint[] mSnapPoints = new SnapPoint[Position.values().length]; + private SnapPoint[] mSnapPoints = new SnapPoint[PiePosition.values().length]; private SnapPoint mActiveSnap = null; /** * Listener interface for snap events on {@link SnapPoint}s. */ public interface OnSnapListener { - void onSnap(Position position); + void onSnap(PiePosition position); } private OnSnapListener mOnSnapListener = null; - public PieLayout(Context context) { + public interface OnExitListener { + void onExit(); + } + private OnExitListener mOnExitListener = null; + + public PieView(Context context) { super(context); mHandler = new Handler(); mBackgroundAnimator.addUpdateListener(mUpdateListener); setDrawingCacheEnabled(false); - setVisibility(View.GONE); + setVisibility(View.VISIBLE); setWillNotDraw(false); setFocusable(true); setOnTouchListener(this); @@ -271,6 +272,10 @@ public class PieLayout extends FrameLayout implements View.OnTouchListener { mOnSnapListener = onSnapListener; } + public void setOnExitListener(OnExitListener onExitListener) { + mOnExitListener = onExitListener; + } + /** * Tells the Layout where to show snap points. * @param mask is a mask that corresponds to {@link Position}{@code .FLAG}. @@ -310,11 +315,11 @@ public class PieLayout extends FrameLayout implements View.OnTouchListener { private void setupSnapPoints(int width, int height) { mActiveSnap = null; // reuse already created snap points - for (Position g : Position.values()) { - if ((mSnapPointMask & g.FLAG) != 0) { + for (PiePosition g : PiePosition.values()) { + if ((mSnapPointMask & g.FLAG) == 0) { int x = width / 2; int y = height / 2; - if (g == Position.LEFT || g == Position.RIGHT) { + if (g == PiePosition.LEFT || g == PiePosition.RIGHT) { x = g.FACTOR * width; } else { y = g.FACTOR * height; @@ -447,11 +452,11 @@ public class PieLayout extends FrameLayout implements View.OnTouchListener { mActiveItem.onClickCall(mLongPressed); } } - PieLayout.this.exit(); + PieView.this.exit(); } if (action == MotionEvent.ACTION_CANCEL) { - PieLayout.this.exit(); + PieView.this.exit(); } } return true; @@ -533,7 +538,7 @@ public class PieLayout extends FrameLayout implements View.OnTouchListener { } estimatedWidth = estimatedWidth * mPieScale; - if (mPosition == Position.LEFT || mPosition == Position.RIGHT) { + if (mPosition == PiePosition.LEFT || mPosition == PiePosition.RIGHT) { mCenter.x = mPadding + (int) ((getWidth() - 2 * mPadding) * mPosition.FACTOR); if (estimatedWidth * 1.3f > getHeight()) { mCenter.y = getHeight() / 2; @@ -565,7 +570,7 @@ public class PieLayout extends FrameLayout implements View.OnTouchListener { getDimensions(); } - public void activate(Point center, Position position) { + public void activate(Point center, PiePosition position) { if (Looper.myLooper() != Looper.getMainLooper()) { Slog.w(TAG, "Activation not on main thread: " + Thread.currentThread().getName()); } @@ -573,7 +578,6 @@ public class PieLayout extends FrameLayout implements View.OnTouchListener { mActivateStartDebug = SystemClock.uptimeMillis(); getDimensions(); - mPosition = position; mLayoutDoneForPosition = null; mActive = true; @@ -593,15 +597,18 @@ public class PieLayout extends FrameLayout implements View.OnTouchListener { mBackgroundAnimator.setStartDelay(ViewConfiguration.getLongPressTimeout() * 2); mBackgroundAnimator.start(); - setVisibility(View.VISIBLE); - - Slog.d(TAG, "activate finished within " + (SystemClock.uptimeMillis() - mActivateStartDebug) + " ms"); } public void exit() { - setVisibility(View.GONE); + if (DEBUG) { + Slog.d(TAG, "Exiting pie now"); + } + // if exit was called before, just ignore this one. + if (!mActive) { + return; + } mBackgroundAnimator.cancel(); mActiveSnap = null; @@ -614,6 +621,9 @@ public class PieLayout extends FrameLayout implements View.OnTouchListener { updateActiveItem(null, false); mActive = false; + if (mOnExitListener != null) { + mOnExitListener.onExit(); + } } public void clearSlices() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/PieController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/PieController.java index 7bc4588..d26ef8a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/PieController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/PieController.java @@ -16,10 +16,7 @@ */ package com.android.systemui.statusbar.policy; -import android.app.ActivityManager.RunningAppProcessInfo; -import android.app.ActivityManagerNative; import android.app.ActivityOptions; -import android.app.IActivityManager; import android.app.SearchManager; import android.app.StatusBarManager; import android.content.ActivityNotFoundException; @@ -28,15 +25,17 @@ import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; import android.content.res.Resources; import android.database.ContentObserver; +import android.graphics.PixelFormat; import android.graphics.Point; import android.graphics.drawable.Drawable; import android.hardware.input.InputManager; import android.os.BatteryManager; import android.os.Handler; +import android.os.Looper; import android.os.Message; import android.os.RemoteException; import android.os.ServiceManager; @@ -44,6 +43,7 @@ import android.os.SystemClock; import android.os.UserHandle; import android.os.Vibrator; import android.provider.Settings; +import android.service.pie.PieManager; import android.telephony.PhoneStateListener; import android.telephony.ServiceState; import android.telephony.TelephonyManager; @@ -53,36 +53,35 @@ import android.view.IWindowManager; import android.view.InputDevice; import android.view.KeyCharacterMap; import android.view.KeyEvent; -import android.view.MotionEvent; import android.view.SoundEffectConstants; import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; import android.view.ViewGroup.LayoutParams; -import android.view.accessibility.AccessibilityEvent; import android.widget.ImageView; import android.widget.Toast; import com.android.internal.util.cm.DevUtils; +import com.android.internal.util.pie.PiePosition; import com.android.systemui.R; import com.android.systemui.statusbar.BaseStatusBar; import com.android.systemui.statusbar.NavigationButtons; import com.android.systemui.statusbar.NavigationButtons.ButtonInfo; import com.android.systemui.statusbar.pie.PieItem; -import com.android.systemui.statusbar.pie.PieLayout; -import com.android.systemui.statusbar.pie.PieLayout.PieDrawable; -import com.android.systemui.statusbar.pie.PieLayout.PieSlice; +import com.android.systemui.statusbar.pie.PieView; +import com.android.systemui.statusbar.pie.PieView.PieDrawable; +import com.android.systemui.statusbar.pie.PieView.PieSlice; import com.android.systemui.statusbar.pie.PieSliceContainer; import com.android.systemui.statusbar.pie.PieSysInfo; -import java.util.List; - /** * Controller class for the default pie control. * <p> * This class is responsible for setting up the pie control, activating it, and defining and * executing the actions that can be triggered by the pie control. */ -public class PieController implements BaseStatusBar.NavigationBarCallback, - PieLayout.OnSnapListener, PieItem.PieOnClickListener, PieItem.PieOnLongClickListener { +public class PieController implements BaseStatusBar.NavigationBarCallback, PieView.OnExitListener, + PieView.OnSnapListener, PieItem.PieOnClickListener, PieItem.PieOnLongClickListener { public static final String TAG = "PieController"; public static final boolean DEBUG = false; @@ -94,14 +93,18 @@ public class PieController implements BaseStatusBar.NavigationBarCallback, private static final int MSG_INJECT_KEY_DOWN = 1066; private static final int MSG_INJECT_KEY_UP = 1067; + private static final int MSG_PIE_GAIN_FOCUS = 1068; + private static final int MSG_PIE_RESTORE_LISTENER_STATE = 1069; private Context mContext; - private PieLayout mPieContainer; + private PieManager mPieManager; + private PieView mPieContainer; /** - * This is only needed for #toggleRecentApps() + * This is only needed for #toggleRecentApps() and #showSearchPanel() */ private BaseStatusBar mStatusBar; private Vibrator mVibrator; + private WindowManager mWindowManager; private IWindowManager mWm; private int mBatteryLevel; private int mBatteryStatus; @@ -120,122 +123,36 @@ public class PieController implements BaseStatusBar.NavigationBarCallback, private Drawable mBackIcon; private Drawable mBackAltIcon; - /** - * Defines the positions in which pie controls may appear. This enumeration is used to store - * an index, a flag and the android gravity for each position. - */ - public enum Position { - LEFT(0, 0, android.view.Gravity.LEFT), - BOTTOM(1, 1, android.view.Gravity.BOTTOM), - RIGHT(2, 1, android.view.Gravity.RIGHT), - TOP(3, 0, android.view.Gravity.TOP); - - Position(int index, int factor, int android_gravity) { - INDEX = index; - FLAG = (0x01<<index); - ANDROID_GRAVITY = android_gravity; - FACTOR = factor; - } - - public final int INDEX; - public final int FLAG; - public final int ANDROID_GRAVITY; - /** - * This is 1 when the position is not at the axis (like {@link Position.RIGHT} is - * at {@code Layout.getWidth()} not at {@code 0}). - */ - public final int FACTOR; - } - - private Position mPosition; - - public static class Tracker { - public static float sDistance; - private float initialX = 0; - private float initialY = 0; - private float gracePeriod = 0; - - private Tracker(Position position) { - this.position = position; - } - - public void start(MotionEvent event) { - initialX = event.getX(); - initialY = event.getY(); - switch (position) { - case LEFT: - gracePeriod = initialX + sDistance / 3.0f; - break; - case RIGHT: - gracePeriod = initialX - sDistance / 3.0f; - break; - } - active = true; - } + protected int mExpandedDesktopState; + private int mPieTriggerSlots; + private int mPieTriggerMask = PiePosition.LEFT.FLAG + | PiePosition.BOTTOM.FLAG + | PiePosition.RIGHT.FLAG + | PiePosition.TOP.FLAG; + private PiePosition mPosition; - public boolean move(MotionEvent event) { - final float x = event.getX(); - final float y = event.getY(); - if (!active) { - return false; - } - - // Unroll the complete logic here - we want to be fast and out of the - // event chain as fast as possible. - boolean loaded = false; - switch (position) { - case LEFT: - if (x < gracePeriod) { - initialY = y; - } - if (initialY - y < sDistance && y - initialY < sDistance) { - if (x - initialX <= sDistance) { - return false; - } - loaded = true; - } - break; - case BOTTOM: - if (initialX - x < sDistance && x - initialX < sDistance) { - if (initialY - y <= sDistance) { - return false; - } - loaded = true; - } - break; - case TOP: - if (initialX - x < sDistance && x - initialX < sDistance) { - if (y - initialY <= sDistance) { - return false; - } - loaded = true; - } - break; - case RIGHT: - if (x > gracePeriod) { - initialY = y; - } - if (initialY - y < sDistance && y - initialY < sDistance) { - if (initialX - x <= sDistance) { - return false; - } - loaded = true; - } - break; + private PieManager.PieActivationListener mPieActivationListener = + new PieManager.PieActivationListener(Looper.getMainLooper()) { + @Override + public void onPieActivation(int touchX, int touchY, PiePosition position, int flags) { + if (position == PiePosition.BOTTOM && isSearchLightEnabled() && mStatusBar != null) { + // if we are at the bottom and nothing else is there, use a + // search light! + mStatusBar.showSearchPanel(); + // restore listener state immediately (after the bookkeeping), and since the + // search panel is a single gesture we will not trigger again + mHandler.obtainMessage(MSG_PIE_RESTORE_LISTENER_STATE).sendToTarget(); + } else if (mPieContainer != null) { + // set the snap points depending on current trigger and mask + mPieContainer.setSnapPoints(mPieTriggerMask & ~mPieTriggerSlots); + activateFromListener(touchX, touchY, position); + // give the main thread some time to do the bookkeeping + mHandler.obtainMessage(MSG_PIE_GAIN_FOCUS).sendToTarget(); } - active = false; - return loaded; } + }; - public boolean active = false; - public final Position position; - } - - public Tracker buildTracker(Position position) { - return new Tracker(position); - } - - private class H extends Handler { + private Handler mHandler = new Handler(Looper.getMainLooper()) { public void handleMessage(Message m) { final InputManager inputManager = InputManager.getInstance(); switch (m.what) { @@ -248,10 +165,17 @@ public class PieController implements BaseStatusBar.NavigationBarCallback, inputManager.injectInputEvent((KeyEvent) m.obj, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); break; + case MSG_PIE_GAIN_FOCUS: + if (!mPieActivationListener.gainTouchFocus(mPieContainer.getWindowToken())) { + mPieContainer.exit(); + } + break; + case MSG_PIE_RESTORE_LISTENER_STATE: + mPieActivationListener.restoreListenerState(); + break; } } - } - private H mHandler = new H(); + }; private void injectKeyDelayed(int keyCode, long when) { mHandler.removeMessages(MSG_INJECT_KEY_DOWN); @@ -277,15 +201,41 @@ public class PieController implements BaseStatusBar.NavigationBarCallback, void observe() { ContentResolver resolver = mContext.getContentResolver(); + // trigger setupNavigationItems() resolver.registerContentObserver(Settings.System.getUriFor( Settings.System.NAV_BUTTONS), false, this); resolver.registerContentObserver(Settings.Secure.getUriFor( Settings.Secure.KILL_APP_LONGPRESS_BACK), false, this); + // trigger setupContainer() + resolver.registerContentObserver(Settings.System.getUriFor( + Settings.System.PIE_CONTROLS), false, this); + resolver.registerContentObserver(Settings.System.getUriFor( + Settings.System.EXPANDED_DESKTOP_STATE), false, this); + resolver.registerContentObserver(Settings.System.getUriFor( + Settings.System.EXPANDED_DESKTOP_STYLE), false, this); + // trigger setupListener() + resolver.registerContentObserver(Settings.System.getUriFor( + Settings.System.PIE_POSITIONS), false, this); } @Override public void onChange(boolean selfChange) { - setupNavigationItems(); + ContentResolver resolver = mContext.getContentResolver(); + boolean expanded = Settings.System.getInt(resolver, + Settings.System.EXPANDED_DESKTOP_STATE, 0) == 1; + if (expanded) { + mExpandedDesktopState = Settings.System.getInt(resolver, + Settings.System.EXPANDED_DESKTOP_STYLE, 0); + } else { + mExpandedDesktopState = 0; + } + if (isEnabled()) { + setupContainer(); + setupNavigationItems(); + setupListener(); + } else { + detachContainer(); + } } } @@ -301,7 +251,7 @@ public class PieController implements BaseStatusBar.NavigationBarCallback, BatteryManager.BATTERY_STATUS_UNKNOWN); } else if (Intent.ACTION_SCREEN_OFF.equals(action)) { // Give up on screen off. what's the point in pie controls if you don't see them? - if (mPieContainer != null) { + if (isShowing()) { mPieContainer.exit(); } } @@ -318,7 +268,9 @@ public class PieController implements BaseStatusBar.NavigationBarCallback, public PieController(Context context) { mContext = context; + mPieManager = PieManager.getInstance(); mVibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE); + mWindowManager = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE); mWm = IWindowManager.Stub.asInterface(ServiceManager.getService("window")); if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { @@ -327,23 +279,29 @@ public class PieController implements BaseStatusBar.NavigationBarCallback, } final Resources res = mContext.getResources(); - Tracker.sDistance = res.getDimensionPixelSize(R.dimen.pie_trigger_distance); mBackIcon = res.getDrawable(R.drawable.ic_sysbar_back); mBackAltIcon = res.getDrawable(R.drawable.ic_sysbar_back_ime); + + mPieManager.setPieActivationListener(mPieActivationListener); + + // start listening for changes (calls setupListener & setupNavigationItems) + mSettingsObserver.observe(); + mSettingsObserver.onChange(true); } - public void detachContainer() { + private void detachContainer() { if (mPieContainer == null) { return; } + mPieManager.updatePieActivationListener(mPieActivationListener, 0); + if (mTelephonyManager != null) { mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE); } mContext.unregisterReceiver(mBroadcastReceiver); - mContext.getContentResolver().unregisterContentObserver(mSettingsObserver); mPieContainer.clearSlices(); mPieContainer = null; @@ -353,15 +311,23 @@ public class PieController implements BaseStatusBar.NavigationBarCallback, mStatusBar = statusBar; } - public void attachContainer(PieLayout container) { - mPieContainer = container; - mPieContainer.clearSlices(); + private void setupContainer() { + if (mPieContainer == null) { + mPieContainer = new PieView(mContext); + mPieContainer.setOnSnapListener(this); + mPieContainer.setOnExitListener(this); - if (DEBUG) { - Slog.d(TAG, "Attaching to container: " + container); + if (mTelephonyManager != null) { + mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_SERVICE_STATE); + } + + IntentFilter filter = new IntentFilter(); + filter.addAction(Intent.ACTION_BATTERY_CHANGED); + filter.addAction(Intent.ACTION_SCREEN_OFF); + mContext.registerReceiver(mBroadcastReceiver, filter); } - mPieContainer.setOnSnapListener(this); + mPieContainer.clearSlices(); final Resources res = mContext.getResources(); @@ -371,7 +337,6 @@ public class PieController implements BaseStatusBar.NavigationBarCallback, mNavigationSlice = new PieSliceContainer(mPieContainer, PieSlice.IMPORTANT | PieDrawable.DISPLAY_ALL); mNavigationSlice.setGeometry(START_ANGLE, 180 - 2 * EMPTY_ANGLE, inner, outer); - setupNavigationItems(); mPieContainer.addSlice(mNavigationSlice); // construct sysinfo slice @@ -380,18 +345,15 @@ public class PieController implements BaseStatusBar.NavigationBarCallback, mSysInfo = new PieSysInfo(mContext, mPieContainer, this, PieDrawable.DISPLAY_NOT_AT_TOP); mSysInfo.setGeometry(START_ANGLE, 180 - 2 * EMPTY_ANGLE, inner, outer); mPieContainer.addSlice(mSysInfo); + } - // start listening for changes - mSettingsObserver.observe(); - - IntentFilter filter = new IntentFilter(); - filter.addAction(Intent.ACTION_BATTERY_CHANGED); - filter.addAction(Intent.ACTION_SCREEN_OFF); - mContext.registerReceiver(mBroadcastReceiver, filter); + private void setupListener() { + ContentResolver resolver = mContext.getContentResolver(); - if (mTelephonyManager != null) { - mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_SERVICE_STATE); - } + mPieTriggerSlots = Settings.System.getInt(resolver, + Settings.System.PIE_POSITIONS, PiePosition.BOTTOM.FLAG); + mPieManager.updatePieActivationListener(mPieActivationListener, + mPieTriggerSlots & mPieTriggerMask); } private void setupNavigationItems() { @@ -462,14 +424,47 @@ public class PieController implements BaseStatusBar.NavigationBarCallback, } } - public void activateFromTrigger(View view, MotionEvent event, Position position) { - if (mPieContainer != null && !isShowing()) { + public void activateFromListener(int touchX, int touchY, PiePosition position) { + if (!isShowing()) { doHapticTriggerFeedback(); mPosition = position; - Point center = new Point((int) event.getRawX(), (int) event.getRawY()); + Point center = new Point(touchX, touchY); mPieContainer.activate(center, position); - mPieContainer.invalidate(); + mWindowManager.addView(mPieContainer, generateLayoutParam()); + } + } + + private WindowManager.LayoutParams generateLayoutParam() { + WindowManager.LayoutParams lp = new WindowManager.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL, + WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN + | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL + | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE + | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, + PixelFormat.TRANSLUCENT); + // This title is for debugging only. See: dumpsys window + lp.setTitle("PieControlPanel"); + lp.windowAnimations = android.R.style.Animation; + lp.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_BEHIND; + return lp; + } + + @Override + public void onExit() { + mWindowManager.removeView(mPieContainer); + mPieActivationListener.restoreListenerState(); + } + + public void updatePieTriggerMask(int newMask) { + int oldState = mPieTriggerSlots & mPieTriggerMask; + mPieTriggerMask = newMask; + + // first we check, if it would make a change + if ((mPieTriggerSlots & mPieTriggerMask) != oldState) { + setupListener(); } } @@ -557,7 +552,7 @@ public class PieController implements BaseStatusBar.NavigationBarCallback, } @Override - public void onSnap(Position position) { + public void onSnap(PiePosition position) { if (position == mPosition) { return; } @@ -569,7 +564,7 @@ public class PieController implements BaseStatusBar.NavigationBarCallback, } int triggerSlots = Settings.System.getInt(mContext.getContentResolver(), - Settings.System.PIE_POSITIONS, Position.BOTTOM.FLAG); + Settings.System.PIE_POSITIONS, PiePosition.BOTTOM.FLAG); triggerSlots = triggerSlots & ~mPosition.FLAG | position.FLAG; @@ -660,13 +655,20 @@ public class PieController implements BaseStatusBar.NavigationBarCallback, } public boolean isShowing() { - return mPieContainer != null && mPieContainer.isShowing(); + return mPieContainer.isShowing(); } public boolean isSearchLightEnabled() { return mSearchLight != null && (mSearchLight.flags & PieDrawable.VISIBLE) != 0; } + public boolean isEnabled() { + int pie = Settings.System.getInt(mContext.getContentResolver(), + Settings.System.PIE_CONTROLS, 0); + + return (pie == 1 && mExpandedDesktopState != 0) || pie == 2; + } + public String getOperatorState() { if (mTelephonyManager == null) { return null; |