/* * 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.CoreStartable; import com.android.systemui.res.R; import com.android.wm.shell.pip.tv.TvPipNotificationController; import java.util.Arrays; import javax.inject.Inject; // NOT Singleton. Started per-user. /** */ public class NotificationChannels implements CoreStartable { public static String ALERTS = "ALR"; public static String SCREENSHOTS_HEADSUP = "SCN_HEADSUP"; // Deprecated. Please use or create a more specific channel that users will better understand @Deprecated 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 static String INSTANT = "INS"; public static String SETUP = "STP"; private final Context mContext; @Inject public NotificationChannels(Context context) { mContext = 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 instant = new NotificationChannel( INSTANT, context.getString(R.string.notification_channel_instant), NotificationManager.IMPORTANCE_MIN); final NotificationChannel setup = new NotificationChannel( SETUP, context.getString(R.string.notification_channel_setup), NotificationManager.IMPORTANCE_DEFAULT); setup.setSound(null, null); 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, instant, setup, storage, createScreenshotChannel( context.getString(R.string.notification_channel_screenshot)), batteryChannel, hint )); 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(com.android.wm.shell.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 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); return screenshotChannel; } @Override public void start() { createAll(mContext); cleanUp(); } private void cleanUp() { mContext.getSystemService(NotificationManager.class).deleteNotificationChannel(GENERAL); } private static boolean isTv(Context context) { PackageManager packageManager = context.getPackageManager(); return packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK); } }