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
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -4292,6 +4295,92 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
mPendingRemoteInputView = clicked;
|
||||
}
|
||||
|
||||
@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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user