[Audiosharing] Show add source notif when app not in foreground
Test: atest Bug: 395786392 Flag: com.android.settingslib.flags.enable_le_audio_sharing Change-Id: I3c88c4209cf34c8f337965ffb45fb8e9a4db0e05
This commit is contained in:
@@ -16,17 +16,25 @@
|
||||
|
||||
package com.android.settings.connecteddevice.audiosharing;
|
||||
|
||||
import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast.EXTRA_BLUETOOTH_DEVICE;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
|
||||
import com.android.settings.R;
|
||||
@@ -43,12 +51,19 @@ public class AudioSharingReceiver extends BroadcastReceiver {
|
||||
"com.android.settings.BLUETOOTH_AUDIO_SHARING_SETTINGS";
|
||||
private static final String ACTION_LE_AUDIO_SHARING_STOP =
|
||||
"com.android.settings.action.BLUETOOTH_LE_AUDIO_SHARING_STOP";
|
||||
private static final String ACTION_LE_AUDIO_SHARING_ADD_SOURCE =
|
||||
"com.android.settings.action.BLUETOOTH_LE_AUDIO_SHARING_ADD_SOURCE";
|
||||
private static final String ACTION_LE_AUDIO_SHARING_CANCEL_NOTIF =
|
||||
"com.android.settings.action.BLUETOOTH_LE_AUDIO_SHARING_CANCEL_NOTIF";
|
||||
private static final String EXTRA_NOTIF_ID = "NOTIF_ID";
|
||||
private static final String CHANNEL_ID = "bluetooth_notification_channel";
|
||||
private static final int NOTIFICATION_ID =
|
||||
private static final int AUDIO_SHARING_NOTIFICATION_ID =
|
||||
com.android.settingslib.R.drawable.ic_bt_le_audio_sharing;
|
||||
private static final int ADD_SOURCE_NOTIFICATION_ID = R.string.share_audio_notification_title;
|
||||
private static final int NOTIF_AUTO_DISMISS_MILLIS = 300000; //5mins
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
public void onReceive(@NonNull Context context, @NonNull Intent intent) {
|
||||
String action = intent.getAction();
|
||||
if (action == null) {
|
||||
Log.w(TAG, "Received unexpected intent with null action.");
|
||||
@@ -74,10 +89,12 @@ public class AudioSharingReceiver extends BroadcastReceiver {
|
||||
// isLeAudioBroadcastSourceSupported() and BluetoothAdapter#
|
||||
// isLeAudioBroadcastAssistantSupported() always return FEATURE_SUPPORTED
|
||||
// or FEATURE_NOT_SUPPORTED when BT and BLE off
|
||||
cancelSharingNotification(context);
|
||||
cancelSharingNotification(context, AUDIO_SHARING_NOTIFICATION_ID);
|
||||
metricsFeatureProvider.action(
|
||||
context, SettingsEnums.ACTION_CANCEL_AUDIO_SHARING_NOTIFICATION,
|
||||
LocalBluetoothLeBroadcast.ACTION_LE_AUDIO_SHARING_STATE_CHANGE);
|
||||
cancelSharingNotification(context, ADD_SOURCE_NOTIFICATION_ID);
|
||||
// TODO: add metric
|
||||
} else {
|
||||
Log.w(
|
||||
TAG,
|
||||
@@ -99,27 +116,40 @@ public class AudioSharingReceiver extends BroadcastReceiver {
|
||||
// isLeAudioBroadcastSourceSupported() and BluetoothAdapter#
|
||||
// isLeAudioBroadcastAssistantSupported() always return FEATURE_SUPPORTED
|
||||
// or FEATURE_NOT_SUPPORTED when BT and BLE off
|
||||
cancelSharingNotification(context);
|
||||
cancelSharingNotification(context, AUDIO_SHARING_NOTIFICATION_ID);
|
||||
metricsFeatureProvider.action(
|
||||
context, SettingsEnums.ACTION_CANCEL_AUDIO_SHARING_NOTIFICATION,
|
||||
ACTION_LE_AUDIO_SHARING_STOP);
|
||||
cancelSharingNotification(context, ADD_SOURCE_NOTIFICATION_ID);
|
||||
break;
|
||||
case LocalBluetoothLeBroadcast.ACTION_LE_AUDIO_SHARING_DEVICE_CONNECTED:
|
||||
if (!BluetoothUtils.isAudioSharingUIAvailable(context)) {
|
||||
Log.d(TAG, "Skip ACTION_LE_AUDIO_SHARING_DEVICE_CONNECTED, feature disabled.");
|
||||
return;
|
||||
}
|
||||
BluetoothDevice device = intent.getParcelableExtra(EXTRA_BLUETOOTH_DEVICE,
|
||||
BluetoothDevice.class);
|
||||
if (device == null) {
|
||||
Log.d(TAG, "Skip ACTION_LE_AUDIO_SHARING_DEVICE_CONNECTED, null device");
|
||||
return;
|
||||
}
|
||||
if (isAppInForeground(context)) {
|
||||
// TODO: show dialog
|
||||
Log.d(TAG, "App in foreground, show share audio dialog");
|
||||
} else {
|
||||
Log.d(TAG, "App not in foreground, show share audio notification");
|
||||
showAddSourceNotification(context, device);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Log.w(TAG, "Received unexpected intent " + intent.getAction());
|
||||
}
|
||||
}
|
||||
|
||||
private void showSharingNotification(Context context) {
|
||||
private void showSharingNotification(@NonNull Context context) {
|
||||
NotificationManager nm = context.getSystemService(NotificationManager.class);
|
||||
if (nm.getNotificationChannel(CHANNEL_ID) == null) {
|
||||
Log.d(TAG, "Create bluetooth notification channel");
|
||||
NotificationChannel notificationChannel =
|
||||
new NotificationChannel(
|
||||
CHANNEL_ID,
|
||||
context.getString(com.android.settings.R.string.bluetooth),
|
||||
NotificationManager.IMPORTANCE_HIGH);
|
||||
nm.createNotificationChannel(notificationChannel);
|
||||
}
|
||||
if (nm == null) return;
|
||||
createNotificationChannelIfNeeded(nm, context);
|
||||
Intent stopIntent =
|
||||
new Intent(ACTION_LE_AUDIO_SHARING_STOP).setPackage(context.getPackageName());
|
||||
PendingIntent stopPendingIntent =
|
||||
@@ -174,11 +204,110 @@ public class AudioSharingReceiver extends BroadcastReceiver {
|
||||
.addAction(stopAction)
|
||||
.addAction(settingsAction)
|
||||
.addExtras(extras);
|
||||
nm.notify(NOTIFICATION_ID, builder.build());
|
||||
nm.notify(AUDIO_SHARING_NOTIFICATION_ID, builder.build());
|
||||
}
|
||||
|
||||
private void cancelSharingNotification(Context context) {
|
||||
private void showAddSourceNotification(@NonNull Context context,
|
||||
@NonNull BluetoothDevice device) {
|
||||
NotificationManager nm = context.getSystemService(NotificationManager.class);
|
||||
nm.cancel(NOTIFICATION_ID);
|
||||
if (nm == null) return;
|
||||
createNotificationChannelIfNeeded(nm, context);
|
||||
Intent addSourceIntent =
|
||||
new Intent(ACTION_LE_AUDIO_SHARING_ADD_SOURCE).setPackage(context.getPackageName())
|
||||
.putExtra(EXTRA_BLUETOOTH_DEVICE, device);
|
||||
PendingIntent addSourcePendingIntent =
|
||||
PendingIntent.getBroadcast(
|
||||
context,
|
||||
R.string.audio_sharing_share_button_label,
|
||||
addSourceIntent,
|
||||
PendingIntent.FLAG_IMMUTABLE);
|
||||
NotificationCompat.Action addSourceAction =
|
||||
new NotificationCompat.Action.Builder(
|
||||
0,
|
||||
context.getString(R.string.audio_sharing_share_button_label),
|
||||
addSourcePendingIntent)
|
||||
.build();
|
||||
Intent cancelIntent = new Intent(ACTION_LE_AUDIO_SHARING_CANCEL_NOTIF).setPackage(
|
||||
context.getPackageName())
|
||||
.putExtra(EXTRA_NOTIF_ID, ADD_SOURCE_NOTIFICATION_ID);
|
||||
PendingIntent cancelPendingIntent =
|
||||
PendingIntent.getBroadcast(
|
||||
context,
|
||||
R.string.cancel,
|
||||
cancelIntent,
|
||||
PendingIntent.FLAG_IMMUTABLE);
|
||||
NotificationCompat.Action cancelAction =
|
||||
new NotificationCompat.Action.Builder(
|
||||
0,
|
||||
context.getString(R.string.cancel),
|
||||
cancelPendingIntent)
|
||||
.build();
|
||||
final Bundle extras = new Bundle();
|
||||
extras.putString(
|
||||
Notification.EXTRA_SUBSTITUTE_APP_NAME,
|
||||
context.getString(R.string.audio_sharing_title));
|
||||
String deviceName = device.getAlias();
|
||||
if (TextUtils.isEmpty(deviceName)) {
|
||||
deviceName = device.getAddress();
|
||||
}
|
||||
NotificationCompat.Builder builder =
|
||||
new NotificationCompat.Builder(context, CHANNEL_ID)
|
||||
.setSmallIcon(com.android.settingslib.R.drawable.ic_bt_le_audio_sharing)
|
||||
.setLocalOnly(true)
|
||||
.setContentTitle(context.getString(R.string.share_audio_notification_title,
|
||||
deviceName))
|
||||
.setContentText(
|
||||
context.getString(R.string.audio_sharing_notification_content))
|
||||
.setOngoing(true)
|
||||
.setSilent(true)
|
||||
.setColor(
|
||||
context.getColor(
|
||||
com.android.internal.R.color
|
||||
.system_notification_accent_color))
|
||||
.addAction(addSourceAction)
|
||||
.addAction(cancelAction)
|
||||
.setTimeoutAfter(NOTIF_AUTO_DISMISS_MILLIS)
|
||||
.addExtras(extras);
|
||||
nm.notify(ADD_SOURCE_NOTIFICATION_ID, builder.build());
|
||||
}
|
||||
|
||||
private void cancelSharingNotification(@NonNull Context context, int notifId) {
|
||||
NotificationManager nm = context.getSystemService(NotificationManager.class);
|
||||
if (nm != null) {
|
||||
nm.cancel(notifId);
|
||||
}
|
||||
}
|
||||
|
||||
private void createNotificationChannelIfNeeded(@NonNull NotificationManager nm,
|
||||
@NonNull Context context) {
|
||||
if (nm.getNotificationChannel(CHANNEL_ID) == null) {
|
||||
Log.d(TAG, "Create bluetooth notification channel");
|
||||
NotificationChannel notificationChannel =
|
||||
new NotificationChannel(
|
||||
CHANNEL_ID,
|
||||
context.getString(com.android.settings.R.string.bluetooth),
|
||||
NotificationManager.IMPORTANCE_HIGH);
|
||||
nm.createNotificationChannel(notificationChannel);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isAppInForeground(@NonNull Context context) {
|
||||
try {
|
||||
ActivityManager activityManager = context.getSystemService(ActivityManager.class);
|
||||
String packageName = context.getPackageName();
|
||||
if (context.getPackageManager().checkPermission(Manifest.permission.PACKAGE_USAGE_STATS,
|
||||
packageName) != PackageManager.PERMISSION_GRANTED) {
|
||||
Log.d(TAG, "check isAppInForeground, returns false due to no permission");
|
||||
return false;
|
||||
}
|
||||
if (packageName != null && activityManager.getPackageImportance(packageName)
|
||||
== ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
|
||||
Log.d(TAG, "check isAppInForeground, returns true");
|
||||
return true;
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
Log.d(TAG, "check isAppInForeground, error = " + e.getMessage());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user