diff options
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. |