/* * Copyright (C) 2017 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.util; import android.app.NotificationChannel; import android.app.NotificationManager; import android.content.Context; import android.content.pm.PackageManager; import android.media.AudioAttributes; import android.net.Uri; import android.provider.Settings; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.R; import com.android.systemui.SystemUI; import com.android.wm.shell.pip.tv.TvPipNotificationController; import java.util.Arrays; public class NotificationChannels extends SystemUI { public static String ALERTS = "ALR"; public static String SCREENSHOTS_LEGACY = "SCN"; public static String SCREENSHOTS_HEADSUP = "SCN_HEADSUP"; public static String GENERAL = "GEN"; public static String STORAGE = "DSK"; public static String BATTERY = "BAT"; public static String TVPIP = TvPipNotificationController.NOTIFICATION_CHANNEL; // "TVPIP" public static String HINTS = "HNT"; public NotificationChannels(Context context) { super(context); } public static void createAll(Context context) { final NotificationManager nm = context.getSystemService(NotificationManager.class); final NotificationChannel batteryChannel = new NotificationChannel(BATTERY, context.getString(R.string.notification_channel_battery), NotificationManager.IMPORTANCE_MAX); final String soundPath = Settings.Global.getString(context.getContentResolver(), Settings.Global.LOW_BATTERY_SOUND); batteryChannel.setSound(Uri.parse("file://" + soundPath), new AudioAttributes.Builder() .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) .setUsage(AudioAttributes.USAGE_NOTIFICATION_EVENT) .build()); batteryChannel.setBlockable(true); final NotificationChannel alerts = new NotificationChannel( ALERTS, context.getString(R.string.notification_channel_alerts), NotificationManager.IMPORTANCE_HIGH); final NotificationChannel general = new NotificationChannel( GENERAL, context.getString(R.string.notification_channel_general), NotificationManager.IMPORTANCE_MIN); final NotificationChannel storage = new NotificationChannel( STORAGE, context.getString(R.string.notification_channel_storage), isTv(context) ? NotificationManager.IMPORTANCE_DEFAULT : NotificationManager.IMPORTANCE_LOW); final NotificationChannel hint = new NotificationChannel( HINTS, context.getString(R.string.notification_channel_hints), NotificationManager.IMPORTANCE_DEFAULT); // No need to bypass DND. nm.createNotificationChannels(Arrays.asList( alerts, general, storage, createScreenshotChannel( context.getString(R.string.notification_channel_screenshot), nm.getNotificationChannel(SCREENSHOTS_LEGACY)), batteryChannel, hint )); // Delete older SS channel if present. // Screenshots promoted to heads-up in P, this cleans up the lower priority channel from O. // This line can be deleted in Q. nm.deleteNotificationChannel(SCREENSHOTS_LEGACY); if (isTv(context)) { // TV specific notification channel for TV PIP controls. // Importance should be {@link NotificationManager#IMPORTANCE_MAX} to have the highest // priority, so it can be shown in all times. nm.createNotificationChannel(new NotificationChannel( TVPIP, context.getString(R.string.notification_channel_tv_pip), NotificationManager.IMPORTANCE_MAX)); } } /** * Set up screenshot channel, respecting any previously committed user settings on legacy * channel. * @return */ @VisibleForTesting static NotificationChannel createScreenshotChannel( String name, NotificationChannel legacySS) { NotificationChannel screenshotChannel = new NotificationChannel(SCREENSHOTS_HEADSUP, name, NotificationManager.IMPORTANCE_HIGH); // pop on screen screenshotChannel.setSound(null, // silent new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_NOTIFICATION).build()); screenshotChannel.setBlockable(true); if (legacySS != null) { // Respect any user modified fields from the old channel. int userlock = legacySS.getUserLockedFields(); if ((userlock & NotificationChannel.USER_LOCKED_IMPORTANCE) != 0) { screenshotChannel.setImportance(legacySS.getImportance()); } if ((userlock & NotificationChannel.USER_LOCKED_SOUND) != 0) { screenshotChannel.setSound(legacySS.getSound(), legacySS.getAudioAttributes()); } if ((userlock & NotificationChannel.USER_LOCKED_VIBRATION) != 0) { screenshotChannel.setVibrationPattern(legacySS.getVibrationPattern()); } if ((userlock & NotificationChannel.USER_LOCKED_LIGHTS) != 0) { screenshotChannel.setLightColor(legacySS.getLightColor()); } // skip show_badge, irrelevant for system channel } return screenshotChannel; } @Override public void start() { createAll(mContext); } private static boolean isTv(Context context) { PackageManager packageManager = context.getPackageManager(); return packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK); } }