blob: 02f56e63a909d6b3f6252aaf9c7c1d8cad188b9a [file] [log] [blame]
Mady Mellor87d79452017-01-10 11:52:52 -08001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
Rohan Shah20790b82018-07-02 17:21:04 -070017package com.android.systemui.statusbar.notification.row;
Geoffrey Pitschdf44b602017-02-03 13:31:50 -050018
Gus Prevas9abc5062018-10-31 16:11:04 -040019import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
20import static android.app.NotificationManager.IMPORTANCE_HIGH;
21import static android.app.NotificationManager.IMPORTANCE_LOW;
Julia Reynoldse0341482018-03-08 14:42:50 -050022import static android.app.NotificationManager.IMPORTANCE_MIN;
Julia Reynolds3aedded2017-03-31 14:42:09 -040023import static android.app.NotificationManager.IMPORTANCE_NONE;
24
Julia Reynolds437cdb12018-01-03 12:27:24 -050025import android.animation.Animator;
26import android.animation.AnimatorListenerAdapter;
27import android.animation.AnimatorSet;
28import android.animation.ObjectAnimator;
Gus Prevas9abc5062018-10-31 16:11:04 -040029import android.annotation.IntDef;
Rohan Shahca0447e2018-03-30 15:18:27 -070030import android.annotation.Nullable;
Mady Mellor87d79452017-01-10 11:52:52 -080031import android.app.INotificationManager;
Julia Reynolds3aedded2017-03-31 14:42:09 -040032import android.app.Notification;
Mady Mellor87d79452017-01-10 11:52:52 -080033import android.app.NotificationChannel;
Geoffrey Pitschdf44b602017-02-03 13:31:50 -050034import android.app.NotificationChannelGroup;
Mady Mellor87d79452017-01-10 11:52:52 -080035import android.content.Context;
Julia Reynolds3aedded2017-03-31 14:42:09 -040036import android.content.Intent;
37import android.content.pm.ActivityInfo;
Mady Mellor87d79452017-01-10 11:52:52 -080038import android.content.pm.ApplicationInfo;
Mady Mellor87d79452017-01-10 11:52:52 -080039import android.content.pm.PackageManager;
Julia Reynolds3aedded2017-03-31 14:42:09 -040040import android.content.pm.ResolveInfo;
Mady Mellor87d79452017-01-10 11:52:52 -080041import android.graphics.drawable.Drawable;
William Brockman75cf66a2018-12-21 13:25:01 -050042import android.metrics.LogMaker;
Rohan Shahca0447e2018-03-30 15:18:27 -070043import android.os.Handler;
Mady Mellor87d79452017-01-10 11:52:52 -080044import android.os.RemoteException;
Julia Reynolds3aedded2017-03-31 14:42:09 -040045import android.service.notification.StatusBarNotification;
46import android.text.TextUtils;
Mady Mellor87d79452017-01-10 11:52:52 -080047import android.util.AttributeSet;
Rohan Shahca0447e2018-03-30 15:18:27 -070048import android.util.Log;
Mady Mellor87d79452017-01-10 11:52:52 -080049import android.view.View;
Julia Reynoldse0341482018-03-08 14:42:50 -050050import android.view.ViewGroup;
Geoffrey Pitschd94e7882017-04-06 09:52:11 -040051import android.view.accessibility.AccessibilityEvent;
Mady Mellor87d79452017-01-10 11:52:52 -080052import android.widget.ImageView;
53import android.widget.LinearLayout;
Mady Mellor87d79452017-01-10 11:52:52 -080054import android.widget.TextView;
55
Rohan Shah524cf7b2018-03-15 14:40:02 -070056import com.android.internal.annotations.VisibleForTesting;
Mady Mellor87d79452017-01-10 11:52:52 -080057import com.android.internal.logging.MetricsLogger;
58import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Rohan Shah524cf7b2018-03-15 14:40:02 -070059import com.android.systemui.Dependency;
Julia Reynolds437cdb12018-01-03 12:27:24 -050060import com.android.systemui.Interpolators;
Mady Mellor87d79452017-01-10 11:52:52 -080061import com.android.systemui.R;
Gus Prevas9abc5062018-10-31 16:11:04 -040062import com.android.systemui.statusbar.notification.NotificationUtils;
Rohan Shah20790b82018-07-02 17:21:04 -070063import com.android.systemui.statusbar.notification.logging.NotificationCounters;
Mady Mellor87d79452017-01-10 11:52:52 -080064
Geoffrey Pitschd0856f02017-02-16 10:51:18 -050065import java.util.List;
Mady Mellor87d79452017-01-10 11:52:52 -080066
67/**
Rohan Shahda5dcdd2018-04-27 17:21:50 -070068 * The guts of a notification revealed when performing a long press. This also houses the blocking
69 * helper affordance that allows a user to keep/stop notifications after swiping one away.
Mady Mellor87d79452017-01-10 11:52:52 -080070 */
Mady Mellor95d743c2017-01-10 12:05:27 -080071public class NotificationInfo extends LinearLayout implements NotificationGuts.GutsContent {
Mady Mellor87d79452017-01-10 11:52:52 -080072 private static final String TAG = "InfoGuts";
73
Gus Prevas894d9152018-11-12 13:51:40 -050074 @IntDef(prefix = { "ACTION_" }, value = {
75 ACTION_NONE,
76 ACTION_UNDO,
77 ACTION_TOGGLE_SILENT,
78 ACTION_BLOCK,
Gus Prevas9abc5062018-10-31 16:11:04 -040079 })
Gus Prevas894d9152018-11-12 13:51:40 -050080 public @interface NotificationInfoAction {
81 }
Gus Prevas9abc5062018-10-31 16:11:04 -040082
Gus Prevas894d9152018-11-12 13:51:40 -050083 public static final int ACTION_NONE = 0;
84 public static final int ACTION_UNDO = 1;
85 public static final int ACTION_TOGGLE_SILENT = 2;
86 public static final int ACTION_BLOCK = 3;
Nadia Benbernou3b4a93a2019-02-06 16:16:47 -050087 public static final int ACTION_DELIVER_SILENTLY = 4;
Gus Prevas9abc5062018-10-31 16:11:04 -040088
Mady Mellor87d79452017-01-10 11:52:52 -080089 private INotificationManager mINotificationManager;
Julia Reynolds437cdb12018-01-03 12:27:24 -050090 private PackageManager mPm;
Rohan Shahda5dcdd2018-04-27 17:21:50 -070091 private MetricsLogger mMetricsLogger;
Julia Reynolds437cdb12018-01-03 12:27:24 -050092
Rohan Shahca0447e2018-03-30 15:18:27 -070093 private String mPackageName;
Geoffrey Pitschd94e7882017-04-06 09:52:11 -040094 private String mAppName;
Geoffrey Pitschd0856f02017-02-16 10:51:18 -050095 private int mAppUid;
Julia Reynolds268647a2018-10-25 16:54:27 -040096 private String mDelegatePkg;
Rohan Shahca0447e2018-03-30 15:18:27 -070097 private int mNumUniqueChannelsInRow;
Geoffrey Pitschd0856f02017-02-16 10:51:18 -050098 private NotificationChannel mSingleNotificationChannel;
Gus Prevas9abc5062018-10-31 16:11:04 -040099 private int mStartingChannelImportance;
Gus Prevascaed15c2019-01-18 14:19:51 -0500100 private boolean mWasShownHighPriority;
101 /**
102 * The last importance level chosen by the user. Null if the user has not chosen an importance
103 * level; non-null once the user takes an action which indicates an explicit preference.
104 */
105 @Nullable private Integer mChosenImportance;
Julia Reynolds437cdb12018-01-03 12:27:24 -0500106 private boolean mIsSingleDefaultChannel;
Rohan Shah63411fc2018-03-28 19:05:52 -0700107 private boolean mIsNonblockable;
Julia Reynolds437cdb12018-01-03 12:27:24 -0500108 private StatusBarNotification mSbn;
109 private AnimatorSet mExpandAnimation;
Julia Reynoldse0341482018-03-08 14:42:50 -0500110 private boolean mIsForeground;
Julia Reynolds35765d82018-08-17 11:39:19 -0400111 private boolean mIsDeviceProvisioned;
Mady Mellor87d79452017-01-10 11:52:52 -0800112
Geoffrey Pitsch5278d3d2017-03-29 13:39:10 -0400113 private CheckSaveListener mCheckSaveListener;
Julia Reynolds437cdb12018-01-03 12:27:24 -0500114 private OnSettingsClickListener mOnSettingsClickListener;
Julia Reynolds3aedded2017-03-31 14:42:09 -0400115 private OnAppSettingsClickListener mAppSettingsClickListener;
Mady Mellor95d743c2017-01-10 12:05:27 -0800116 private NotificationGuts mGutsContainer;
Rohan Shah524cf7b2018-03-15 14:40:02 -0700117
Rohan Shahda5dcdd2018-04-27 17:21:50 -0700118 /** Whether this view is being shown as part of the blocking helper. */
Rohan Shah524cf7b2018-03-15 14:40:02 -0700119 private boolean mIsForBlockingHelper;
Julia Reynolds0ef7d842018-01-24 17:50:31 -0500120 private boolean mNegativeUserSentiment;
Mady Mellor87d79452017-01-10 11:52:52 -0800121
Rohan Shahdd588c72018-05-09 20:32:15 -0700122 /**
123 * String that describes how the user exit or quit out of this view, also used as a counter tag.
124 */
125 private String mExitReason = NotificationCounters.BLOCKING_HELPER_DISMISSED;
Rohan Shahda5dcdd2018-04-27 17:21:50 -0700126
127 private OnClickListener mOnKeepShowing = v -> {
Rohan Shahdd588c72018-05-09 20:32:15 -0700128 mExitReason = NotificationCounters.BLOCKING_HELPER_KEEP_SHOWING;
Rohan Shahda5dcdd2018-04-27 17:21:50 -0700129 closeControls(v);
Will Brockmana399f022019-01-30 10:59:36 -0500130 if (mIsForBlockingHelper) {
131 mMetricsLogger.write(getLogMaker().setCategory(
132 MetricsEvent.NOTIFICATION_BLOCKING_HELPER)
133 .setType(MetricsEvent.TYPE_ACTION)
134 .setSubtype(MetricsEvent.BLOCKING_HELPER_CLICK_STAY_SILENT));
135 }
Rohan Shahda5dcdd2018-04-27 17:21:50 -0700136 };
Julia Reynolds437cdb12018-01-03 12:27:24 -0500137
Gus Prevas9abc5062018-10-31 16:11:04 -0400138 private OnClickListener mOnToggleSilent = v -> {
Nadia Benbernou3b4a93a2019-02-06 16:16:47 -0500139 handleSaveImportance(ACTION_TOGGLE_SILENT, MetricsEvent.BLOCKING_HELPER_CLICK_ALERT_ME);
140 };
141
142 private OnClickListener mOnDeliverSilently = v -> {
143 handleSaveImportance(
144 ACTION_DELIVER_SILENTLY, MetricsEvent.BLOCKING_HELPER_CLICK_STAY_SILENT);
Gus Prevas9abc5062018-10-31 16:11:04 -0400145 };
146
Rohan Shahca0447e2018-03-30 15:18:27 -0700147 private OnClickListener mOnStopOrMinimizeNotifications = v -> {
Nadia Benbernou3b4a93a2019-02-06 16:16:47 -0500148 handleSaveImportance(ACTION_BLOCK, MetricsEvent.BLOCKING_HELPER_CLICK_BLOCKED);
149 };
150
151 private void handleSaveImportance(int action, int metricsSubtype) {
Gus Prevas533836a2018-09-24 17:15:32 -0400152 Runnable saveImportance = () -> {
Nadia Benbernou3b4a93a2019-02-06 16:16:47 -0500153 swapContent(action, true /* animate */);
Will Brockmana399f022019-01-30 10:59:36 -0500154 if (mIsForBlockingHelper) {
155 mMetricsLogger.write(getLogMaker()
156 .setCategory(MetricsEvent.NOTIFICATION_BLOCKING_HELPER)
157 .setType(MetricsEvent.TYPE_ACTION)
Nadia Benbernou3b4a93a2019-02-06 16:16:47 -0500158 .setSubtype(metricsSubtype));
Will Brockmana399f022019-01-30 10:59:36 -0500159 }
Gus Prevas533836a2018-09-24 17:15:32 -0400160 };
161 if (mCheckSaveListener != null) {
162 mCheckSaveListener.checkSave(saveImportance, mSbn);
163 } else {
164 saveImportance.run();
165 }
Nadia Benbernou3b4a93a2019-02-06 16:16:47 -0500166 }
Julia Reynolds437cdb12018-01-03 12:27:24 -0500167
168 private OnClickListener mOnUndo = v -> {
Rohan Shahda5dcdd2018-04-27 17:21:50 -0700169 // Reset exit counter that we'll log and record an undo event separately (not an exit event)
Rohan Shahdd588c72018-05-09 20:32:15 -0700170 mExitReason = NotificationCounters.BLOCKING_HELPER_DISMISSED;
Will Brockmana399f022019-01-30 10:59:36 -0500171 if (mIsForBlockingHelper) {
172 logBlockingHelperCounter(NotificationCounters.BLOCKING_HELPER_UNDO);
173 mMetricsLogger.write(getLogMaker().setCategory(
174 MetricsEvent.NOTIFICATION_BLOCKING_HELPER)
175 .setType(MetricsEvent.TYPE_DISMISS)
176 .setSubtype(MetricsEvent.BLOCKING_HELPER_CLICK_UNDO));
177 } else {
178 mMetricsLogger.write(importanceChangeLogMaker().setType(MetricsEvent.TYPE_DISMISS));
179 }
Gus Prevas894d9152018-11-12 13:51:40 -0500180 swapContent(ACTION_UNDO, true /* animate */);
Julia Reynolds437cdb12018-01-03 12:27:24 -0500181 };
182
Mady Mellor87d79452017-01-10 11:52:52 -0800183 public NotificationInfo(Context context, AttributeSet attrs) {
184 super(context, attrs);
185 }
186
Geoffrey Pitsch5278d3d2017-03-29 13:39:10 -0400187 // Specify a CheckSaveListener to override when/if the user's changes are committed.
188 public interface CheckSaveListener {
189 // Invoked when importance has changed and the NotificationInfo wants to try to save it.
190 // Listener should run saveImportance unless the change should be canceled.
Eliot Courtney47098cb2017-10-18 17:30:30 +0900191 void checkSave(Runnable saveImportance, StatusBarNotification sbn);
Geoffrey Pitsch5278d3d2017-03-29 13:39:10 -0400192 }
193
Jason Monk2a6ea9c2017-01-26 11:14:51 -0500194 public interface OnSettingsClickListener {
Geoffrey Pitschd0856f02017-02-16 10:51:18 -0500195 void onClick(View v, NotificationChannel channel, int appUid);
Mady Mellor87d79452017-01-10 11:52:52 -0800196 }
197
Julia Reynolds3aedded2017-03-31 14:42:09 -0400198 public interface OnAppSettingsClickListener {
199 void onClick(View v, Intent intent);
200 }
201
Rohan Shah524cf7b2018-03-15 14:40:02 -0700202 @VisibleForTesting
203 void bindNotification(
204 final PackageManager pm,
Jason Monk2a6ea9c2017-01-26 11:14:51 -0500205 final INotificationManager iNotificationManager,
Geoffrey Pitschd0856f02017-02-16 10:51:18 -0500206 final String pkg,
Julia Reynolds437cdb12018-01-03 12:27:24 -0500207 final NotificationChannel notificationChannel,
Rohan Shahca0447e2018-03-30 15:18:27 -0700208 final int numUniqueChannelsInRow,
Julia Reynolds3aedded2017-03-31 14:42:09 -0400209 final StatusBarNotification sbn,
Julia Reynolds437cdb12018-01-03 12:27:24 -0500210 final CheckSaveListener checkSaveListener,
211 final OnSettingsClickListener onSettingsClick,
212 final OnAppSettingsClickListener onAppSettingsClick,
Julia Reynolds35765d82018-08-17 11:39:19 -0400213 boolean isDeviceProvisioned,
Gus Prevas9abc5062018-10-31 16:11:04 -0400214 boolean isNonblockable,
Gus Prevascaed15c2019-01-18 14:19:51 -0500215 int importance,
216 boolean wasShownHighPriority)
Geoffrey Pitschd0856f02017-02-16 10:51:18 -0500217 throws RemoteException {
Rohan Shahca0447e2018-03-30 15:18:27 -0700218 bindNotification(pm, iNotificationManager, pkg, notificationChannel,
219 numUniqueChannelsInRow, sbn, checkSaveListener, onSettingsClick,
Julia Reynolds35765d82018-08-17 11:39:19 -0400220 onAppSettingsClick, isDeviceProvisioned, isNonblockable,
Gus Prevas82ad0592018-11-28 14:27:40 -0500221 false /* isBlockingHelper */, false /* isUserSentimentNegative */,
Gus Prevascaed15c2019-01-18 14:19:51 -0500222 importance, wasShownHighPriority);
Julia Reynolds0ef7d842018-01-24 17:50:31 -0500223 }
224
Rohan Shah524cf7b2018-03-15 14:40:02 -0700225 public void bindNotification(
226 PackageManager pm,
227 INotificationManager iNotificationManager,
228 String pkg,
229 NotificationChannel notificationChannel,
Rohan Shahca0447e2018-03-30 15:18:27 -0700230 int numUniqueChannelsInRow,
Rohan Shah524cf7b2018-03-15 14:40:02 -0700231 StatusBarNotification sbn,
232 CheckSaveListener checkSaveListener,
233 OnSettingsClickListener onSettingsClick,
234 OnAppSettingsClickListener onAppSettingsClick,
Julia Reynolds35765d82018-08-17 11:39:19 -0400235 boolean isDeviceProvisioned,
Rohan Shah63411fc2018-03-28 19:05:52 -0700236 boolean isNonblockable,
Rohan Shah524cf7b2018-03-15 14:40:02 -0700237 boolean isForBlockingHelper,
Gus Prevas9abc5062018-10-31 16:11:04 -0400238 boolean isUserSentimentNegative,
Gus Prevascaed15c2019-01-18 14:19:51 -0500239 int importance,
240 boolean wasShownHighPriority)
Rohan Shah524cf7b2018-03-15 14:40:02 -0700241 throws RemoteException {
Mady Mellor87d79452017-01-10 11:52:52 -0800242 mINotificationManager = iNotificationManager;
Rohan Shahda5dcdd2018-04-27 17:21:50 -0700243 mMetricsLogger = Dependency.get(MetricsLogger.class);
Rohan Shahca0447e2018-03-30 15:18:27 -0700244 mPackageName = pkg;
245 mNumUniqueChannelsInRow = numUniqueChannelsInRow;
Julia Reynolds3aedded2017-03-31 14:42:09 -0400246 mSbn = sbn;
247 mPm = pm;
248 mAppSettingsClickListener = onAppSettingsClick;
Rohan Shahca0447e2018-03-30 15:18:27 -0700249 mAppName = mPackageName;
Julia Reynolds437cdb12018-01-03 12:27:24 -0500250 mCheckSaveListener = checkSaveListener;
251 mOnSettingsClickListener = onSettingsClick;
252 mSingleNotificationChannel = notificationChannel;
Gus Prevascaed15c2019-01-18 14:19:51 -0500253 mStartingChannelImportance = mSingleNotificationChannel.getImportance();
254 mWasShownHighPriority = wasShownHighPriority;
Rohan Shah524cf7b2018-03-15 14:40:02 -0700255 mNegativeUserSentiment = isUserSentimentNegative;
Rohan Shah63411fc2018-03-28 19:05:52 -0700256 mIsNonblockable = isNonblockable;
Julia Reynoldse0341482018-03-08 14:42:50 -0500257 mIsForeground =
258 (mSbn.getNotification().flags & Notification.FLAG_FOREGROUND_SERVICE) != 0;
Rohan Shah524cf7b2018-03-15 14:40:02 -0700259 mIsForBlockingHelper = isForBlockingHelper;
Rohan Shahdbd64e72018-03-28 14:46:50 -0700260 mAppUid = mSbn.getUid();
Julia Reynolds268647a2018-10-25 16:54:27 -0400261 mDelegatePkg = mSbn.getOpPkg();
Julia Reynolds35765d82018-08-17 11:39:19 -0400262 mIsDeviceProvisioned = isDeviceProvisioned;
Geoffrey Pitschdf44b602017-02-03 13:31:50 -0500263
Julia Reynolds437cdb12018-01-03 12:27:24 -0500264 int numTotalChannels = mINotificationManager.getNumNotificationChannelsForPackage(
Geoffrey Pitschd034d292017-05-12 11:59:20 -0400265 pkg, mAppUid, false /* includeDeleted */);
Rohan Shahca0447e2018-03-30 15:18:27 -0700266 if (mNumUniqueChannelsInRow == 0) {
Geoffrey Pitschd034d292017-05-12 11:59:20 -0400267 throw new IllegalArgumentException("bindNotification requires at least one channel");
268 } else {
Julia Reynolds437cdb12018-01-03 12:27:24 -0500269 // Special behavior for the Default channel if no other channels have been defined.
Rohan Shahca0447e2018-03-30 15:18:27 -0700270 mIsSingleDefaultChannel = mNumUniqueChannelsInRow == 1
Rohan Shahdbd64e72018-03-28 14:46:50 -0700271 && mSingleNotificationChannel.getId().equals(
272 NotificationChannel.DEFAULT_CHANNEL_ID)
273 && numTotalChannels == 1;
Geoffrey Pitschd034d292017-05-12 11:59:20 -0400274 }
275
Julia Reynolds437cdb12018-01-03 12:27:24 -0500276 bindHeader();
277 bindPrompt();
278 bindButtons();
Eyal Posenera9cf9c72018-12-18 16:23:54 +0200279
Will Brockmana399f022019-01-30 10:59:36 -0500280 mMetricsLogger.write(notificationControlsLogMaker());
Julia Reynolds437cdb12018-01-03 12:27:24 -0500281 }
282
283 private void bindHeader() throws RemoteException {
284 // Package name
285 Drawable pkgicon = null;
286 ApplicationInfo info;
287 try {
Rohan Shahca0447e2018-03-30 15:18:27 -0700288 info = mPm.getApplicationInfo(
289 mPackageName,
Julia Reynolds437cdb12018-01-03 12:27:24 -0500290 PackageManager.MATCH_UNINSTALLED_PACKAGES
291 | PackageManager.MATCH_DISABLED_COMPONENTS
292 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
293 | PackageManager.MATCH_DIRECT_BOOT_AWARE);
294 if (info != null) {
Julia Reynolds437cdb12018-01-03 12:27:24 -0500295 mAppName = String.valueOf(mPm.getApplicationLabel(info));
296 pkgicon = mPm.getApplicationIcon(info);
Geoffrey Pitschee8c81e2017-03-23 11:38:56 -0400297 }
Julia Reynolds437cdb12018-01-03 12:27:24 -0500298 } catch (PackageManager.NameNotFoundException e) {
299 // app is gone, just show package name and generic icon
300 pkgicon = mPm.getDefaultActivityIcon();
Geoffrey Pitschd0856f02017-02-16 10:51:18 -0500301 }
Julia Reynolds437cdb12018-01-03 12:27:24 -0500302 ((ImageView) findViewById(R.id.pkgicon)).setImageDrawable(pkgicon);
Geoffrey Pitschd94e7882017-04-06 09:52:11 -0400303 ((TextView) findViewById(R.id.pkgname)).setText(mAppName);
Mady Mellor87d79452017-01-10 11:52:52 -0800304
Julia Reynolds268647a2018-10-25 16:54:27 -0400305 // Delegate
306 bindDelegate();
Daniel Sandlerd0a52b62018-10-31 20:13:22 +0000307
308 // Settings button.
309 final View settingsButton = findViewById(R.id.info);
310 if (mAppUid >= 0 && mOnSettingsClickListener != null && mIsDeviceProvisioned) {
311 settingsButton.setVisibility(View.VISIBLE);
312 final int appUidF = mAppUid;
313 settingsButton.setOnClickListener(
314 (View view) -> {
315 logBlockingHelperCounter(
316 NotificationCounters.BLOCKING_HELPER_NOTIF_SETTINGS);
317 mOnSettingsClickListener.onClick(view,
318 mNumUniqueChannelsInRow > 1 ? null : mSingleNotificationChannel,
319 appUidF);
320 });
321 } else {
322 settingsButton.setVisibility(View.GONE);
323 }
324 }
325
Julia Reynolds268647a2018-10-25 16:54:27 -0400326 private void bindPrompt() throws RemoteException {
Daniel Sandlerd0a52b62018-10-31 20:13:22 +0000327 final TextView blockPrompt = findViewById(R.id.block_prompt);
328 bindName();
Julia Reynolds268647a2018-10-25 16:54:27 -0400329 bindGroup();
Daniel Sandlerd0a52b62018-10-31 20:13:22 +0000330 if (mIsNonblockable) {
331 blockPrompt.setText(R.string.notification_unblockable_desc);
332 } else {
333 if (mNegativeUserSentiment) {
334 blockPrompt.setText(R.string.inline_blocking_helper);
335 } else if (mIsSingleDefaultChannel || mNumUniqueChannelsInRow > 1) {
336 blockPrompt.setText(R.string.inline_keep_showing_app);
337 } else {
338 blockPrompt.setText(R.string.inline_keep_showing);
339 }
340 }
341 }
342
343 private void bindName() {
344 final TextView channelName = findViewById(R.id.channel_name);
345 if (mIsSingleDefaultChannel || mNumUniqueChannelsInRow > 1) {
346 channelName.setVisibility(View.GONE);
347 } else {
348 channelName.setText(mSingleNotificationChannel.getName());
349 }
Julia Reynoldsac98aea2018-10-25 16:54:27 -0400350 }
351
Julia Reynolds268647a2018-10-25 16:54:27 -0400352 private void bindDelegate() {
353 TextView delegateView = findViewById(R.id.delegate_name);
354 TextView dividerView = findViewById(R.id.pkg_divider);
355
356 CharSequence delegatePkg = null;
357 if (!TextUtils.equals(mPackageName, mDelegatePkg)) {
358 // this notification was posted by a delegate!
359 ApplicationInfo info;
360 try {
361 info = mPm.getApplicationInfo(
362 mDelegatePkg,
363 PackageManager.MATCH_UNINSTALLED_PACKAGES
364 | PackageManager.MATCH_DISABLED_COMPONENTS
365 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
366 | PackageManager.MATCH_DIRECT_BOOT_AWARE);
367 if (info != null) {
368 delegatePkg = String.valueOf(mPm.getApplicationLabel(info));
369 }
370 } catch (PackageManager.NameNotFoundException e) { }
371 }
372 if (delegatePkg != null) {
373 delegateView.setText(mContext.getResources().getString(
374 R.string.notification_delegate_header, delegatePkg));
375 delegateView.setVisibility(View.VISIBLE);
376 dividerView.setVisibility(View.VISIBLE);
377 } else {
378 delegateView.setVisibility(View.GONE);
379 dividerView.setVisibility(View.GONE);
380 }
381 }
382
383 private void bindGroup() throws RemoteException {
384 // Set group information if this channel has an associated group.
385 CharSequence groupName = null;
386 if (mSingleNotificationChannel != null && mSingleNotificationChannel.getGroup() != null) {
387 final NotificationChannelGroup notificationChannelGroup =
388 mINotificationManager.getNotificationChannelGroupForPackage(
389 mSingleNotificationChannel.getGroup(), mPackageName, mAppUid);
390 if (notificationChannelGroup != null) {
391 groupName = notificationChannelGroup.getName();
392 }
393 }
394 TextView groupNameView = findViewById(R.id.group_name);
395 TextView groupDividerView = findViewById(R.id.pkg_group_divider);
396 if (groupName != null) {
397 groupNameView.setText(groupName);
398 groupNameView.setVisibility(View.VISIBLE);
399 groupDividerView.setVisibility(View.VISIBLE);
400 } else {
401 groupNameView.setVisibility(View.GONE);
402 groupDividerView.setVisibility(View.GONE);
403 }
404 }
405
Rohan Shahda5dcdd2018-04-27 17:21:50 -0700406 @VisibleForTesting
407 void logBlockingHelperCounter(String counterTag) {
408 if (mIsForBlockingHelper) {
409 mMetricsLogger.count(counterTag, 1);
410 }
411 }
412
Geoffrey Pitsch5278d3d2017-03-29 13:39:10 -0400413 private boolean hasImportanceChanged() {
Gus Prevas9abc5062018-10-31 16:11:04 -0400414 return mSingleNotificationChannel != null
Gus Prevascaed15c2019-01-18 14:19:51 -0500415 && mChosenImportance != null
416 && (mStartingChannelImportance != mChosenImportance
417 || (mWasShownHighPriority && mChosenImportance < IMPORTANCE_DEFAULT)
418 || (!mWasShownHighPriority && mChosenImportance >= IMPORTANCE_DEFAULT));
Mady Mellor87d79452017-01-10 11:52:52 -0800419 }
420
Geoffrey Pitschdf44b602017-02-03 13:31:50 -0500421 private void saveImportance() {
Gus Prevas894d9152018-11-12 13:51:40 -0500422 if (!mIsNonblockable
423 || mExitReason != NotificationCounters.BLOCKING_HELPER_STOP_NOTIFICATIONS) {
Gus Prevascaed15c2019-01-18 14:19:51 -0500424 if (mChosenImportance == null) {
425 mChosenImportance = mStartingChannelImportance;
426 }
Gus Prevas533836a2018-09-24 17:15:32 -0400427 updateImportance();
Geoffrey Pitschd0856f02017-02-16 10:51:18 -0500428 }
Rohan Shahca0447e2018-03-30 15:18:27 -0700429 }
430
431 /**
432 * Commits the updated importance values on the background thread.
433 */
434 private void updateImportance() {
Gus Prevascaed15c2019-01-18 14:19:51 -0500435 if (mChosenImportance != null) {
436 mMetricsLogger.write(importanceChangeLogMaker());
Rohan Shahca0447e2018-03-30 15:18:27 -0700437
Gus Prevascaed15c2019-01-18 14:19:51 -0500438 Handler bgHandler = new Handler(Dependency.get(Dependency.BG_LOOPER));
439 bgHandler.post(
440 new UpdateImportanceRunnable(mINotificationManager, mPackageName, mAppUid,
441 mNumUniqueChannelsInRow == 1 ? mSingleNotificationChannel : null,
442 mStartingChannelImportance, mChosenImportance));
443 }
Mady Mellor87d79452017-01-10 11:52:52 -0800444 }
445
Julia Reynolds437cdb12018-01-03 12:27:24 -0500446 private void bindButtons() {
Rohan Shah524cf7b2018-03-15 14:40:02 -0700447 findViewById(R.id.undo).setOnClickListener(mOnUndo);
Julia Reynolds437cdb12018-01-03 12:27:24 -0500448
Gus Prevas82ad0592018-11-28 14:27:40 -0500449 boolean showInterruptivenessSettings =
450 !mIsNonblockable
451 && !mIsForeground
452 && !mIsForBlockingHelper
453 && NotificationUtils.useNewInterruptionModel(mContext);
454 if (showInterruptivenessSettings) {
455 findViewById(R.id.block_or_minimize).setVisibility(GONE);
456 findViewById(R.id.interruptiveness_settings).setVisibility(VISIBLE);
457 View block = findViewById(R.id.int_block);
458 TextView silent = findViewById(R.id.int_silent);
459 TextView alert = findViewById(R.id.int_alert);
460
Gus Prevas82ad0592018-11-28 14:27:40 -0500461 block.setOnClickListener(mOnStopOrMinimizeNotifications);
Gus Prevascaed15c2019-01-18 14:19:51 -0500462 if (mWasShownHighPriority) {
Gus Prevas82ad0592018-11-28 14:27:40 -0500463 silent.setOnClickListener(mOnToggleSilent);
464 silent.setText(R.string.inline_silent_button_silent);
465 alert.setOnClickListener(mOnKeepShowing);
466 alert.setText(R.string.inline_silent_button_keep_alerting);
467 } else {
468 silent.setOnClickListener(mOnKeepShowing);
469 silent.setText(R.string.inline_silent_button_stay_silent);
470 alert.setOnClickListener(mOnToggleSilent);
471 alert.setText(R.string.inline_silent_button_alert);
472 }
Mady Mellor87d79452017-01-10 11:52:52 -0800473 } else {
Gus Prevas82ad0592018-11-28 14:27:40 -0500474 findViewById(R.id.block_or_minimize).setVisibility(VISIBLE);
475 findViewById(R.id.interruptiveness_settings).setVisibility(GONE);
476 View block = findViewById(R.id.block);
Nadia Benbernou3b4a93a2019-02-06 16:16:47 -0500477 TextView done = findViewById(R.id.done);
Gus Prevas82ad0592018-11-28 14:27:40 -0500478 View minimize = findViewById(R.id.minimize);
Nadia Benbernou3b4a93a2019-02-06 16:16:47 -0500479 View deliverSilently = findViewById(R.id.deliver_silently);
480
Gus Prevas82ad0592018-11-28 14:27:40 -0500481
482 block.setOnClickListener(mOnStopOrMinimizeNotifications);
Nadia Benbernou3b4a93a2019-02-06 16:16:47 -0500483 done.setOnClickListener(mOnKeepShowing);
Gus Prevas82ad0592018-11-28 14:27:40 -0500484 minimize.setOnClickListener(mOnStopOrMinimizeNotifications);
Nadia Benbernou3b4a93a2019-02-06 16:16:47 -0500485 deliverSilently.setOnClickListener(mOnDeliverSilently);
Gus Prevas82ad0592018-11-28 14:27:40 -0500486
487 if (mIsNonblockable) {
Nadia Benbernou3b4a93a2019-02-06 16:16:47 -0500488 done.setText(android.R.string.ok);
Gus Prevas82ad0592018-11-28 14:27:40 -0500489 block.setVisibility(GONE);
490 minimize.setVisibility(GONE);
Nadia Benbernou3b4a93a2019-02-06 16:16:47 -0500491 deliverSilently.setVisibility(GONE);
Gus Prevas82ad0592018-11-28 14:27:40 -0500492 } else if (mIsForeground) {
493 block.setVisibility(GONE);
494 minimize.setVisibility(VISIBLE);
495 } else {
496 block.setVisibility(VISIBLE);
497 minimize.setVisibility(GONE);
498 }
499
500 // Set up app settings link (i.e. Customize)
Nadia Benbernou3b4a93a2019-02-06 16:16:47 -0500501 View settingsLinkView = findViewById(R.id.app_settings);
Gus Prevas82ad0592018-11-28 14:27:40 -0500502 Intent settingsIntent = getAppSettingsIntent(mPm, mPackageName,
503 mSingleNotificationChannel,
504 mSbn.getId(), mSbn.getTag());
505 if (!mIsForBlockingHelper
506 && settingsIntent != null
507 && !TextUtils.isEmpty(mSbn.getNotification().getSettingsText())) {
508 settingsLinkView.setVisibility(VISIBLE);
Gus Prevas82ad0592018-11-28 14:27:40 -0500509 settingsLinkView.setOnClickListener((View view) -> {
510 mAppSettingsClickListener.onClick(view, settingsIntent);
511 });
512 } else {
513 settingsLinkView.setVisibility(View.GONE);
514 }
Mady Mellor87d79452017-01-10 11:52:52 -0800515 }
516 }
517
Gus Prevas894d9152018-11-12 13:51:40 -0500518 private void swapContent(@NotificationInfoAction int action, boolean animate) {
Julia Reynolds437cdb12018-01-03 12:27:24 -0500519 if (mExpandAnimation != null) {
520 mExpandAnimation.cancel();
521 }
Mady Mellor87d79452017-01-10 11:52:52 -0800522
Julia Reynoldse0341482018-03-08 14:42:50 -0500523 View prompt = findViewById(R.id.prompt);
524 ViewGroup confirmation = findViewById(R.id.confirmation);
525 TextView confirmationText = findViewById(R.id.confirmation_text);
526 View header = findViewById(R.id.header);
527
Gus Prevas9abc5062018-10-31 16:11:04 -0400528 switch (action) {
Gus Prevas894d9152018-11-12 13:51:40 -0500529 case ACTION_UNDO:
Gus Prevas9abc5062018-10-31 16:11:04 -0400530 mChosenImportance = mStartingChannelImportance;
531 break;
Nadia Benbernou3b4a93a2019-02-06 16:16:47 -0500532 case ACTION_DELIVER_SILENTLY:
533 mExitReason = NotificationCounters.BLOCKING_HELPER_DELIVER_SILENTLY;
534 mChosenImportance = IMPORTANCE_LOW;
535 confirmationText.setText(R.string.notification_channel_silenced);
536 break;
Gus Prevas894d9152018-11-12 13:51:40 -0500537 case ACTION_TOGGLE_SILENT:
538 mExitReason = NotificationCounters.BLOCKING_HELPER_TOGGLE_SILENT;
Gus Prevascaed15c2019-01-18 14:19:51 -0500539 if (mWasShownHighPriority) {
Gus Prevas9abc5062018-10-31 16:11:04 -0400540 mChosenImportance = IMPORTANCE_LOW;
541 confirmationText.setText(R.string.notification_channel_silenced);
542 } else {
543 mChosenImportance = IMPORTANCE_HIGH;
544 confirmationText.setText(R.string.notification_channel_unsilenced);
545 }
546 break;
Gus Prevas894d9152018-11-12 13:51:40 -0500547 case ACTION_BLOCK:
548 mExitReason = NotificationCounters.BLOCKING_HELPER_STOP_NOTIFICATIONS;
Gus Prevas9abc5062018-10-31 16:11:04 -0400549 if (mIsForeground) {
550 mChosenImportance = IMPORTANCE_MIN;
551 confirmationText.setText(R.string.notification_channel_minimized);
552 } else {
553 mChosenImportance = IMPORTANCE_NONE;
554 confirmationText.setText(R.string.notification_channel_disabled);
555 }
556 break;
557 default:
558 throw new IllegalArgumentException();
Julia Reynolds437cdb12018-01-03 12:27:24 -0500559 }
560
Gus Prevas894d9152018-11-12 13:51:40 -0500561 boolean isUndo = action == ACTION_UNDO;
Julia Reynolds437cdb12018-01-03 12:27:24 -0500562
Gus Prevas9abc5062018-10-31 16:11:04 -0400563 prompt.setVisibility(isUndo ? VISIBLE : GONE);
564 confirmation.setVisibility(isUndo ? GONE : VISIBLE);
565 header.setVisibility(isUndo ? VISIBLE : GONE);
Julia Reynolds437cdb12018-01-03 12:27:24 -0500566
Gus Prevas894d9152018-11-12 13:51:40 -0500567 if (animate) {
568 ObjectAnimator promptAnim = ObjectAnimator.ofFloat(prompt, View.ALPHA,
569 prompt.getAlpha(), isUndo ? 1f : 0f);
570 promptAnim.setInterpolator(isUndo ? Interpolators.ALPHA_IN : Interpolators.ALPHA_OUT);
571 ObjectAnimator confirmAnim = ObjectAnimator.ofFloat(confirmation, View.ALPHA,
572 confirmation.getAlpha(), isUndo ? 0f : 1f);
573 confirmAnim.setInterpolator(isUndo ? Interpolators.ALPHA_OUT : Interpolators.ALPHA_IN);
Julia Reynolds437cdb12018-01-03 12:27:24 -0500574
Gus Prevas894d9152018-11-12 13:51:40 -0500575 mExpandAnimation = new AnimatorSet();
576 mExpandAnimation.playTogether(promptAnim, confirmAnim);
577 mExpandAnimation.setDuration(150);
578 mExpandAnimation.addListener(new AnimatorListenerAdapter() {
579 boolean mCancelled = false;
Julia Reynolds437cdb12018-01-03 12:27:24 -0500580
Gus Prevas894d9152018-11-12 13:51:40 -0500581 @Override
582 public void onAnimationCancel(Animator animation) {
583 mCancelled = true;
Julia Reynolds437cdb12018-01-03 12:27:24 -0500584 }
Gus Prevas894d9152018-11-12 13:51:40 -0500585
586 @Override
587 public void onAnimationEnd(Animator animation) {
588 if (!mCancelled) {
589 prompt.setVisibility(isUndo ? VISIBLE : GONE);
590 confirmation.setVisibility(isUndo ? GONE : VISIBLE);
591 }
592 }
593 });
594 mExpandAnimation.start();
595 }
Rohan Shah142e2da2018-06-14 13:14:18 -0700596
597 // Since we're swapping/update the content, reset the timeout so the UI can't close
598 // immediately after the update.
599 if (mGutsContainer != null) {
600 mGutsContainer.resetFalsingCheck();
601 }
Mady Mellor87d79452017-01-10 11:52:52 -0800602 }
603
Geoffrey Pitschd94e7882017-04-06 09:52:11 -0400604 @Override
Gus Prevas9abc5062018-10-31 16:11:04 -0400605 public void onFinishedClosing() {
Gus Prevascaed15c2019-01-18 14:19:51 -0500606 if (mChosenImportance != null) {
607 mStartingChannelImportance = mChosenImportance;
Gus Prevas9abc5062018-10-31 16:11:04 -0400608 }
609 mExitReason = NotificationCounters.BLOCKING_HELPER_DISMISSED;
610
611 View prompt = findViewById(R.id.prompt);
612 ViewGroup confirmation = findViewById(R.id.confirmation);
613 View header = findViewById(R.id.header);
614 prompt.setVisibility(VISIBLE);
615 prompt.setAlpha(1f);
616 confirmation.setVisibility(GONE);
617 confirmation.setAlpha(1f);
618 header.setVisibility(VISIBLE);
619 header.setAlpha(1f);
Will Brockmana399f022019-01-30 10:59:36 -0500620
621 mMetricsLogger.write(notificationControlsLogMaker().setType(MetricsEvent.TYPE_CLOSE));
Gus Prevas9abc5062018-10-31 16:11:04 -0400622 }
623
624 @Override
Geoffrey Pitschd94e7882017-04-06 09:52:11 -0400625 public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
626 super.onInitializeAccessibilityEvent(event);
627 if (mGutsContainer != null &&
628 event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
629 if (mGutsContainer.isExposed()) {
630 event.getText().add(mContext.getString(
631 R.string.notification_channel_controls_opened_accessibility, mAppName));
632 } else {
633 event.getText().add(mContext.getString(
634 R.string.notification_channel_controls_closed_accessibility, mAppName));
635 }
636 }
637 }
638
Julia Reynolds3aedded2017-03-31 14:42:09 -0400639 private Intent getAppSettingsIntent(PackageManager pm, String packageName,
640 NotificationChannel channel, int id, String tag) {
641 Intent intent = new Intent(Intent.ACTION_MAIN)
642 .addCategory(Notification.INTENT_CATEGORY_NOTIFICATION_PREFERENCES)
643 .setPackage(packageName);
644 final List<ResolveInfo> resolveInfos = pm.queryIntentActivities(
645 intent,
646 PackageManager.MATCH_DEFAULT_ONLY
647 );
648 if (resolveInfos == null || resolveInfos.size() == 0 || resolveInfos.get(0) == null) {
649 return null;
650 }
651 final ActivityInfo activityInfo = resolveInfos.get(0).activityInfo;
652 intent.setClassName(activityInfo.packageName, activityInfo.name);
653 if (channel != null) {
654 intent.putExtra(Notification.EXTRA_CHANNEL_ID, channel.getId());
655 }
656 intent.putExtra(Notification.EXTRA_NOTIFICATION_ID, id);
657 intent.putExtra(Notification.EXTRA_NOTIFICATION_TAG, tag);
658 return intent;
659 }
660
Rohan Shahca0447e2018-03-30 15:18:27 -0700661 /**
662 * Closes the controls and commits the updated importance values (indirectly). If this view is
663 * being used to show the blocking helper, this will immediately dismiss the blocking helper and
664 * commit the updated importance.
665 *
666 * <p><b>Note,</b> this will only get called once the view is dismissing. This means that the
667 * user does not have the ability to undo the action anymore. See {@link #swapContent(boolean)}
668 * for where undo is handled.
669 */
Rohan Shah524cf7b2018-03-15 14:40:02 -0700670 @VisibleForTesting
671 void closeControls(View v) {
Rohan Shahda5dcdd2018-04-27 17:21:50 -0700672 int[] parentLoc = new int[2];
673 int[] targetLoc = new int[2];
674 mGutsContainer.getLocationOnScreen(parentLoc);
675 v.getLocationOnScreen(targetLoc);
676 final int centerX = v.getWidth() / 2;
677 final int centerY = v.getHeight() / 2;
678 final int x = targetLoc[0] - parentLoc[0] + centerX;
679 final int y = targetLoc[1] - parentLoc[1] + centerY;
680 mGutsContainer.closeControls(x, y, true /* save */, false /* force */);
Julia Reynolds437cdb12018-01-03 12:27:24 -0500681 }
682
Mady Mellor87d79452017-01-10 11:52:52 -0800683 @Override
Mady Mellor95d743c2017-01-10 12:05:27 -0800684 public void setGutsParent(NotificationGuts guts) {
685 mGutsContainer = guts;
Mady Mellor87d79452017-01-10 11:52:52 -0800686 }
687
688 @Override
Mady Mellor434180c2017-02-13 11:29:42 -0800689 public boolean willBeRemoved() {
Julia Reynolds437cdb12018-01-03 12:27:24 -0500690 return hasImportanceChanged();
Mady Mellor434180c2017-02-13 11:29:42 -0800691 }
692
693 @Override
Lucas Dupin9b08c012018-05-16 19:53:32 -0700694 public boolean shouldBeSaved() {
695 return hasImportanceChanged();
696 }
697
698 @Override
Mady Mellor87d79452017-01-10 11:52:52 -0800699 public View getContentView() {
700 return this;
701 }
702
703 @Override
Mady Mellorc2dbe492017-03-30 13:22:03 -0700704 public boolean handleCloseControls(boolean save, boolean force) {
Julia Reynoldsc65656a2018-02-12 09:55:14 -0500705 // Save regardless of the importance so we can lock the importance field if the user wants
706 // to keep getting notifications
707 if (save) {
Rohan Shahca0447e2018-03-30 15:18:27 -0700708 saveImportance();
Geoffrey Pitschdf44b602017-02-03 13:31:50 -0500709 }
Rohan Shahdd588c72018-05-09 20:32:15 -0700710 logBlockingHelperCounter(mExitReason);
Mady Mellor87d79452017-01-10 11:52:52 -0800711 return false;
712 }
Mady Mellore09fb702017-03-30 13:23:29 -0700713
714 @Override
715 public int getActualHeight() {
716 return getHeight();
717 }
Rohan Shahca0447e2018-03-30 15:18:27 -0700718
Gus Prevas533836a2018-09-24 17:15:32 -0400719 @VisibleForTesting
720 public boolean isAnimating() {
721 return mExpandAnimation != null && mExpandAnimation.isRunning();
722 }
723
Rohan Shahca0447e2018-03-30 15:18:27 -0700724 /**
725 * Runnable to either update the given channel (with a new importance value) or, if no channel
726 * is provided, update notifications enabled state for the package.
727 */
728 private static class UpdateImportanceRunnable implements Runnable {
729 private final INotificationManager mINotificationManager;
730 private final String mPackageName;
731 private final int mAppUid;
732 private final @Nullable NotificationChannel mChannelToUpdate;
733 private final int mCurrentImportance;
734 private final int mNewImportance;
735
736
737 public UpdateImportanceRunnable(INotificationManager notificationManager,
738 String packageName, int appUid, @Nullable NotificationChannel channelToUpdate,
739 int currentImportance, int newImportance) {
740 mINotificationManager = notificationManager;
741 mPackageName = packageName;
742 mAppUid = appUid;
743 mChannelToUpdate = channelToUpdate;
744 mCurrentImportance = currentImportance;
745 mNewImportance = newImportance;
746 }
747
748 @Override
749 public void run() {
750 try {
751 if (mChannelToUpdate != null) {
752 mChannelToUpdate.setImportance(mNewImportance);
753 mChannelToUpdate.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
754 mINotificationManager.updateNotificationChannelForPackage(
755 mPackageName, mAppUid, mChannelToUpdate);
756 } else {
757 // For notifications with more than one channel, update notification enabled
758 // state. If the importance was lowered, we disable notifications.
Rohan Shah590e1b22018-04-10 23:48:47 -0400759 mINotificationManager.setNotificationsEnabledWithImportanceLockForPackage(
Rohan Shahca0447e2018-03-30 15:18:27 -0700760 mPackageName, mAppUid, mNewImportance >= mCurrentImportance);
761 }
762 } catch (RemoteException e) {
763 Log.e(TAG, "Unable to update notification importance", e);
764 }
765 }
766 }
Eyal Posenera9cf9c72018-12-18 16:23:54 +0200767
Will Brockmana399f022019-01-30 10:59:36 -0500768 /**
769 * Returns a LogMaker with all available notification information.
770 * Caller should set category, type, and maybe subtype, before passing it to mMetricsLogger.
771 * @return LogMaker
772 */
Eyal Posenera9cf9c72018-12-18 16:23:54 +0200773 private LogMaker getLogMaker() {
Will Brockmana399f022019-01-30 10:59:36 -0500774 // The constructor requires a category, so also do it in the other branch for consistency.
775 return mSbn == null ? new LogMaker(MetricsEvent.NOTIFICATION_BLOCKING_HELPER)
776 : mSbn.getLogMaker().setCategory(MetricsEvent.NOTIFICATION_BLOCKING_HELPER);
777 }
778
779 /**
780 * Returns an initialized LogMaker for logging importance changes.
781 * The caller may override the type before passing it to mMetricsLogger.
782 * @return LogMaker
783 */
784 private LogMaker importanceChangeLogMaker() {
785 Integer chosenImportance =
786 mChosenImportance != null ? mChosenImportance : mStartingChannelImportance;
787 return getLogMaker().setCategory(MetricsEvent.ACTION_SAVE_IMPORTANCE)
788 .setType(MetricsEvent.TYPE_ACTION)
789 .setSubtype(chosenImportance - mStartingChannelImportance);
790 }
791
792 /**
793 * Returns an initialized LogMaker for logging open/close of the info display.
794 * The caller may override the type before passing it to mMetricsLogger.
795 * @return LogMaker
796 */
797 private LogMaker notificationControlsLogMaker() {
798 return getLogMaker().setCategory(MetricsEvent.ACTION_NOTE_CONTROLS)
799 .setType(MetricsEvent.TYPE_OPEN)
800 .setSubtype(mIsForBlockingHelper ? MetricsEvent.BLOCKING_HELPER_DISPLAY
801 : MetricsEvent.BLOCKING_HELPER_UNKNOWN);
Eyal Posenera9cf9c72018-12-18 16:23:54 +0200802 }
Mady Mellor87d79452017-01-10 11:52:52 -0800803}