blob: 8d1bb5fe940d1f1055ec1494bfadb9242c6b445a [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
Geoffrey Pitschdf44b602017-02-03 13:31:50 -050017package com.android.systemui.statusbar;
18
Julia Reynolds3aedded2017-03-31 14:42:09 -040019import static android.app.NotificationManager.IMPORTANCE_NONE;
20
Mady Mellor87d79452017-01-10 11:52:52 -080021import android.app.INotificationManager;
Julia Reynolds3aedded2017-03-31 14:42:09 -040022import android.app.Notification;
Mady Mellor87d79452017-01-10 11:52:52 -080023import android.app.NotificationChannel;
Geoffrey Pitschdf44b602017-02-03 13:31:50 -050024import android.app.NotificationChannelGroup;
Mady Mellor87d79452017-01-10 11:52:52 -080025import android.content.Context;
Julia Reynolds3aedded2017-03-31 14:42:09 -040026import android.content.Intent;
27import android.content.pm.ActivityInfo;
Mady Mellor87d79452017-01-10 11:52:52 -080028import android.content.pm.ApplicationInfo;
29import android.content.pm.PackageInfo;
30import android.content.pm.PackageManager;
Julia Reynolds3aedded2017-03-31 14:42:09 -040031import android.content.pm.ResolveInfo;
Mady Mellor87d79452017-01-10 11:52:52 -080032import android.graphics.drawable.Drawable;
Mady Mellor87d79452017-01-10 11:52:52 -080033import android.os.RemoteException;
Julia Reynolds3aedded2017-03-31 14:42:09 -040034import android.service.notification.StatusBarNotification;
35import android.text.TextUtils;
Mady Mellor87d79452017-01-10 11:52:52 -080036import android.util.AttributeSet;
Mady Mellor87d79452017-01-10 11:52:52 -080037import android.view.View;
Geoffrey Pitschd94e7882017-04-06 09:52:11 -040038import android.view.accessibility.AccessibilityEvent;
Mady Mellor87d79452017-01-10 11:52:52 -080039import android.widget.ImageView;
40import android.widget.LinearLayout;
Mady Mellor87d79452017-01-10 11:52:52 -080041import android.widget.Switch;
42import android.widget.TextView;
43
44import com.android.internal.logging.MetricsLogger;
45import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
46import com.android.settingslib.Utils;
Mady Mellor87d79452017-01-10 11:52:52 -080047import com.android.systemui.R;
Mady Mellor87d79452017-01-10 11:52:52 -080048
Geoffrey Pitschd0856f02017-02-16 10:51:18 -050049import java.lang.IllegalArgumentException;
50import java.util.List;
Mady Mellor87d79452017-01-10 11:52:52 -080051import java.util.Set;
52
53/**
54 * The guts of a notification revealed when performing a long press.
55 */
Mady Mellor95d743c2017-01-10 12:05:27 -080056public class NotificationInfo extends LinearLayout implements NotificationGuts.GutsContent {
Mady Mellor87d79452017-01-10 11:52:52 -080057 private static final String TAG = "InfoGuts";
58
59 private INotificationManager mINotificationManager;
Geoffrey Pitschd0856f02017-02-16 10:51:18 -050060 private String mPkg;
Geoffrey Pitschd94e7882017-04-06 09:52:11 -040061 private String mAppName;
Geoffrey Pitschd0856f02017-02-16 10:51:18 -050062 private int mAppUid;
63 private List<NotificationChannel> mNotificationChannels;
64 private NotificationChannel mSingleNotificationChannel;
Geoffrey Pitsch1fbf66e2017-05-09 11:32:27 -040065 private boolean mIsSingleDefaultChannel;
Julia Reynolds3aedded2017-03-31 14:42:09 -040066 private StatusBarNotification mSbn;
Mady Mellor87d79452017-01-10 11:52:52 -080067 private int mStartingUserImportance;
Mady Mellor87d79452017-01-10 11:52:52 -080068
Geoffrey Pitschdf44b602017-02-03 13:31:50 -050069 private TextView mNumChannelsView;
70 private View mChannelDisabledView;
Julia Reynolds3aedded2017-03-31 14:42:09 -040071 private TextView mSettingsLinkView;
Mady Mellor87d79452017-01-10 11:52:52 -080072 private Switch mChannelEnabledSwitch;
Geoffrey Pitsch5278d3d2017-03-29 13:39:10 -040073 private CheckSaveListener mCheckSaveListener;
Julia Reynolds3aedded2017-03-31 14:42:09 -040074 private OnAppSettingsClickListener mAppSettingsClickListener;
75 private PackageManager mPm;
Mady Mellor87d79452017-01-10 11:52:52 -080076
Mady Mellor95d743c2017-01-10 12:05:27 -080077 private NotificationGuts mGutsContainer;
Mady Mellor87d79452017-01-10 11:52:52 -080078
79 public NotificationInfo(Context context, AttributeSet attrs) {
80 super(context, attrs);
81 }
82
Geoffrey Pitsch5278d3d2017-03-29 13:39:10 -040083 // Specify a CheckSaveListener to override when/if the user's changes are committed.
84 public interface CheckSaveListener {
85 // Invoked when importance has changed and the NotificationInfo wants to try to save it.
86 // Listener should run saveImportance unless the change should be canceled.
Eliot Courtney47098cb2017-10-18 17:30:30 +090087 void checkSave(Runnable saveImportance, StatusBarNotification sbn);
Geoffrey Pitsch5278d3d2017-03-29 13:39:10 -040088 }
89
Jason Monk2a6ea9c2017-01-26 11:14:51 -050090 public interface OnSettingsClickListener {
Geoffrey Pitschd0856f02017-02-16 10:51:18 -050091 void onClick(View v, NotificationChannel channel, int appUid);
Mady Mellor87d79452017-01-10 11:52:52 -080092 }
93
Julia Reynolds3aedded2017-03-31 14:42:09 -040094 public interface OnAppSettingsClickListener {
95 void onClick(View v, Intent intent);
96 }
97
Jason Monk2a6ea9c2017-01-26 11:14:51 -050098 public void bindNotification(final PackageManager pm,
99 final INotificationManager iNotificationManager,
Geoffrey Pitschd0856f02017-02-16 10:51:18 -0500100 final String pkg,
101 final List<NotificationChannel> notificationChannels,
Julia Reynolds3aedded2017-03-31 14:42:09 -0400102 int startingUserImportance,
103 final StatusBarNotification sbn,
Mady Mellor87d79452017-01-10 11:52:52 -0800104 OnSettingsClickListener onSettingsClick,
Julia Reynolds3aedded2017-03-31 14:42:09 -0400105 OnAppSettingsClickListener onAppSettingsClick,
Geoffrey Pitsch5278d3d2017-03-29 13:39:10 -0400106 OnClickListener onDoneClick,
107 CheckSaveListener checkSaveListener,
108 final Set<String> nonBlockablePkgs)
Geoffrey Pitschd0856f02017-02-16 10:51:18 -0500109 throws RemoteException {
Mady Mellor87d79452017-01-10 11:52:52 -0800110 mINotificationManager = iNotificationManager;
Geoffrey Pitschd0856f02017-02-16 10:51:18 -0500111 mPkg = pkg;
112 mNotificationChannels = notificationChannels;
Geoffrey Pitsch5278d3d2017-03-29 13:39:10 -0400113 mCheckSaveListener = checkSaveListener;
Julia Reynolds3aedded2017-03-31 14:42:09 -0400114 mSbn = sbn;
115 mPm = pm;
116 mAppSettingsClickListener = onAppSettingsClick;
Julia Reynolds3aedded2017-03-31 14:42:09 -0400117 mStartingUserImportance = startingUserImportance;
Geoffrey Pitschd94e7882017-04-06 09:52:11 -0400118 mAppName = mPkg;
Mady Mellor87d79452017-01-10 11:52:52 -0800119 Drawable pkgicon = null;
Julia Reynolds5a311932017-03-01 16:33:44 -0500120 CharSequence channelNameText = "";
121 ApplicationInfo info = null;
Mady Mellor87d79452017-01-10 11:52:52 -0800122 try {
Geoffrey Pitschd0856f02017-02-16 10:51:18 -0500123 info = pm.getApplicationInfo(mPkg,
Mady Mellor87d79452017-01-10 11:52:52 -0800124 PackageManager.MATCH_UNINSTALLED_PACKAGES
125 | PackageManager.MATCH_DISABLED_COMPONENTS
126 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
127 | PackageManager.MATCH_DIRECT_BOOT_AWARE);
128 if (info != null) {
Julia Reynolds33bef2c2017-09-05 11:07:18 -0400129 mAppUid = sbn.getUid();
Geoffrey Pitschd94e7882017-04-06 09:52:11 -0400130 mAppName = String.valueOf(pm.getApplicationLabel(info));
Mady Mellor87d79452017-01-10 11:52:52 -0800131 pkgicon = pm.getApplicationIcon(info);
132 }
133 } catch (PackageManager.NameNotFoundException e) {
134 // app is gone, just show package name and generic icon
135 pkgicon = pm.getDefaultActivityIcon();
136 }
Geoffrey Pitschdf44b602017-02-03 13:31:50 -0500137 ((ImageView) findViewById(R.id.pkgicon)).setImageDrawable(pkgicon);
138
Geoffrey Pitschd034d292017-05-12 11:59:20 -0400139 int numTotalChannels = iNotificationManager.getNumNotificationChannelsForPackage(
140 pkg, mAppUid, false /* includeDeleted */);
141 if (mNotificationChannels.isEmpty()) {
142 throw new IllegalArgumentException("bindNotification requires at least one channel");
143 } else {
144 if (mNotificationChannels.size() == 1) {
145 mSingleNotificationChannel = mNotificationChannels.get(0);
146 // Special behavior for the Default channel if no other channels have been defined.
147 mIsSingleDefaultChannel =
148 (mSingleNotificationChannel.getId()
149 .equals(NotificationChannel.DEFAULT_CHANNEL_ID) &&
150 numTotalChannels <= 1);
151 } else {
152 mSingleNotificationChannel = null;
153 mIsSingleDefaultChannel = false;
154 }
155 }
156
Geoffrey Pitschb43486a2017-06-01 13:45:59 -0400157 boolean nonBlockable = false;
158 try {
159 final PackageInfo pkgInfo = pm.getPackageInfo(pkg, PackageManager.GET_SIGNATURES);
160 if (Utils.isSystemPackage(getResources(), pm, pkgInfo)) {
161 final int numChannels = mNotificationChannels.size();
162 for (int i = 0; i < numChannels; i++) {
163 final NotificationChannel notificationChannel = mNotificationChannels.get(i);
164 // If any of the system channels is not blockable, the bundle is nonblockable
165 if (!notificationChannel.isBlockableSystem()) {
166 nonBlockable = true;
167 break;
168 }
169 }
170 }
171 } catch (PackageManager.NameNotFoundException e) {
172 // unlikely.
173 }
174 if (nonBlockablePkgs != null) {
175 nonBlockable |= nonBlockablePkgs.contains(pkg);
176 }
177
Geoffrey Pitschd0856f02017-02-16 10:51:18 -0500178 String channelsDescText;
Alan Viverette51efddb2017-04-05 10:00:01 -0400179 mNumChannelsView = findViewById(R.id.num_channels_desc);
Geoffrey Pitschb43486a2017-06-01 13:45:59 -0400180 if (nonBlockable) {
181 channelsDescText = mContext.getString(R.string.notification_unblockable_desc);
182 } else if (mIsSingleDefaultChannel) {
Geoffrey Pitschee8c81e2017-03-23 11:38:56 -0400183 channelsDescText = mContext.getString(R.string.notification_default_channel_desc);
184 } else {
185 switch (mNotificationChannels.size()) {
186 case 1:
187 channelsDescText = String.format(mContext.getResources().getQuantityString(
Geoffrey Pitsch1fbf66e2017-05-09 11:32:27 -0400188 R.plurals.notification_num_channels_desc, numTotalChannels),
189 numTotalChannels);
Geoffrey Pitschee8c81e2017-03-23 11:38:56 -0400190 break;
191 case 2:
192 channelsDescText = mContext.getString(
193 R.string.notification_channels_list_desc_2,
194 mNotificationChannels.get(0).getName(),
195 mNotificationChannels.get(1).getName());
196 break;
197 default:
198 final int numOthers = mNotificationChannels.size() - 2;
199 channelsDescText = String.format(
200 mContext.getResources().getQuantityString(
201 R.plurals.notification_channels_list_desc_2_and_others,
202 numOthers),
203 mNotificationChannels.get(0).getName(),
204 mNotificationChannels.get(1).getName(),
205 numOthers);
206 }
Geoffrey Pitschd0856f02017-02-16 10:51:18 -0500207 }
208 mNumChannelsView.setText(channelsDescText);
Mady Mellor87d79452017-01-10 11:52:52 -0800209
Geoffrey Pitschd0856f02017-02-16 10:51:18 -0500210 if (mSingleNotificationChannel == null) {
211 // Multiple channels don't use a channel name for the title.
212 channelNameText = mContext.getString(R.string.notification_num_channels,
213 mNotificationChannels.size());
Geoffrey Pitschb43486a2017-06-01 13:45:59 -0400214 } else if (mIsSingleDefaultChannel || nonBlockable) {
215 // If this is the default channel or the app is unblockable,
216 // don't use our channel-specific text.
Mady Mellor87d79452017-01-10 11:52:52 -0800217 channelNameText = mContext.getString(R.string.notification_header_default_channel);
218 } else {
Geoffrey Pitschd0856f02017-02-16 10:51:18 -0500219 channelNameText = mSingleNotificationChannel.getName();
Mady Mellor87d79452017-01-10 11:52:52 -0800220 }
Geoffrey Pitschd94e7882017-04-06 09:52:11 -0400221 ((TextView) findViewById(R.id.pkgname)).setText(mAppName);
Mady Mellor87d79452017-01-10 11:52:52 -0800222 ((TextView) findViewById(R.id.channel_name)).setText(channelNameText);
223
Geoffrey Pitschdf44b602017-02-03 13:31:50 -0500224 // Set group information if this channel has an associated group.
225 CharSequence groupName = null;
Geoffrey Pitschd0856f02017-02-16 10:51:18 -0500226 if (mSingleNotificationChannel != null && mSingleNotificationChannel.getGroup() != null) {
227 final NotificationChannelGroup notificationChannelGroup =
228 iNotificationManager.getNotificationChannelGroupForPackage(
229 mSingleNotificationChannel.getGroup(), pkg, mAppUid);
230 if (notificationChannelGroup != null) {
231 groupName = notificationChannelGroup.getName();
Geoffrey Pitschdf44b602017-02-03 13:31:50 -0500232 }
Mady Mellor87d79452017-01-10 11:52:52 -0800233 }
Geoffrey Pitschdf44b602017-02-03 13:31:50 -0500234 TextView groupNameView = ((TextView) findViewById(R.id.group_name));
235 TextView groupDividerView = ((TextView) findViewById(R.id.pkg_group_divider));
236 if (groupName != null) {
237 groupNameView.setText(groupName);
238 groupNameView.setVisibility(View.VISIBLE);
239 groupDividerView.setVisibility(View.VISIBLE);
240 } else {
241 groupNameView.setVisibility(View.GONE);
242 groupDividerView.setVisibility(View.GONE);
243 }
Mady Mellor87d79452017-01-10 11:52:52 -0800244
Geoffrey Pitschdf44b602017-02-03 13:31:50 -0500245 bindButtons(nonBlockable);
Mady Mellor87d79452017-01-10 11:52:52 -0800246
247 // Top-level importance group
Geoffrey Pitschdf44b602017-02-03 13:31:50 -0500248 mChannelDisabledView = findViewById(R.id.channel_disabled);
Geoffrey Pitschd0856f02017-02-16 10:51:18 -0500249 updateSecondaryText();
Geoffrey Pitschdf44b602017-02-03 13:31:50 -0500250
251 // Settings button.
252 final TextView settingsButton = (TextView) findViewById(R.id.more_settings);
Geoffrey Pitschd0856f02017-02-16 10:51:18 -0500253 if (mAppUid >= 0 && onSettingsClick != null) {
Geoffrey Pitsch029a3fa2017-03-30 13:01:57 -0400254 settingsButton.setVisibility(View.VISIBLE);
Geoffrey Pitschd0856f02017-02-16 10:51:18 -0500255 final int appUidF = mAppUid;
Geoffrey Pitschdf44b602017-02-03 13:31:50 -0500256 settingsButton.setOnClickListener(
257 (View view) -> {
Geoffrey Pitschd0856f02017-02-16 10:51:18 -0500258 onSettingsClick.onClick(view, mSingleNotificationChannel, appUidF);
Geoffrey Pitschdf44b602017-02-03 13:31:50 -0500259 });
Geoffrey Pitschb43486a2017-06-01 13:45:59 -0400260 if (numTotalChannels <= 1 || nonBlockable) {
Geoffrey Pitschdf44b602017-02-03 13:31:50 -0500261 settingsButton.setText(R.string.notification_more_settings);
Geoffrey Pitschb43486a2017-06-01 13:45:59 -0400262 } else {
263 settingsButton.setText(R.string.notification_all_categories);
Geoffrey Pitschdf44b602017-02-03 13:31:50 -0500264 }
Geoffrey Pitschdf44b602017-02-03 13:31:50 -0500265 } else {
266 settingsButton.setVisibility(View.GONE);
267 }
268
269 // Done button.
270 final TextView doneButton = (TextView) findViewById(R.id.done);
271 doneButton.setText(R.string.notification_done);
272 doneButton.setOnClickListener(onDoneClick);
Julia Reynolds3aedded2017-03-31 14:42:09 -0400273
274 // Optional settings link
275 updateAppSettingsLink();
Mady Mellor87d79452017-01-10 11:52:52 -0800276 }
277
Geoffrey Pitsch5278d3d2017-03-29 13:39:10 -0400278 private boolean hasImportanceChanged() {
Geoffrey Pitschd0856f02017-02-16 10:51:18 -0500279 return mSingleNotificationChannel != null &&
Geoffrey Pitsch8c8dbde2017-04-20 11:44:33 -0400280 mChannelEnabledSwitch != null &&
Geoffrey Pitschd0856f02017-02-16 10:51:18 -0500281 mStartingUserImportance != getSelectedImportance();
Mady Mellor87d79452017-01-10 11:52:52 -0800282 }
283
Geoffrey Pitschdf44b602017-02-03 13:31:50 -0500284 private void saveImportance() {
Geoffrey Pitsch8c8dbde2017-04-20 11:44:33 -0400285 if (!hasImportanceChanged()) {
Geoffrey Pitschd0856f02017-02-16 10:51:18 -0500286 return;
287 }
Geoffrey Pitsch8c8dbde2017-04-20 11:44:33 -0400288 final int selectedImportance = getSelectedImportance();
Mady Mellor87d79452017-01-10 11:52:52 -0800289 MetricsLogger.action(mContext, MetricsEvent.ACTION_SAVE_IMPORTANCE,
290 selectedImportance - mStartingUserImportance);
Geoffrey Pitschd0856f02017-02-16 10:51:18 -0500291 mSingleNotificationChannel.setImportance(selectedImportance);
Julia Reynolds8ceb5792017-04-11 11:32:44 -0400292 mSingleNotificationChannel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
Mady Mellor87d79452017-01-10 11:52:52 -0800293 try {
294 mINotificationManager.updateNotificationChannelForPackage(
Geoffrey Pitschd0856f02017-02-16 10:51:18 -0500295 mPkg, mAppUid, mSingleNotificationChannel);
Mady Mellor87d79452017-01-10 11:52:52 -0800296 } catch (RemoteException e) {
297 // :(
298 }
299 }
300
301 private int getSelectedImportance() {
302 if (!mChannelEnabledSwitch.isChecked()) {
Julia Reynolds3aedded2017-03-31 14:42:09 -0400303 return IMPORTANCE_NONE;
Mady Mellor87d79452017-01-10 11:52:52 -0800304 } else {
Geoffrey Pitschdf44b602017-02-03 13:31:50 -0500305 return mStartingUserImportance;
Mady Mellor87d79452017-01-10 11:52:52 -0800306 }
307 }
308
Geoffrey Pitschdf44b602017-02-03 13:31:50 -0500309 private void bindButtons(final boolean nonBlockable) {
Mady Mellor87d79452017-01-10 11:52:52 -0800310 // Enabled Switch
311 mChannelEnabledSwitch = (Switch) findViewById(R.id.channel_enabled_switch);
Geoffrey Pitschdf44b602017-02-03 13:31:50 -0500312 mChannelEnabledSwitch.setChecked(
Julia Reynolds3aedded2017-03-31 14:42:09 -0400313 mStartingUserImportance != IMPORTANCE_NONE);
Geoffrey Pitschd0856f02017-02-16 10:51:18 -0500314 final boolean visible = !nonBlockable && mSingleNotificationChannel != null;
315 mChannelEnabledSwitch.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
Mady Mellor87d79452017-01-10 11:52:52 -0800316
Mady Mellor87d79452017-01-10 11:52:52 -0800317 // Callback when checked.
318 mChannelEnabledSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
Mady Mellor95d743c2017-01-10 12:05:27 -0800319 if (mGutsContainer != null) {
320 mGutsContainer.resetFalsingCheck();
Geoffrey Pitschdf44b602017-02-03 13:31:50 -0500321 }
Geoffrey Pitschd0856f02017-02-16 10:51:18 -0500322 updateSecondaryText();
Julia Reynolds3aedded2017-03-31 14:42:09 -0400323 updateAppSettingsLink();
Mady Mellor87d79452017-01-10 11:52:52 -0800324 });
Mady Mellor87d79452017-01-10 11:52:52 -0800325 }
326
Geoffrey Pitschd94e7882017-04-06 09:52:11 -0400327 @Override
328 public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
329 super.onInitializeAccessibilityEvent(event);
330 if (mGutsContainer != null &&
331 event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
332 if (mGutsContainer.isExposed()) {
333 event.getText().add(mContext.getString(
334 R.string.notification_channel_controls_opened_accessibility, mAppName));
335 } else {
336 event.getText().add(mContext.getString(
337 R.string.notification_channel_controls_closed_accessibility, mAppName));
338 }
339 }
340 }
341
Geoffrey Pitschd0856f02017-02-16 10:51:18 -0500342 private void updateSecondaryText() {
Geoffrey Pitschd0856f02017-02-16 10:51:18 -0500343 final boolean disabled = mSingleNotificationChannel != null &&
Julia Reynolds3aedded2017-03-31 14:42:09 -0400344 getSelectedImportance() == IMPORTANCE_NONE;
Geoffrey Pitschee8c81e2017-03-23 11:38:56 -0400345 if (disabled) {
Geoffrey Pitschd0856f02017-02-16 10:51:18 -0500346 mChannelDisabledView.setVisibility(View.VISIBLE);
347 mNumChannelsView.setVisibility(View.GONE);
Geoffrey Pitschdf44b602017-02-03 13:31:50 -0500348 } else {
Geoffrey Pitschd0856f02017-02-16 10:51:18 -0500349 mChannelDisabledView.setVisibility(View.GONE);
Geoffrey Pitsch1fbf66e2017-05-09 11:32:27 -0400350 mNumChannelsView.setVisibility(mIsSingleDefaultChannel ? View.INVISIBLE : View.VISIBLE);
Mady Mellor87d79452017-01-10 11:52:52 -0800351 }
352 }
353
Julia Reynolds3aedded2017-03-31 14:42:09 -0400354 private void updateAppSettingsLink() {
355 mSettingsLinkView = findViewById(R.id.app_settings);
356 Intent settingsIntent = getAppSettingsIntent(mPm, mPkg, mSingleNotificationChannel,
357 mSbn.getId(), mSbn.getTag());
358 if (settingsIntent != null && getSelectedImportance() != IMPORTANCE_NONE
359 && !TextUtils.isEmpty(mSbn.getNotification().getSettingsText())) {
360 mSettingsLinkView.setVisibility(View.VISIBLE);
361 mSettingsLinkView.setText(mContext.getString(R.string.notification_app_settings,
362 mSbn.getNotification().getSettingsText()));
363 mSettingsLinkView.setOnClickListener((View view) -> {
364 mAppSettingsClickListener.onClick(view, settingsIntent);
365 });
366 } else {
367 mSettingsLinkView.setVisibility(View.GONE);
368 }
369 }
370
371 private Intent getAppSettingsIntent(PackageManager pm, String packageName,
372 NotificationChannel channel, int id, String tag) {
373 Intent intent = new Intent(Intent.ACTION_MAIN)
374 .addCategory(Notification.INTENT_CATEGORY_NOTIFICATION_PREFERENCES)
375 .setPackage(packageName);
376 final List<ResolveInfo> resolveInfos = pm.queryIntentActivities(
377 intent,
378 PackageManager.MATCH_DEFAULT_ONLY
379 );
380 if (resolveInfos == null || resolveInfos.size() == 0 || resolveInfos.get(0) == null) {
381 return null;
382 }
383 final ActivityInfo activityInfo = resolveInfos.get(0).activityInfo;
384 intent.setClassName(activityInfo.packageName, activityInfo.name);
385 if (channel != null) {
386 intent.putExtra(Notification.EXTRA_CHANNEL_ID, channel.getId());
387 }
388 intent.putExtra(Notification.EXTRA_NOTIFICATION_ID, id);
389 intent.putExtra(Notification.EXTRA_NOTIFICATION_TAG, tag);
390 return intent;
391 }
392
Mady Mellor87d79452017-01-10 11:52:52 -0800393 @Override
Mady Mellor95d743c2017-01-10 12:05:27 -0800394 public void setGutsParent(NotificationGuts guts) {
395 mGutsContainer = guts;
Mady Mellor87d79452017-01-10 11:52:52 -0800396 }
397
398 @Override
Mady Mellor434180c2017-02-13 11:29:42 -0800399 public boolean willBeRemoved() {
Geoffrey Pitsch8c8dbde2017-04-20 11:44:33 -0400400 return mChannelEnabledSwitch != null && !mChannelEnabledSwitch.isChecked();
Mady Mellor434180c2017-02-13 11:29:42 -0800401 }
402
403 @Override
Mady Mellor87d79452017-01-10 11:52:52 -0800404 public View getContentView() {
405 return this;
406 }
407
408 @Override
Mady Mellorc2dbe492017-03-30 13:22:03 -0700409 public boolean handleCloseControls(boolean save, boolean force) {
Geoffrey Pitsch5278d3d2017-03-29 13:39:10 -0400410 if (save && hasImportanceChanged()) {
411 if (mCheckSaveListener != null) {
Eliot Courtney47098cb2017-10-18 17:30:30 +0900412 mCheckSaveListener.checkSave(this::saveImportance, mSbn);
Geoffrey Pitsch5278d3d2017-03-29 13:39:10 -0400413 } else {
414 saveImportance();
415 }
Geoffrey Pitschdf44b602017-02-03 13:31:50 -0500416 }
Mady Mellor87d79452017-01-10 11:52:52 -0800417 return false;
418 }
Mady Mellore09fb702017-03-30 13:23:29 -0700419
420 @Override
421 public int getActualHeight() {
422 return getHeight();
423 }
Mady Mellor87d79452017-01-10 11:52:52 -0800424}