diff options
| author | 2016-05-03 11:07:07 +0100 | |
|---|---|---|
| committer | 2016-05-03 12:18:31 +0100 | |
| commit | cd35def3c35f04d7fd056590d4668b5ebbc80490 (patch) | |
| tree | d6c53fdbe643aca41b02746c5c0eabc86b6e3d1e | |
| parent | ecd73f48fe219cf238c4c2ec692c42855787bde0 (diff) | |
Make notification reply can response to work challenge
When user clicks work notification reply button while work user has
challenge, it will bring you to work challenge, and click on the reply
button when work challenge is unlock.
Bug: 28036566
Change-Id: I7b8520c4e58c0c0f965e4770ab0c7b926d8fb39a
5 files changed, 172 insertions, 49 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index be683444fb43..d4c9c3635a12 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -457,9 +457,17 @@ public abstract class BaseStatusBar extends SystemUI implements row.setUserExpanded(true); - if (isLockscreenPublicMode() && !mAllowLockscreenRemoteInput) { - onLockedRemoteInput(row, view); - return true; + if (!mAllowLockscreenRemoteInput) { + if (isLockscreenPublicMode()) { + onLockedRemoteInput(row, view); + return true; + } + final int userId = pendingIntent.getCreatorUserHandle().getIdentifier(); + if (mUserManager.getUserInfo(userId).isManagedProfile() + && mKeyguardManager.isDeviceLocked(userId)) { + onLockedWorkRemoteInput(userId, row, view); + return true; + } } riv.setVisibility(View.VISIBLE); @@ -540,16 +548,21 @@ public abstract class BaseStatusBar extends SystemUI implements } else if (WORK_CHALLENGE_UNLOCKED_NOTIFICATION_ACTION.equals(action)) { final IntentSender intentSender = intent.getParcelableExtra(Intent.EXTRA_INTENT); final String notificationKey = intent.getStringExtra(Intent.EXTRA_INDEX); - try { - mContext.startIntentSender(intentSender, null, 0, 0, 0); - } catch (IntentSender.SendIntentException e) { - /* ignore */ + if (intentSender != null) { + try { + mContext.startIntentSender(intentSender, null, 0, 0, 0); + } catch (IntentSender.SendIntentException e) { + /* ignore */ + } } - try { - mBarService.onNotificationClick(notificationKey); - } catch (RemoteException e) { - /* ignore */ + if (notificationKey != null) { + try { + mBarService.onNotificationClick(notificationKey); + } catch (RemoteException e) { + /* ignore */ + } } + onWorkChallengeUnlocked(); } } }; @@ -1389,6 +1402,8 @@ public abstract class BaseStatusBar extends SystemUI implements return mLockscreenPublicMode; } + protected void onWorkChallengeUnlocked() {} + /** * Has the given user chosen to allow notifications to be shown even when the lockscreen is in * "public" (secure & locked) mode? @@ -1498,6 +1513,9 @@ public abstract class BaseStatusBar extends SystemUI implements protected void onLockedRemoteInput(ExpandableNotificationRow row, View clickedView) {} + protected void onLockedWorkRemoteInput(int userId, ExpandableNotificationRow row, + View clicked) {} + @Override public void onExpandClicked(Entry clickedEntry, boolean nowExpanded) { } @@ -1925,39 +1943,6 @@ public abstract class BaseStatusBar extends SystemUI implements }, afterKeyguardGone); } - public boolean startWorkChallengeIfNecessary(int userId, IntentSender intendSender, - String notificationKey) { - final Intent newIntent = mKeyguardManager.createConfirmDeviceCredentialIntent(null, - null, userId); - if (newIntent == null) { - return false; - } - final Intent callBackIntent = new Intent( - WORK_CHALLENGE_UNLOCKED_NOTIFICATION_ACTION); - callBackIntent.putExtra(Intent.EXTRA_INTENT, intendSender); - callBackIntent.putExtra(Intent.EXTRA_INDEX, notificationKey); - callBackIntent.setPackage(mContext.getPackageName()); - - PendingIntent callBackPendingIntent = PendingIntent.getBroadcast( - mContext, - 0, - callBackIntent, - PendingIntent.FLAG_CANCEL_CURRENT | - PendingIntent.FLAG_ONE_SHOT | - PendingIntent.FLAG_IMMUTABLE - ); - newIntent.putExtra( - Intent.EXTRA_INTENT, - callBackPendingIntent.getIntentSender() - ); - try { - ActivityManagerNative.getDefault().startConfirmDeviceCredentialIntent(newIntent); - } catch (RemoteException ex) { - // ignore - } - return true; - } - public void register(ExpandableNotificationRow row, StatusBarNotification sbn) { Notification notification = sbn.getNotification(); if (notification.contentIntent != null || notification.fullScreenIntent != null) { @@ -1984,6 +1969,37 @@ public abstract class BaseStatusBar extends SystemUI implements } } + protected boolean startWorkChallengeIfNecessary(int userId, IntentSender intendSender, + String notificationKey) { + final Intent newIntent = mKeyguardManager.createConfirmDeviceCredentialIntent(null, + null, userId); + if (newIntent == null) { + return false; + } + final Intent callBackIntent = new Intent( + WORK_CHALLENGE_UNLOCKED_NOTIFICATION_ACTION); + callBackIntent.putExtra(Intent.EXTRA_INTENT, intendSender); + callBackIntent.putExtra(Intent.EXTRA_INDEX, notificationKey); + callBackIntent.setPackage(mContext.getPackageName()); + + PendingIntent callBackPendingIntent = PendingIntent.getBroadcast( + mContext, + 0, + callBackIntent, + PendingIntent.FLAG_CANCEL_CURRENT | + PendingIntent.FLAG_ONE_SHOT | + PendingIntent.FLAG_IMMUTABLE); + newIntent.putExtra( + Intent.EXTRA_INTENT, + callBackPendingIntent.getIntentSender()); + try { + ActivityManagerNative.getDefault().startConfirmDeviceCredentialIntent(newIntent); + } catch (RemoteException ex) { + // ignore + } + return true; + } + protected Bundle getActivityOptions() { // Anything launched from the notification shade should always go into the // fullscreen stack. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java index 5b16fce925d1..0a28b8016ae6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java @@ -1239,6 +1239,14 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { || !mSensitiveHiddenInGeneral) ? View.VISIBLE : View.GONE); } + public void makeActionsVisibile() { + setUserExpanded(true, true); + if (isChildInGroup()) { + mGroupManager.setGroupExpanded(mStatusBarNotification, true); + } + notifyHeightChanged(false); + } + public void setChildrenExpanded(boolean expanded, boolean animate) { mChildrenExpanded = expanded; if (mNotificationHeader != null) { 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 f7ecd61e1568..71b56dd7ff40 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -32,6 +32,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.IntentSender; import android.content.pm.IPackageManager; import android.content.pm.PackageManager; import android.content.pm.UserInfo; @@ -89,6 +90,7 @@ import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.view.ViewParent; import android.view.ViewStub; +import android.view.ViewTreeObserver; import android.view.WindowManager; import android.view.WindowManagerGlobal; import android.view.animation.AccelerateInterpolator; @@ -348,6 +350,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, // RemoteInputView to be activated after unlock private View mPendingRemoteInputView; + private View mPendingWorkRemoteInputView; int mMaxAllowedKeyguardNotifications; @@ -4293,6 +4296,92 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } @Override + protected boolean startWorkChallengeIfNecessary(int userId, IntentSender intendSender, + String notificationKey) { + // Clear pending remote view, as we do not want to trigger pending remote input view when + // it's called by other code + mPendingWorkRemoteInputView = null; + return super.startWorkChallengeIfNecessary(userId, intendSender, notificationKey); + } + + @Override + protected void onLockedWorkRemoteInput(int userId, ExpandableNotificationRow row, + View clicked) { + // Collapse notification and show work challenge + animateCollapsePanels(); + startWorkChallengeIfNecessary(userId, null, null); + // Add pending remote input view after starting work challenge, as starting work challenge + // will clear all previous pending review view + mPendingWorkRemoteInputView = clicked; + } + + @Override + protected void onWorkChallengeUnlocked() { + if (mPendingWorkRemoteInputView != null) { + final View pendingWorkRemoteInputView = mPendingWorkRemoteInputView; + // Expand notification panel and the notification row, then click on remote input view + final Runnable clickPendingViewRunnable = new Runnable() { + @Override + public void run() { + if (mPendingWorkRemoteInputView != null) { + final View pendingWorkRemoteInputView = mPendingWorkRemoteInputView; + ViewParent p = pendingWorkRemoteInputView.getParent(); + while (p != null) { + if (p instanceof ExpandableNotificationRow) { + final ExpandableNotificationRow row = (ExpandableNotificationRow) p; + ViewParent viewParent = row.getParent(); + if (viewParent instanceof NotificationStackScrollLayout) { + final NotificationStackScrollLayout scrollLayout = + (NotificationStackScrollLayout) viewParent; + row.makeActionsVisibile(); + row.post(new Runnable() { + @Override + public void run() { + final Runnable finishScrollingCallback = new Runnable() + { + @Override + public void run() { + mPendingWorkRemoteInputView.callOnClick(); + mPendingWorkRemoteInputView = null; + scrollLayout.setFinishScrollingCallback(null); + } + }; + if (scrollLayout.scrollTo(row)) { + // It scrolls! So call it when it's finished. + scrollLayout.setFinishScrollingCallback( + finishScrollingCallback); + } else { + // It does not scroll, so call it now! + finishScrollingCallback.run(); + } + } + }); + } + break; + } + p = p.getParent(); + } + } + } + }; + mNotificationPanel.getViewTreeObserver().addOnGlobalLayoutListener( + new ViewTreeObserver.OnGlobalLayoutListener() { + @Override + public void onGlobalLayout() { + if (mNotificationPanel.mStatusBar.getStatusBarWindow() + .getHeight() != mNotificationPanel.mStatusBar + .getStatusBarHeight()) { + mNotificationPanel.getViewTreeObserver() + .removeOnGlobalLayoutListener(this); + mNotificationPanel.post(clickPendingViewRunnable); + } + } + }); + instantExpandNotificationsPanel(); + } + } + + @Override public void onExpandClicked(Entry clickedEntry, boolean nowExpanded) { mHeadsUpManager.setExpanded(clickedEntry, nowExpanded); if (mState == StatusBarState.KEYGUARD && nowExpanded) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java index 0a4dce8b1f22..f190df2fe2e8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java @@ -94,7 +94,6 @@ public class NotificationStackScrollLayout extends ViewGroup private static final float RUBBER_BAND_FACTOR_NORMAL = 0.35f; private static final float RUBBER_BAND_FACTOR_AFTER_EXPAND = 0.15f; private static final float RUBBER_BAND_FACTOR_ON_PANEL_EXPAND = 0.21f; - /** * Sentinel value for no current active pointer. Used by {@link #mActivePointerId}. */ @@ -116,6 +115,7 @@ public class NotificationStackScrollLayout extends ViewGroup private VelocityTracker mVelocityTracker; private OverScroller mScroller; + private Runnable mFinishScrollingCallback; private int mTouchSlop; private int mMinimumVelocity; private int mMaximumVelocity; @@ -922,17 +922,19 @@ public class NotificationStackScrollLayout extends ViewGroup mScrollingEnabled = enable; } - public void scrollTo(View v) { + public boolean scrollTo(View v) { ExpandableView expandableView = (ExpandableView) v; int positionInLinearLayout = getPositionInLinearLayout(v); - - int targetScroll = positionInLinearLayout + expandableView.getActualHeight() + + int targetScroll = positionInLinearLayout + expandableView.getIntrinsicHeight() + getImeInset() - getHeight() + getTopPadding(); + if (mOwnScrollY < targetScroll) { mScroller.startScroll(mScrollX, mOwnScrollY, 0, targetScroll - mOwnScrollY); mDontReportNextOverScroll = true; postInvalidateOnAnimation(); + return true; } + return false; } @Override @@ -1291,6 +1293,10 @@ public class NotificationStackScrollLayout extends ViewGroup } } + public void setFinishScrollingCallback(Runnable runnable) { + mFinishScrollingCallback = runnable; + } + @Override public void computeScroll() { if (mScroller.computeScrollOffset()) { @@ -1321,6 +1327,9 @@ public class NotificationStackScrollLayout extends ViewGroup postInvalidateOnAnimation(); } else { mDontClampNextScroll = false; + if (mFinishScrollingCallback != null) { + mFinishScrollingCallback.run(); + } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/ScrollContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/ScrollContainer.java index 64efa697de71..17b7871bbfe0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/ScrollContainer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/ScrollContainer.java @@ -31,8 +31,9 @@ public interface ScrollContainer { /** * Request that the view is made visible by scrolling to it. + * Return true if it scrolls. */ - void scrollTo(View v); + boolean scrollTo(View v); /** * Request that the view does not dismiss for the current touch. |