diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationPresenter.java index 0e9f950f54edb..3334f8b457352 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationPresenter.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationPresenter.java @@ -15,9 +15,6 @@ */ package com.android.systemui.statusbar; -import android.content.Intent; - -import com.android.systemui.statusbar.notification.ActivityLaunchAnimator; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.row.ActivatableNotificationView; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; @@ -38,12 +35,6 @@ public interface NotificationPresenter extends ExpandableNotificationRow.OnExpan */ boolean isPresenterFullyCollapsed(); - /** - * Runs the given intent. The presenter may want to run some animations or close itself when - * this happens. - */ - void startNotificationGutsIntent(Intent intent, int appUid, ExpandableNotificationRow row); - /** * Refresh or remove lockscreen artwork from media metadata or the lockscreen wallpaper. */ @@ -74,8 +65,7 @@ public interface NotificationPresenter extends ExpandableNotificationRow.OnExpan int getMaxNotificationsWhileLocked(boolean recompute); /** - * True if the presenter - * @return + * True if the presenter is currently locked. */ default boolean isPresenterLocked() { return false; } @@ -88,22 +78,4 @@ public interface NotificationPresenter extends ExpandableNotificationRow.OnExpan * @return true if the shade is collapsing. */ boolean isCollapsing(); - - /** - * @return true if the shade is collapsing to show an activity over the lock screen - */ - default public boolean isCollapsingToShowActivityOverLockscreen() { - return false; - } - - /** - * Get the {@link ActivityLaunchAnimator} from the presenter so it can be queried by - * {@link com.android.systemui.statusbar.phone.StatusBar} - * @return the current animator - * @deprecated This is only here for now because StatusBar is still the ActivityLaunchAnimator - * callback but shouldn't be. - */ - default public ActivityLaunchAnimator getActivityLaunchAnimator() { - return null; - } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java index ecadf96dfbfc2..ba69f3bb1bc2d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java @@ -111,7 +111,6 @@ public class NotificationRemoteInputManager implements Dumpable { private final KeyguardManager mKeyguardManager; protected RemoteInputController mRemoteInputController; - protected NotificationPresenter mPresenter; protected NotificationLifetimeExtender.NotificationSafeToRemoveCallback mNotificationLifetimeFinishedCallback; protected IStatusBarService mBarService; @@ -320,10 +319,8 @@ public class NotificationRemoteInputManager implements Dumpable { mKeyguardManager = context.getSystemService(KeyguardManager.class); } - public void setUpWithPresenter(NotificationPresenter presenter, - Callback callback, - RemoteInputController.Delegate delegate) { - mPresenter = presenter; + /** Initializes this component with the provided dependencies. */ + public void setUpWithCallback(Callback callback, RemoteInputController.Delegate delegate) { mCallback = callback; mRemoteInputController = new RemoteInputController(delegate); mRemoteInputController.addCallback(new RemoteInputController.Callback() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationActivityStarter.java new file mode 100644 index 0000000000000..ba1b23bd80ed5 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationActivityStarter.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.notification; + +import android.content.Intent; +import android.service.notification.StatusBarNotification; + +import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; + +/** + * Component responsible for handling actions on a notification which cause activites to start. + * (e.g. clicking on a notification, tapping on the settings icon in the notification guts) + */ +public interface NotificationActivityStarter { + /** Called when the user clicks on the surface of a notification. */ + void onNotificationClicked(StatusBarNotification sbn, ExpandableNotificationRow row); + + /** Called when the user clicks on a button in the notification guts which fires an intent. */ + void startNotificationGutsIntent(Intent intent, int appUid, + ExpandableNotificationRow row); + + default boolean isCollapsingToShowActivityOverLockscreen() { + return false; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java index 70d144e006f91..f4e7913972e6c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java @@ -143,6 +143,7 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater. protected IStatusBarService mBarService; private NotificationPresenter mPresenter; private Callback mCallback; + private NotificationActivityStarter mNotificationActivityStarter; protected PowerManager mPowerManager; private NotificationListenerService.RankingMap mLatestRankingMap; protected HeadsUpManager mHeadsUpManager; @@ -193,7 +194,7 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater. mBubbleController.collapseStack(); } - mCallback.onNotificationClicked(sbn, row); + mNotificationActivityStarter.onNotificationClicked(sbn, row); } private boolean isMenuVisible(ExpandableNotificationRow row) { @@ -346,6 +347,11 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater. mOnAppOpsClickListener = mGutsManager::openGuts; } + public void setNotificationActivityStarter( + NotificationActivityStarter notificationActivityStarter) { + mNotificationActivityStarter = notificationActivityStarter; + } + public NotificationData getNotificationData() { return mNotificationData; } @@ -1247,15 +1253,6 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater. */ void onNotificationRemoved(String key, StatusBarNotification old); - - /** - * Called when a notification is clicked. - * - * @param sbn notification that was clicked - * @param row row for that notification - */ - void onNotificationClicked(StatusBarNotification sbn, ExpandableNotificationRow row); - /** * Called when a new notification and row is created. * diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java index 3dc50ae55c565..2e4552701456a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java @@ -25,7 +25,6 @@ import android.app.NotificationChannel; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; -import android.content.res.Resources; import android.net.Uri; import android.os.ServiceManager; import android.os.UserHandle; @@ -42,13 +41,13 @@ import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto; import com.android.systemui.Dependency; import com.android.systemui.Dumpable; -import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; import com.android.systemui.statusbar.NotificationLifetimeExtender; import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationPresenter; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.StatusBarStateController; +import com.android.systemui.statusbar.notification.NotificationActivityStarter; import com.android.systemui.statusbar.notification.NotificationData; import com.android.systemui.statusbar.notification.row.NotificationInfo.CheckSaveListener; import com.android.systemui.statusbar.notification.stack.NotificationListContainer; @@ -79,13 +78,13 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx Dependency.get(StatusBarStateController.class); private final DeviceProvisionedController mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class); - private final ActivityStarter mActivityStarter = Dependency.get(ActivityStarter.class); // which notification is currently being longpress-examined by the user private NotificationGuts mNotificationGutsExposed; private NotificationMenuRowPlugin.MenuItem mGutsMenuItem; private NotificationSafeToRemoveCallback mNotificationLifetimeFinishedCallback; private NotificationPresenter mPresenter; + private NotificationActivityStarter mNotificationActivityStarter; private NotificationListContainer mListContainer; private CheckSaveListener mCheckSaveListener; private OnSettingsClickListener mOnSettingsClickListener; @@ -94,8 +93,6 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx public NotificationGutsManager(Context context) { mContext = context; - Resources res = context.getResources(); - mAccessibilityManager = (AccessibilityManager) mContext.getSystemService(Context.ACCESSIBILITY_SERVICE); } @@ -109,6 +106,11 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx mOnSettingsClickListener = onSettingsClick; } + public void setNotificationActivityStarter( + NotificationActivityStarter notificationActivityStarter) { + mNotificationActivityStarter = notificationActivityStarter; + } + public void onDensityOrFontScaleChanged(NotificationData.Entry entry) { setExposedGuts(entry.getGuts()); bindGuts(entry.getRow()); @@ -127,7 +129,7 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx if (channel != null) { intent.putExtra(EXTRA_FRAGMENT_ARG_KEY, channel.getId()); } - mPresenter.startNotificationGutsIntent(intent, appUid, row); + mNotificationActivityStarter.startNotificationGutsIntent(intent, appUid, row); } protected void startAppOpsSettingsActivity(String pkg, int uid, ArraySet ops, @@ -138,12 +140,12 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx } else { Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION); intent.setData(Uri.fromParts("package", pkg, null)); - mPresenter.startNotificationGutsIntent(intent, uid, row); + mNotificationActivityStarter.startNotificationGutsIntent(intent, uid, row); } } else if (ops.contains(OP_CAMERA) || ops.contains(OP_RECORD_AUDIO)) { Intent intent = new Intent(Intent.ACTION_MANAGE_APP_PERMISSIONS); intent.putExtra(Intent.EXTRA_PACKAGE_NAME, pkg); - mPresenter.startNotificationGutsIntent(intent, uid, row); + mNotificationActivityStarter.startNotificationGutsIntent(intent, uid, row); } } @@ -262,7 +264,8 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx (View v, Intent intent) -> { mMetricsLogger.action(MetricsProto.MetricsEvent.ACTION_APP_NOTE_SETTINGS); guts.resetFalsingCheck(); - mPresenter.startNotificationGutsIntent(intent, sbn.getUid(), row); + mNotificationActivityStarter.startNotificationGutsIntent(intent, sbn.getUid(), + row); }; boolean isForBlockingHelper = row.isBlockingHelperShowing(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index 96ec6be1f9574..bf53b7720e44f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -187,6 +187,7 @@ import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.StatusBarStateController; import com.android.systemui.statusbar.VibratorHelper; import com.android.systemui.statusbar.notification.ActivityLaunchAnimator; +import com.android.systemui.statusbar.notification.NotificationActivityStarter; import com.android.systemui.statusbar.notification.NotificationData; import com.android.systemui.statusbar.notification.NotificationData.Entry; import com.android.systemui.statusbar.notification.NotificationEntryManager; @@ -578,7 +579,9 @@ public class StatusBar extends SystemUI implements DemoMode, private HeadsUpAppearanceController mHeadsUpAppearanceController; private boolean mVibrateOnOpening; private VibratorHelper mVibratorHelper; + private ActivityLaunchAnimator mActivityLaunchAnimator; protected NotificationPresenter mPresenter; + private NotificationActivityStarter mNotificationActivityStarter; private boolean mPulsing; @Override @@ -1014,13 +1017,23 @@ public class StatusBar extends SystemUI implements DemoMode, protected void setUpPresenter() { // Set up the initial notification state. + mActivityLaunchAnimator = new ActivityLaunchAnimator( + mStatusBarWindow, this, mNotificationPanel, + (NotificationListContainer) mStackScroller); + mPresenter = new StatusBarNotificationPresenter(mContext, mNotificationPanel, mHeadsUpManager, mStatusBarWindow, mStackScroller, mDozeScrimController, - mScrimController, this); + mScrimController, mActivityLaunchAnimator); + mAppOpsController.addCallback(APP_OPS, this); mNotificationListener.setUpWithPresenter(mPresenter); mNotificationShelf.setOnActivatedListener(mPresenter); mRemoteInputManager.getController().addCallback(mStatusBarWindowController); + + mNotificationActivityStarter = new StatusBarNotificationActivityStarter( + mContext, mNotificationPanel, mPresenter, mHeadsUpManager, mActivityLaunchAnimator); + mGutsManager.setNotificationActivityStarter(mNotificationActivityStarter); + mEntryManager.setNotificationActivityStarter(mNotificationActivityStarter); } /** @@ -1639,9 +1652,9 @@ public class StatusBar extends SystemUI implements DemoMode, @Override public void onExpandAnimationTimedOut() { - ActivityLaunchAnimator animator = mPresenter.getActivityLaunchAnimator(); if (mPresenter.isPresenterFullyCollapsed() && !mPresenter.isCollapsing() - && animator != null && !animator.isLaunchForActivity()) { + && mActivityLaunchAnimator != null + && !mActivityLaunchAnimator.isLaunchForActivity()) { onClosingFinished(); } else { collapsePanel(true /* animate */); @@ -1940,7 +1953,7 @@ public class StatusBar extends SystemUI implements DemoMode, runPostCollapseRunnables(); setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false); - if (!mPresenter.isCollapsingToShowActivityOverLockscreen()) { + if (!mNotificationActivityStarter.isCollapsingToShowActivityOverLockscreen()) { showBouncerIfKeyguard(); } else if (DEBUG) { Log.d(TAG, "Not showing bouncer due to activity showing over lockscreen"); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java new file mode 100644 index 0000000000000..c93d151b0f52d --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java @@ -0,0 +1,368 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.phone; + +import static com.android.systemui.Dependency.MAIN_HANDLER; +import static com.android.systemui.SysUiServiceProvider.getComponent; +import static com.android.systemui.statusbar.phone.StatusBar.getActivityOptions; + +import android.app.ActivityManager; +import android.app.ActivityTaskManager; +import android.app.KeyguardManager; +import android.app.Notification; +import android.app.PendingIntent; +import android.app.TaskStackBuilder; +import android.content.Context; +import android.content.Intent; +import android.os.AsyncTask; +import android.os.Looper; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.os.UserHandle; +import android.service.notification.StatusBarNotification; +import android.text.TextUtils; +import android.util.Log; +import android.view.RemoteAnimationAdapter; + +import com.android.internal.statusbar.IStatusBarService; +import com.android.internal.statusbar.NotificationVisibility; +import com.android.internal.widget.LockPatternUtils; +import com.android.systemui.Dependency; +import com.android.systemui.assist.AssistManager; +import com.android.systemui.plugins.ActivityStarter; +import com.android.systemui.statusbar.CommandQueue; +import com.android.systemui.statusbar.NotificationLockscreenUserManager; +import com.android.systemui.statusbar.NotificationPresenter; +import com.android.systemui.statusbar.NotificationRemoteInputManager; +import com.android.systemui.statusbar.RemoteInputController; +import com.android.systemui.statusbar.StatusBarState; +import com.android.systemui.statusbar.StatusBarStateController; +import com.android.systemui.statusbar.notification.ActivityLaunchAnimator; +import com.android.systemui.statusbar.notification.NotificationActivityStarter; +import com.android.systemui.statusbar.notification.NotificationData; +import com.android.systemui.statusbar.notification.NotificationEntryManager; +import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; +import com.android.systemui.statusbar.policy.HeadsUpUtil; +import com.android.systemui.statusbar.policy.KeyguardMonitor; +import com.android.systemui.statusbar.policy.PreviewInflater; + +/** + * Status bar implementation of {@link NotificationActivityStarter}. + */ +public class StatusBarNotificationActivityStarter implements NotificationActivityStarter { + + private static final String TAG = "NotificationClickHandler"; + + private final AssistManager mAssistManager = Dependency.get(AssistManager.class); + private final NotificationGroupManager mGroupManager = + Dependency.get(NotificationGroupManager.class); + private final StatusBarRemoteInputCallback mStatusBarRemoteInputCallback = + (StatusBarRemoteInputCallback) Dependency.get( + NotificationRemoteInputManager.Callback.class); + private final NotificationRemoteInputManager mRemoteInputManager = + Dependency.get(NotificationRemoteInputManager.class); + private final NotificationLockscreenUserManager mLockscreenUserManager = + Dependency.get(NotificationLockscreenUserManager.class); + private final ShadeController mShadeController = Dependency.get(ShadeController.class); + private final KeyguardMonitor mKeyguardMonitor = Dependency.get(KeyguardMonitor.class); + private final ActivityStarter mActivityStarter = Dependency.get(ActivityStarter.class); + private final NotificationEntryManager mEntryManager = + Dependency.get(NotificationEntryManager.class); + private final StatusBarStateController mStatusBarStateController = + Dependency.get(StatusBarStateController.class); + + private final Context mContext; + private final NotificationPanelView mNotificationPanel; + private final NotificationPresenter mPresenter; + private final LockPatternUtils mLockPatternUtils; + private final HeadsUpManagerPhone mHeadsUpManager; + private final KeyguardManager mKeyguardManager; + private final ActivityLaunchAnimator mActivityLaunchAnimator; + private final IStatusBarService mBarService; + private final CommandQueue mCommandQueue; + + private boolean mIsCollapsingToShowActivityOverLockscreen; + + public StatusBarNotificationActivityStarter(Context context, + NotificationPanelView panel, + NotificationPresenter presenter, + HeadsUpManagerPhone headsUpManager, + ActivityLaunchAnimator activityLaunchAnimator) { + mContext = context; + mNotificationPanel = panel; + mPresenter = presenter; + mLockPatternUtils = new LockPatternUtils(context); + mHeadsUpManager = headsUpManager; + mKeyguardManager = context.getSystemService(KeyguardManager.class); + mActivityLaunchAnimator = activityLaunchAnimator; + mBarService = IStatusBarService.Stub.asInterface( + ServiceManager.getService(Context.STATUS_BAR_SERVICE)); + mCommandQueue = getComponent(context, CommandQueue.class); + } + + /** + * Called when a notification is clicked. + * + * @param sbn notification that was clicked + * @param row row for that notification + */ + @Override + public void onNotificationClicked(StatusBarNotification sbn, ExpandableNotificationRow row) { + RemoteInputController controller = mRemoteInputManager.getController(); + if (controller.isRemoteInputActive(row.getEntry()) + && !TextUtils.isEmpty(row.getActiveRemoteInputText())) { + // We have an active remote input typed and the user clicked on the notification. + // this was probably unintentional, so we're closing the edit text instead. + controller.closeRemoteInputs(); + return; + } + Notification notification = sbn.getNotification(); + final PendingIntent intent = notification.contentIntent != null + ? notification.contentIntent + : notification.fullScreenIntent; + final String notificationKey = sbn.getKey(); + + boolean isActivityIntent = intent.isActivity(); + final boolean afterKeyguardGone = isActivityIntent + && PreviewInflater.wouldLaunchResolverActivity(mContext, intent.getIntent(), + mLockscreenUserManager.getCurrentUserId()); + final boolean wasOccluded = mShadeController.isOccluded(); + boolean showOverLockscreen = mKeyguardMonitor.isShowing() + && PreviewInflater.wouldShowOverLockscreen(mContext, + intent.getIntent(), + mLockscreenUserManager.getCurrentUserId()); + ActivityStarter.OnDismissAction postKeyguardAction = + () -> handleNotificationClickAfterKeyguardDismissed( + sbn, row, controller, intent, notificationKey, + isActivityIntent, wasOccluded, showOverLockscreen); + if (showOverLockscreen) { + mIsCollapsingToShowActivityOverLockscreen = true; + postKeyguardAction.onDismiss(); + } else { + mActivityStarter.dismissKeyguardThenExecute( + postKeyguardAction, null /* cancel */, afterKeyguardGone); + } + } + + private boolean handleNotificationClickAfterKeyguardDismissed( + StatusBarNotification sbn, + ExpandableNotificationRow row, + RemoteInputController controller, + PendingIntent intent, + String notificationKey, + boolean isActivityIntent, + boolean wasOccluded, + boolean showOverLockscreen) { + // TODO: Some of this code may be able to move to NotificationEntryManager. + if (mHeadsUpManager != null && mHeadsUpManager.isAlerting(notificationKey)) { + // Release the HUN notification to the shade. + + if (mPresenter.isPresenterFullyCollapsed()) { + HeadsUpUtil.setIsClickedHeadsUpNotification(row, true); + } + // + // In most cases, when FLAG_AUTO_CANCEL is set, the notification will + // become canceled shortly by NoMan, but we can't assume that. + mHeadsUpManager.removeNotification(sbn.getKey(), + true /* releaseImmediately */); + } + StatusBarNotification parentToCancel = null; + if (shouldAutoCancel(sbn) && mGroupManager.isOnlyChildInGroup(sbn)) { + StatusBarNotification summarySbn = + mGroupManager.getLogicalGroupSummary(sbn).notification; + if (shouldAutoCancel(summarySbn)) { + parentToCancel = summarySbn; + } + } + final StatusBarNotification parentToCancelFinal = parentToCancel; + final Runnable runnable = () -> handleNotificationClickAfterPanelCollapsed( + sbn, row, controller, intent, notificationKey, + isActivityIntent, wasOccluded, parentToCancelFinal); + + if (showOverLockscreen) { + mShadeController.addPostCollapseAction(runnable); + mShadeController.collapsePanel(true /* animate */); + } else if (mKeyguardMonitor.isShowing() + && mShadeController.isOccluded()) { + mShadeController.addAfterKeyguardGoneRunnable(runnable); + mShadeController.collapsePanel(); + } else { + new Thread(runnable).start(); + } + + return !mNotificationPanel.isFullyCollapsed(); + } + + private void handleNotificationClickAfterPanelCollapsed( + StatusBarNotification sbn, + ExpandableNotificationRow row, + RemoteInputController controller, + PendingIntent intent, + String notificationKey, + boolean isActivityIntent, + boolean wasOccluded, + StatusBarNotification parentToCancelFinal) { + try { + // The intent we are sending is for the application, which + // won't have permission to immediately start an activity after + // the user switches to home. We know it is safe to do at this + // point, so make sure new activity switches are now allowed. + ActivityManager.getService().resumeAppSwitches(); + } catch (RemoteException e) { + } + int launchResult; + // If we are launching a work activity and require to launch + // separate work challenge, we defer the activity action and cancel + // notification until work challenge is unlocked. + if (isActivityIntent) { + final int userId = intent.getCreatorUserHandle().getIdentifier(); + if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId) + && mKeyguardManager.isDeviceLocked(userId)) { + // TODO(b/28935539): should allow certain activities to + // bypass work challenge + if (mStatusBarRemoteInputCallback.startWorkChallengeIfNecessary(userId, + intent.getIntentSender(), notificationKey)) { + // Show work challenge, do not run PendingIntent and + // remove notification + collapseOnMainThread(); + return; + } + } + } + Intent fillInIntent = null; + NotificationData.Entry entry = row.getEntry(); + CharSequence remoteInputText = null; + if (!TextUtils.isEmpty(entry.remoteInputText)) { + remoteInputText = entry.remoteInputText; + } + if (!TextUtils.isEmpty(remoteInputText) && !controller.isSpinning(entry.key)) { + fillInIntent = new Intent().putExtra(Notification.EXTRA_REMOTE_INPUT_DRAFT, + remoteInputText.toString()); + } + RemoteAnimationAdapter adapter = mActivityLaunchAnimator.getLaunchAnimation( + row, wasOccluded); + try { + if (adapter != null) { + ActivityTaskManager.getService() + .registerRemoteAnimationForNextActivityStart( + intent.getCreatorPackage(), adapter); + } + launchResult = intent.sendAndReturnResult(mContext, 0, fillInIntent, null, + null, null, getActivityOptions(adapter)); + mActivityLaunchAnimator.setLaunchResult(launchResult, isActivityIntent); + } catch (RemoteException | PendingIntent.CanceledException e) { + // the stack trace isn't very helpful here. + // Just log the exception message. + Log.w(TAG, "Sending contentIntent failed: " + e); + + // TODO: Dismiss Keyguard. + } + if (isActivityIntent) { + mAssistManager.hideAssist(); + } + if (shouldCollapse()) { + collapseOnMainThread(); + } + + final int count = + mEntryManager.getNotificationData().getActiveNotifications().size(); + final int rank = mEntryManager.getNotificationData().getRank(notificationKey); + final NotificationVisibility nv = NotificationVisibility.obtain(notificationKey, + rank, count, true); + try { + mBarService.onNotificationClick(notificationKey, nv); + } catch (RemoteException ex) { + // system process is dead if we're here. + } + if (parentToCancelFinal != null) { + removeNotification(parentToCancelFinal); + } + if (shouldAutoCancel(sbn) + || mRemoteInputManager.isNotificationKeptForRemoteInputHistory( + notificationKey)) { + // Automatically remove all notifications that we may have kept around longer + removeNotification(sbn); + } + mIsCollapsingToShowActivityOverLockscreen = false; + } + + @Override + public void startNotificationGutsIntent(final Intent intent, final int appUid, + ExpandableNotificationRow row) { + mActivityStarter.dismissKeyguardThenExecute(() -> { + AsyncTask.execute(() -> { + int launchResult = TaskStackBuilder.create(mContext) + .addNextIntentWithParentStack(intent) + .startActivities(getActivityOptions( + mActivityLaunchAnimator.getLaunchAnimation( + row, mShadeController.isOccluded())), + new UserHandle(UserHandle.getUserId(appUid))); + mActivityLaunchAnimator.setLaunchResult(launchResult, true /* isActivityIntent */); + if (shouldCollapse()) { + // Putting it back on the main thread, since we're touching views + Dependency.get(MAIN_HANDLER).post(() -> mCommandQueue.animateCollapsePanels( + CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */)); + } + }); + return true; + }, null, false /* afterKeyguardGone */); + } + + @Override + public boolean isCollapsingToShowActivityOverLockscreen() { + return mIsCollapsingToShowActivityOverLockscreen; + } + + private static boolean shouldAutoCancel(StatusBarNotification sbn) { + int flags = sbn.getNotification().flags; + if ((flags & Notification.FLAG_AUTO_CANCEL) != Notification.FLAG_AUTO_CANCEL) { + return false; + } + if ((flags & Notification.FLAG_FOREGROUND_SERVICE) != 0) { + return false; + } + return true; + } + + private void collapseOnMainThread() { + if (Looper.getMainLooper().isCurrentThread()) { + mShadeController.collapsePanel(); + } else { + Dependency.get(MAIN_HANDLER).post(mShadeController::collapsePanel); + } + } + + private boolean shouldCollapse() { + return mStatusBarStateController.getState() != StatusBarState.SHADE + || !mActivityLaunchAnimator.isAnimationPending(); + } + + private void removeNotification(StatusBarNotification notification) { + // We have to post it to the UI thread for synchronization + Dependency.get(MAIN_HANDLER).post(() -> { + Runnable removeRunnable = + () -> mEntryManager.performRemoveNotification(notification); + if (mPresenter.isCollapsing()) { + // To avoid lags we're only performing the remove + // after the shade was collapsed + mShadeController.addPostCollapseAction(removeRunnable); + } else { + removeRunnable.run(); + } + }); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java index 588c3a8a33eae..3550bd627377d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java @@ -14,35 +14,22 @@ package com.android.systemui.statusbar.phone; -import static com.android.systemui.Dependency.MAIN_HANDLER; import static com.android.systemui.SysUiServiceProvider.getComponent; import static com.android.systemui.statusbar.phone.StatusBar.CLOSE_PANEL_WHEN_EMPTIED; import static com.android.systemui.statusbar.phone.StatusBar.DEBUG; import static com.android.systemui.statusbar.phone.StatusBar.MULTIUSER_DEBUG; import static com.android.systemui.statusbar.phone.StatusBar.SPEW; -import static com.android.systemui.statusbar.phone.StatusBar.getActivityOptions; -import android.app.ActivityManager; -import android.app.ActivityTaskManager; import android.app.KeyguardManager; -import android.app.Notification; -import android.app.PendingIntent; -import android.app.TaskStackBuilder; import android.content.Context; -import android.content.Intent; import android.content.pm.PackageManager; -import android.os.AsyncTask; -import android.os.Looper; import android.os.RemoteException; import android.os.ServiceManager; -import android.os.UserHandle; import android.service.notification.StatusBarNotification; import android.service.vr.IVrManager; import android.service.vr.IVrStateCallbacks; -import android.text.TextUtils; import android.util.Log; import android.util.Slog; -import android.view.RemoteAnimationAdapter; import android.view.View; import android.view.ViewGroup; import android.view.accessibility.AccessibilityManager; @@ -50,13 +37,10 @@ import android.widget.TextView; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.statusbar.IStatusBarService; -import com.android.internal.statusbar.NotificationVisibility; -import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.Dependency; import com.android.systemui.InitController; import com.android.systemui.R; -import com.android.systemui.assist.AssistManager; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.ActivityStarter.OnDismissAction; import com.android.systemui.statusbar.AmbientPulseManager; @@ -65,9 +49,7 @@ import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationMediaManager; import com.android.systemui.statusbar.NotificationPresenter; import com.android.systemui.statusbar.NotificationRemoteInputManager; -import com.android.systemui.statusbar.NotificationRemoteInputManager.Callback; import com.android.systemui.statusbar.NotificationViewHierarchyManager; -import com.android.systemui.statusbar.RemoteInputController; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.StatusBarStateController; import com.android.systemui.statusbar.notification.AboveShelfObserver; @@ -80,9 +62,7 @@ import com.android.systemui.statusbar.notification.row.NotificationGutsManager; import com.android.systemui.statusbar.notification.row.NotificationGutsManager.OnSettingsClickListener; import com.android.systemui.statusbar.notification.row.NotificationInfo.CheckSaveListener; import com.android.systemui.statusbar.notification.stack.NotificationListContainer; -import com.android.systemui.statusbar.policy.HeadsUpUtil; import com.android.systemui.statusbar.policy.KeyguardMonitor; -import com.android.systemui.statusbar.policy.PreviewInflater; public class StatusBarNotificationPresenter implements NotificationPresenter { @@ -93,7 +73,6 @@ public class StatusBarNotificationPresenter implements NotificationPresenter { private final ShadeController mShadeController = Dependency.get(ShadeController.class); private final ActivityStarter mActivityStarter = Dependency.get(ActivityStarter.class); - private final AssistManager mAssistManager = Dependency.get(AssistManager.class); private final KeyguardMonitor mKeyguardMonitor = Dependency.get(KeyguardMonitor.class); private final NotificationViewHierarchyManager mViewHierarchyManager = Dependency.get(NotificationViewHierarchyManager.class); @@ -105,12 +84,6 @@ public class StatusBarNotificationPresenter implements NotificationPresenter { Dependency.get(NotificationEntryManager.class); private final NotificationMediaManager mMediaManager = Dependency.get(NotificationMediaManager.class); - private final NotificationRemoteInputManager mRemoteInputManager = - Dependency.get(NotificationRemoteInputManager.class); - private final NotificationGroupManager mGroupManager = - Dependency.get(NotificationGroupManager.class); - private final StatusBarRemoteInputCallback mStatusBarRemoteInputCallback = - (StatusBarRemoteInputCallback) Dependency.get(Callback.class); protected AmbientPulseManager mAmbientPulseManager = Dependency.get(AmbientPulseManager.class); private final NotificationPanelView mNotificationPanel; @@ -122,7 +95,6 @@ public class StatusBarNotificationPresenter implements NotificationPresenter { private final CommandQueue mCommandQueue; private final AccessibilityManager mAccessibilityManager; - private final LockPatternUtils mLockPatternUtils; private final KeyguardManager mKeyguardManager; private final ActivityLaunchAnimator mActivityLaunchAnimator; private final int mMaxAllowedKeyguardNotifications; @@ -133,34 +105,32 @@ public class StatusBarNotificationPresenter implements NotificationPresenter { protected boolean mVrMode; private int mMaxKeyguardNotifications; - private boolean mIsCollapsingToShowActivityOverLockscreen; - public StatusBarNotificationPresenter(Context context, NotificationPanelView panel, - HeadsUpManagerPhone headsUp, StatusBarWindowView statusBarWindow, - ViewGroup stackScroller, DozeScrimController dozeScrimController, + public StatusBarNotificationPresenter(Context context, + NotificationPanelView panel, + HeadsUpManagerPhone headsUp, + StatusBarWindowView statusBarWindow, + ViewGroup stackScroller, + DozeScrimController dozeScrimController, ScrimController scrimController, - ActivityLaunchAnimator.Callback launchAnimatorCallback) { + ActivityLaunchAnimator activityLaunchAnimator) { mContext = context; mNotificationPanel = panel; mHeadsUpManager = headsUp; mCommandQueue = getComponent(context, CommandQueue.class); mAboveShelfObserver = new AboveShelfObserver(stackScroller); + mActivityLaunchAnimator = activityLaunchAnimator; mAboveShelfObserver.setListener(statusBarWindow.findViewById( R.id.notification_container_parent)); mAccessibilityManager = context.getSystemService(AccessibilityManager.class); mDozeScrimController = dozeScrimController; mScrimController = scrimController; mUnlockMethodCache = UnlockMethodCache.getInstance(mContext); - mLockPatternUtils = new LockPatternUtils(context); mKeyguardManager = context.getSystemService(KeyguardManager.class); mMaxAllowedKeyguardNotifications = context.getResources().getInteger( R.integer.keyguard_max_notification_count); mBarService = IStatusBarService.Stub.asInterface( ServiceManager.getService(Context.STATUS_BAR_SERVICE)); - mActivityLaunchAnimator = new ActivityLaunchAnimator(statusBarWindow, - launchAnimatorCallback, - mNotificationPanel, - (NotificationListContainer) stackScroller); if (MULTIUSER_DEBUG) { mNotificationPanelDebugText = mNotificationPanel.findViewById(R.id.header_debug_info); @@ -176,10 +146,12 @@ public class StatusBarNotificationPresenter implements NotificationPresenter { Slog.e(TAG, "Failed to register VR mode state listener: " + e); } } - mRemoteInputManager.setUpWithPresenter(this, + NotificationRemoteInputManager remoteInputManager = + Dependency.get(NotificationRemoteInputManager.class); + remoteInputManager.setUpWithCallback( Dependency.get(NotificationRemoteInputManager.Callback.class), mNotificationPanel.createRemoteInputDelegate()); - mRemoteInputManager.getController().addCallback( + remoteInputManager.getController().addCallback( Dependency.get(StatusBarWindowController.class)); NotificationListContainer notifListContainer = (NotificationListContainer) stackScroller; @@ -203,11 +175,6 @@ public class StatusBarNotificationPresenter implements NotificationPresenter { } } - @Override - public ActivityLaunchAnimator getActivityLaunchAnimator() { - return mActivityLaunchAnimator; - } - @Override public boolean isCollapsing() { return mNotificationPanel.isCollapsing() @@ -215,11 +182,6 @@ public class StatusBarNotificationPresenter implements NotificationPresenter { || mActivityLaunchAnimator.isAnimationRunning(); } - @Override - public boolean isCollapsingToShowActivityOverLockscreen() { - return mIsCollapsingToShowActivityOverLockscreen; - } - @Override public void onPerformRemoveNotification(StatusBarNotification n) { if (mNotificationPanel.hasPulsingNotifications() && @@ -376,201 +338,6 @@ public class StatusBarNotificationPresenter implements NotificationPresenter { mMediaManager.updateMediaMetaData(metaDataChanged, allowEnterAnimation); } - @Override - public void onNotificationClicked(StatusBarNotification sbn, ExpandableNotificationRow row) { - RemoteInputController controller = mRemoteInputManager.getController(); - if (controller.isRemoteInputActive(row.getEntry()) - && !TextUtils.isEmpty(row.getActiveRemoteInputText())) { - // We have an active remote input typed and the user clicked on the notification. - // this was probably unintentional, so we're closing the edit text instead. - controller.closeRemoteInputs(); - return; - } - Notification notification = sbn.getNotification(); - final PendingIntent intent = notification.contentIntent != null - ? notification.contentIntent - : notification.fullScreenIntent; - final String notificationKey = sbn.getKey(); - - boolean isActivityIntent = intent.isActivity(); - final boolean afterKeyguardGone = isActivityIntent - && PreviewInflater.wouldLaunchResolverActivity(mContext, intent.getIntent(), - mLockscreenUserManager.getCurrentUserId()); - final boolean wasOccluded = mShadeController.isOccluded(); - boolean showOverLockscreen = mKeyguardMonitor.isShowing() - && PreviewInflater.wouldShowOverLockscreen(mContext, - intent.getIntent(), - mLockscreenUserManager.getCurrentUserId()); - OnDismissAction postKeyguardAction = () -> { - // TODO: Some of this code may be able to move to NotificationEntryManager. - if (mHeadsUpManager != null && mHeadsUpManager.isAlerting(notificationKey)) { - // Release the HUN notification to the shade. - - if (isPresenterFullyCollapsed()) { - HeadsUpUtil.setIsClickedHeadsUpNotification(row, true); - } - // - // In most cases, when FLAG_AUTO_CANCEL is set, the notification will - // become canceled shortly by NoMan, but we can't assume that. - mHeadsUpManager.removeNotification(sbn.getKey(), - true /* releaseImmediately */); - } - StatusBarNotification parentToCancel = null; - if (shouldAutoCancel(sbn) && mGroupManager.isOnlyChildInGroup(sbn)) { - StatusBarNotification summarySbn = - mGroupManager.getLogicalGroupSummary(sbn).notification; - if (shouldAutoCancel(summarySbn)) { - parentToCancel = summarySbn; - } - } - final StatusBarNotification parentToCancelFinal = parentToCancel; - final Runnable runnable = () -> { - try { - // The intent we are sending is for the application, which - // won't have permission to immediately start an activity after - // the user switches to home. We know it is safe to do at this - // point, so make sure new activity switches are now allowed. - ActivityManager.getService().resumeAppSwitches(); - } catch (RemoteException e) { - } - int launchResult = ActivityManager.START_CANCELED; - if (intent != null) { - // If we are launching a work activity and require to launch - // separate work challenge, we defer the activity action and cancel - // notification until work challenge is unlocked. - if (isActivityIntent) { - final int userId = intent.getCreatorUserHandle().getIdentifier(); - if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId) - && mKeyguardManager.isDeviceLocked(userId)) { - // TODO(b/28935539): should allow certain activities to - // bypass work challenge - if (mStatusBarRemoteInputCallback.startWorkChallengeIfNecessary(userId, - intent.getIntentSender(), notificationKey)) { - // Show work challenge, do not run PendingIntent and - // remove notification - collapseOnMainThread(); - return; - } - } - } - Intent fillInIntent = null; - Entry entry = row.getEntry(); - CharSequence remoteInputText = null; - if (!TextUtils.isEmpty(entry.remoteInputText)) { - remoteInputText = entry.remoteInputText; - } - if (!TextUtils.isEmpty(remoteInputText) - && !controller.isSpinning(entry.key)) { - fillInIntent = new Intent().putExtra(Notification.EXTRA_REMOTE_INPUT_DRAFT, - remoteInputText.toString()); - } - RemoteAnimationAdapter adapter = mActivityLaunchAnimator.getLaunchAnimation( - row, wasOccluded); - try { - if (adapter != null) { - ActivityTaskManager.getService() - .registerRemoteAnimationForNextActivityStart( - intent.getCreatorPackage(), adapter); - } - launchResult = intent.sendAndReturnResult(mContext, 0, fillInIntent, null, - null, null, getActivityOptions(adapter)); - mActivityLaunchAnimator.setLaunchResult(launchResult, isActivityIntent); - } catch (RemoteException | PendingIntent.CanceledException e) { - // the stack trace isn't very helpful here. - // Just log the exception message. - Log.w(TAG, "Sending contentIntent failed: " + e); - - // TODO: Dismiss Keyguard. - } - if (isActivityIntent) { - mAssistManager.hideAssist(); - } - } - if (shouldCollapse()) { - collapseOnMainThread(); - } - - final int count = - mEntryManager.getNotificationData().getActiveNotifications().size(); - final int rank = mEntryManager.getNotificationData().getRank(notificationKey); - final NotificationVisibility nv = NotificationVisibility.obtain(notificationKey, - rank, count, true); - try { - mBarService.onNotificationClick(notificationKey, nv); - } catch (RemoteException ex) { - // system process is dead if we're here. - } - if (parentToCancelFinal != null) { - removeNotification(parentToCancelFinal); - } - if (shouldAutoCancel(sbn) - || mRemoteInputManager.isNotificationKeptForRemoteInputHistory( - notificationKey)) { - // Automatically remove all notifications that we may have kept around longer - removeNotification(sbn); - } - mIsCollapsingToShowActivityOverLockscreen = false; - }; - - if (showOverLockscreen) { - mShadeController.addPostCollapseAction(runnable); - mShadeController.collapsePanel(true /* animate */); - } else if (mKeyguardMonitor.isShowing() - && mShadeController.isOccluded()) { - mShadeController.addAfterKeyguardGoneRunnable(runnable); - mShadeController.collapsePanel(); - } else { - new Thread(runnable).start(); - } - - return !mNotificationPanel.isFullyCollapsed(); - }; - if (showOverLockscreen) { - mIsCollapsingToShowActivityOverLockscreen = true; - postKeyguardAction.onDismiss(); - } else { - mActivityStarter.dismissKeyguardThenExecute( - postKeyguardAction, null /* cancel */, afterKeyguardGone); - } - } - - private void removeNotification(StatusBarNotification notification) { - // We have to post it to the UI thread for synchronization - Dependency.get(MAIN_HANDLER).post(() -> { - Runnable removeRunnable = - () -> mEntryManager.performRemoveNotification(notification); - if (isCollapsing()) { - // To avoid lags we're only performing the remove - // after the shade was collapsed - mShadeController.addPostCollapseAction(removeRunnable); - } else { - removeRunnable.run(); - } - }); - } - - @Override - public void startNotificationGutsIntent(final Intent intent, final int appUid, - ExpandableNotificationRow row) { - mActivityStarter.dismissKeyguardThenExecute(() -> { - AsyncTask.execute(() -> { - int launchResult = TaskStackBuilder.create(mContext) - .addNextIntentWithParentStack(intent) - .startActivities(getActivityOptions( - mActivityLaunchAnimator.getLaunchAnimation( - row, mShadeController.isOccluded())), - new UserHandle(UserHandle.getUserId(appUid))); - mActivityLaunchAnimator.setLaunchResult(launchResult, true /* isActivityIntent */); - if (shouldCollapse()) { - // Putting it back on the main thread, since we're touching views - Dependency.get(MAIN_HANDLER).post(() -> mCommandQueue.animateCollapsePanels( - CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */)); - } - }); - return true; - }, null, false /* afterKeyguardGone */); - } - @Override public int getMaxNotificationsWhileLocked(boolean recompute) { if (recompute) { @@ -600,41 +367,12 @@ public class StatusBarNotificationPresenter implements NotificationPresenter { return mVrMode; } - @Override - public boolean isPresenterLocked() { - return mStatusBarStateController.getState() == StatusBarState.KEYGUARD; - } - - private void collapseOnMainThread() { - if (Looper.getMainLooper().isCurrentThread()) { - mShadeController.collapsePanel(); - } else { - Dependency.get(MAIN_HANDLER).post(mShadeController::collapsePanel); - } - } - - private boolean shouldCollapse() { - return mStatusBarStateController.getState() != StatusBarState.SHADE - || !mActivityLaunchAnimator.isAnimationPending(); - } - private void onLockedNotificationImportanceChange(OnDismissAction dismissAction) { mStatusBarStateController.setLeaveOpenOnKeyguardHide(true); mActivityStarter.dismissKeyguardThenExecute(dismissAction, null, true /* afterKeyguardGone */); } - private static boolean shouldAutoCancel(StatusBarNotification sbn) { - int flags = sbn.getNotification().flags; - if ((flags & Notification.FLAG_AUTO_CANCEL) != Notification.FLAG_AUTO_CANCEL) { - return false; - } - if ((flags & Notification.FLAG_FOREGROUND_SERVICE) != 0) { - return false; - } - return true; - } - private final IVrStateCallbacks mVrStateCallbacks = new IVrStateCallbacks.Stub() { @Override public void onVrStateChanged(boolean enabled) { @@ -645,7 +383,6 @@ public class StatusBarNotificationPresenter implements NotificationPresenter { private final CheckSaveListener mCheckSaveListener = new CheckSaveListener() { @Override public void checkSave(Runnable saveImportance, StatusBarNotification sbn) { - int state = mStatusBarStateController.getState(); // If the user has security enabled, show challenge if the setting is changed. if (mLockscreenUserManager.isLockscreenPublicMode(sbn.getUser().getIdentifier()) && mKeyguardManager.isKeyguardLocked()) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java index e3f6bd8f21f1f..78f537459d0a7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java @@ -17,8 +17,7 @@ package com.android.systemui.statusbar.phone; import static android.content.Intent.ACTION_DEVICE_LOCKED_CHANGED; import static com.android.systemui.SysUiServiceProvider.getComponent; -import static com.android.systemui.statusbar.NotificationLockscreenUserManager - .NOTIFICATION_UNLOCKED_BY_WORK_CHALLENGE_ACTION; +import static com.android.systemui.statusbar.NotificationLockscreenUserManager.NOTIFICATION_UNLOCKED_BY_WORK_CHALLENGE_ACTION; import android.app.ActivityManager; import android.app.KeyguardManager; @@ -163,7 +162,7 @@ public class StatusBarRemoteInputCallback implements Callback, Callbacks { mPendingWorkRemoteInputView = clicked; } - protected boolean startWorkChallengeIfNecessary(int userId, IntentSender intendSender, + 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 diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NonPhoneDependencyTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NonPhoneDependencyTest.java index 9449e297fcc56..f8ff583162cf9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NonPhoneDependencyTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NonPhoneDependencyTest.java @@ -91,7 +91,7 @@ public class NonPhoneDependencyTest extends SysuiTestCase { mCheckSaveListener, mOnSettingsClickListener); notificationLogger.setUpWithContainer(mListContainer); mediaManager.setUpWithPresenter(mPresenter); - remoteInputManager.setUpWithPresenter(mPresenter, mRemoteInputManagerCallback, + remoteInputManager.setUpWithCallback(mRemoteInputManagerCallback, mDelegate); lockscreenUserManager.setUpWithPresenter(mPresenter); viewHierarchyManager.setUpWithPresenter(mPresenter, mListContainer); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java index b5d305d864e8d..bee931f0f8e8e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java @@ -1,8 +1,8 @@ package com.android.systemui.statusbar; import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertTrue; import static junit.framework.Assert.assertFalse; +import static junit.framework.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -22,13 +22,12 @@ import android.testing.TestableLooper; import com.android.systemui.Dependency; import com.android.systemui.SysuiTestCase; - -import com.android.systemui.statusbar.notification.NotificationData; -import com.android.systemui.statusbar.notification.NotificationEntryManager; -import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.NotificationRemoteInputManager.RemoteInputActiveExtender; import com.android.systemui.statusbar.NotificationRemoteInputManager.RemoteInputHistoryExtender; import com.android.systemui.statusbar.NotificationRemoteInputManager.SmartReplyHistoryExtender; +import com.android.systemui.statusbar.notification.NotificationData; +import com.android.systemui.statusbar.notification.NotificationEntryManager; +import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.google.android.collect.Sets; @@ -80,7 +79,7 @@ public class NotificationRemoteInputManagerTest extends SysuiTestCase { mEntry = new NotificationData.Entry(mSbn); mEntry.setRow(mRow); - mRemoteInputManager.setUpWithPresenterForTest(mPresenter, mCallback, + mRemoteInputManager.setUpWithPresenterForTest(mCallback, mDelegate, mController); for (NotificationLifetimeExtender extender : mRemoteInputManager.getLifetimeExtenders()) { extender.setCallback( @@ -201,11 +200,10 @@ public class NotificationRemoteInputManagerTest extends SysuiTestCase { super(context); } - public void setUpWithPresenterForTest(NotificationPresenter presenter, - Callback callback, + public void setUpWithPresenterForTest(Callback callback, RemoteInputController.Delegate delegate, RemoteInputController controller) { - super.setUpWithPresenter(presenter, callback, delegate); + super.setUpWithCallback(callback, delegate); mRemoteInputController = controller; } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java index 76b992f42090e..8d52ccd71808c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java @@ -76,7 +76,7 @@ public class SmartReplyControllerTest extends SysuiTestCase { mSmartReplyController); mRemoteInputManager = new NotificationRemoteInputManager(mContext); - mRemoteInputManager.setUpWithPresenter(mPresenter, mCallback, mDelegate); + mRemoteInputManager.setUpWithCallback(mCallback, mDelegate); mNotification = new Notification.Builder(mContext, "") .setSmallIcon(R.drawable.ic_person) .setContentTitle("Title") diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java index 8966aca3069ce..ad43bea740898 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java @@ -59,8 +59,8 @@ import com.android.systemui.SysuiTestCase; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; import com.android.systemui.statusbar.NotificationPresenter; import com.android.systemui.statusbar.NotificationTestHelper; +import com.android.systemui.statusbar.notification.NotificationActivityStarter; import com.android.systemui.statusbar.notification.NotificationData; -import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.row.NotificationGutsManager.OnSettingsClickListener; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout; import com.android.systemui.statusbar.policy.DeviceProvisionedController; @@ -93,7 +93,7 @@ public class NotificationGutsManagerTest extends SysuiTestCase { @Rule public MockitoRule mockito = MockitoJUnit.rule(); @Mock private NotificationPresenter mPresenter; - @Mock private NotificationEntryManager mEntryManager; + @Mock private NotificationActivityStarter mNotificationActivityStarter; @Mock private NotificationStackScrollLayout mStackScroller; @Mock private NotificationInfo.CheckSaveListener mCheckSaveListener; @Mock private OnSettingsClickListener mOnSettingsClickListener; @@ -112,6 +112,7 @@ public class NotificationGutsManagerTest extends SysuiTestCase { mGutsManager = new NotificationGutsManager(mContext); mGutsManager.setUpWithPresenter(mPresenter, mStackScroller, mCheckSaveListener, mOnSettingsClickListener); + mGutsManager.setNotificationActivityStarter(mNotificationActivityStarter); } //////////////////////////////////////////////////////////////////////////////////////////////// @@ -219,7 +220,8 @@ public class NotificationGutsManagerTest extends SysuiTestCase { ops.add(OP_CAMERA); mGutsManager.startAppOpsSettingsActivity("", 0, ops, null); ArgumentCaptor captor = ArgumentCaptor.forClass(Intent.class); - verify(mPresenter, times(1)).startNotificationGutsIntent(captor.capture(), anyInt(), any()); + verify(mNotificationActivityStarter, times(1)) + .startNotificationGutsIntent(captor.capture(), anyInt(), any()); assertEquals(Intent.ACTION_MANAGE_APP_PERMISSIONS, captor.getValue().getAction()); } @@ -229,7 +231,8 @@ public class NotificationGutsManagerTest extends SysuiTestCase { ops.add(OP_RECORD_AUDIO); mGutsManager.startAppOpsSettingsActivity("", 0, ops, null); ArgumentCaptor captor = ArgumentCaptor.forClass(Intent.class); - verify(mPresenter, times(1)).startNotificationGutsIntent(captor.capture(), anyInt(), any()); + verify(mNotificationActivityStarter, times(1)) + .startNotificationGutsIntent(captor.capture(), anyInt(), any()); assertEquals(Intent.ACTION_MANAGE_APP_PERMISSIONS, captor.getValue().getAction()); } @@ -240,7 +243,8 @@ public class NotificationGutsManagerTest extends SysuiTestCase { ops.add(OP_RECORD_AUDIO); mGutsManager.startAppOpsSettingsActivity("", 0, ops, null); ArgumentCaptor captor = ArgumentCaptor.forClass(Intent.class); - verify(mPresenter, times(1)).startNotificationGutsIntent(captor.capture(), anyInt(), any()); + verify(mNotificationActivityStarter, times(1)) + .startNotificationGutsIntent(captor.capture(), anyInt(), any()); assertEquals(Intent.ACTION_MANAGE_APP_PERMISSIONS, captor.getValue().getAction()); } @@ -250,7 +254,8 @@ public class NotificationGutsManagerTest extends SysuiTestCase { ops.add(OP_SYSTEM_ALERT_WINDOW); mGutsManager.startAppOpsSettingsActivity("", 0, ops, null); ArgumentCaptor captor = ArgumentCaptor.forClass(Intent.class); - verify(mPresenter, times(1)).startNotificationGutsIntent(captor.capture(), anyInt(), any()); + verify(mNotificationActivityStarter, times(1)) + .startNotificationGutsIntent(captor.capture(), anyInt(), any()); assertEquals(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, captor.getValue().getAction()); } @@ -262,7 +267,8 @@ public class NotificationGutsManagerTest extends SysuiTestCase { ops.add(OP_SYSTEM_ALERT_WINDOW); mGutsManager.startAppOpsSettingsActivity("", 0, ops, null); ArgumentCaptor captor = ArgumentCaptor.forClass(Intent.class); - verify(mPresenter, times(1)).startNotificationGutsIntent(captor.capture(), anyInt(), any()); + verify(mNotificationActivityStarter, times(1)) + .startNotificationGutsIntent(captor.capture(), anyInt(), any()); assertEquals(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, captor.getValue().getAction()); } @@ -273,7 +279,8 @@ public class NotificationGutsManagerTest extends SysuiTestCase { ops.add(OP_SYSTEM_ALERT_WINDOW); mGutsManager.startAppOpsSettingsActivity("", 0, ops, null); ArgumentCaptor captor = ArgumentCaptor.forClass(Intent.class); - verify(mPresenter, times(1)).startNotificationGutsIntent(captor.capture(), anyInt(), any()); + verify(mNotificationActivityStarter, times(1)) + .startNotificationGutsIntent(captor.capture(), anyInt(), any()); assertEquals(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, captor.getValue().getAction()); } @@ -284,7 +291,8 @@ public class NotificationGutsManagerTest extends SysuiTestCase { ops.add(OP_SYSTEM_ALERT_WINDOW); mGutsManager.startAppOpsSettingsActivity("", 0, ops, null); ArgumentCaptor captor = ArgumentCaptor.forClass(Intent.class); - verify(mPresenter, times(1)).startNotificationGutsIntent(captor.capture(), anyInt(), any()); + verify(mNotificationActivityStarter, times(1)) + .startNotificationGutsIntent(captor.capture(), anyInt(), any()); assertEquals(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, captor.getValue().getAction()); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java index 59a49378e9e76..27123e435525c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java @@ -70,7 +70,7 @@ public class StatusBarNotificationPresenterTest extends SysuiTestCase { mock(NotificationPanelView.class), mock(HeadsUpManagerPhone.class), statusBarWindowView, mock(NotificationListContainerViewGroup.class), mock(DozeScrimController.class), mock(ScrimController.class), - mock(ActivityLaunchAnimator.Callback.class)); + mock(ActivityLaunchAnimator.class)); } @Test