- 28,932 files - Full Java source code - Smali files - Resources Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
837 lines
34 KiB
Java
837 lines
34 KiB
Java
package androidx.core.app;
|
|
|
|
import android.app.Notification;
|
|
import android.app.NotificationChannel;
|
|
import android.app.NotificationChannelGroup;
|
|
import android.app.NotificationManager;
|
|
import android.content.ComponentName;
|
|
import android.content.Context;
|
|
import android.content.Intent;
|
|
import android.content.ServiceConnection;
|
|
import android.content.pm.ResolveInfo;
|
|
import android.content.pm.ServiceInfo;
|
|
import android.os.Build;
|
|
import android.os.Bundle;
|
|
import android.os.DeadObjectException;
|
|
import android.os.Handler;
|
|
import android.os.HandlerThread;
|
|
import android.os.IBinder;
|
|
import android.os.Message;
|
|
import android.os.RemoteException;
|
|
import android.provider.Settings;
|
|
import android.service.notification.StatusBarNotification;
|
|
import android.support.v4.app.INotificationSideChannel;
|
|
import android.util.Log;
|
|
import androidx.annotation.GuardedBy;
|
|
import androidx.annotation.NonNull;
|
|
import androidx.annotation.Nullable;
|
|
import androidx.annotation.RequiresApi;
|
|
import androidx.annotation.RequiresPermission;
|
|
import androidx.annotation.RestrictTo;
|
|
import androidx.annotation.VisibleForTesting;
|
|
import com.facebook.internal.security.CertificateUtil;
|
|
import com.ironsource.v8;
|
|
import java.lang.annotation.Retention;
|
|
import java.lang.annotation.RetentionPolicy;
|
|
import java.util.ArrayDeque;
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.Collection;
|
|
import java.util.Collections;
|
|
import java.util.HashMap;
|
|
import java.util.HashSet;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
|
|
/* loaded from: classes.dex */
|
|
public final class NotificationManagerCompat {
|
|
public static final String ACTION_BIND_SIDE_CHANNEL = "android.support.BIND_NOTIFICATION_SIDE_CHANNEL";
|
|
private static final String CHECK_OP_NO_THROW = "checkOpNoThrow";
|
|
public static final String EXTRA_USE_SIDE_CHANNEL = "android.support.useSideChannel";
|
|
public static final int IMPORTANCE_DEFAULT = 3;
|
|
public static final int IMPORTANCE_HIGH = 4;
|
|
public static final int IMPORTANCE_LOW = 2;
|
|
public static final int IMPORTANCE_MAX = 5;
|
|
public static final int IMPORTANCE_MIN = 1;
|
|
public static final int IMPORTANCE_NONE = 0;
|
|
public static final int IMPORTANCE_UNSPECIFIED = -1000;
|
|
public static final int INTERRUPTION_FILTER_ALARMS = 4;
|
|
public static final int INTERRUPTION_FILTER_ALL = 1;
|
|
public static final int INTERRUPTION_FILTER_NONE = 3;
|
|
public static final int INTERRUPTION_FILTER_PRIORITY = 2;
|
|
public static final int INTERRUPTION_FILTER_UNKNOWN = 0;
|
|
static final int MAX_SIDE_CHANNEL_SDK_VERSION = 19;
|
|
private static final String OP_POST_NOTIFICATION = "OP_POST_NOTIFICATION";
|
|
private static final String SETTING_ENABLED_NOTIFICATION_LISTENERS = "enabled_notification_listeners";
|
|
private static final int SIDE_CHANNEL_RETRY_BASE_INTERVAL_MS = 1000;
|
|
private static final int SIDE_CHANNEL_RETRY_MAX_COUNT = 6;
|
|
private static final String TAG = "NotifManCompat";
|
|
|
|
@GuardedBy("sEnabledNotificationListenersLock")
|
|
private static String sEnabledNotificationListeners;
|
|
|
|
@GuardedBy("sLock")
|
|
private static SideChannelManager sSideChannelManager;
|
|
private final Context mContext;
|
|
private final NotificationManager mNotificationManager;
|
|
private static final Object sEnabledNotificationListenersLock = new Object();
|
|
|
|
@GuardedBy("sEnabledNotificationListenersLock")
|
|
private static Set<String> sEnabledNotificationListenerPackages = new HashSet();
|
|
private static final Object sLock = new Object();
|
|
|
|
@Retention(RetentionPolicy.SOURCE)
|
|
@RestrictTo({RestrictTo.Scope.LIBRARY_GROUP_PREFIX})
|
|
public @interface InterruptionFilter {
|
|
}
|
|
|
|
public interface Task {
|
|
void send(INotificationSideChannel iNotificationSideChannel) throws RemoteException;
|
|
}
|
|
|
|
@NonNull
|
|
public static NotificationManagerCompat from(@NonNull Context context) {
|
|
return new NotificationManagerCompat(context);
|
|
}
|
|
|
|
private NotificationManagerCompat(Context context) {
|
|
this.mContext = context;
|
|
this.mNotificationManager = (NotificationManager) context.getSystemService("notification");
|
|
}
|
|
|
|
@VisibleForTesting
|
|
public NotificationManagerCompat(@NonNull NotificationManager notificationManager, @NonNull Context context) {
|
|
this.mContext = context;
|
|
this.mNotificationManager = notificationManager;
|
|
}
|
|
|
|
public void cancel(int i) {
|
|
cancel(null, i);
|
|
}
|
|
|
|
public void cancel(@Nullable String str, int i) {
|
|
this.mNotificationManager.cancel(str, i);
|
|
}
|
|
|
|
public void cancelAll() {
|
|
this.mNotificationManager.cancelAll();
|
|
}
|
|
|
|
@RequiresPermission("android.permission.POST_NOTIFICATIONS")
|
|
public void notify(int i, @NonNull Notification notification) {
|
|
notify(null, i, notification);
|
|
}
|
|
|
|
@RequiresPermission("android.permission.POST_NOTIFICATIONS")
|
|
public void notify(@Nullable String str, int i, @NonNull Notification notification) {
|
|
if (useSideChannelForNotification(notification)) {
|
|
pushSideChannelQueue(new NotifyTask(this.mContext.getPackageName(), i, str, notification));
|
|
this.mNotificationManager.cancel(str, i);
|
|
} else {
|
|
this.mNotificationManager.notify(str, i, notification);
|
|
}
|
|
}
|
|
|
|
@RequiresPermission("android.permission.POST_NOTIFICATIONS")
|
|
public void notify(@NonNull List<NotificationWithIdAndTag> list) {
|
|
int size = list.size();
|
|
for (int i = 0; i < size; i++) {
|
|
NotificationWithIdAndTag notificationWithIdAndTag = list.get(i);
|
|
notify(notificationWithIdAndTag.mTag, notificationWithIdAndTag.mId, notificationWithIdAndTag.mNotification);
|
|
}
|
|
}
|
|
|
|
public static class NotificationWithIdAndTag {
|
|
final int mId;
|
|
Notification mNotification;
|
|
final String mTag;
|
|
|
|
public NotificationWithIdAndTag(@Nullable String str, int i, @NonNull Notification notification) {
|
|
this.mTag = str;
|
|
this.mId = i;
|
|
this.mNotification = notification;
|
|
}
|
|
|
|
public NotificationWithIdAndTag(int i, @NonNull Notification notification) {
|
|
this(null, i, notification);
|
|
}
|
|
}
|
|
|
|
@NonNull
|
|
public List<StatusBarNotification> getActiveNotifications() {
|
|
return Api23Impl.getActiveNotifications(this.mNotificationManager);
|
|
}
|
|
|
|
public boolean areNotificationsEnabled() {
|
|
return Api24Impl.areNotificationsEnabled(this.mNotificationManager);
|
|
}
|
|
|
|
public int getImportance() {
|
|
return Api24Impl.getImportance(this.mNotificationManager);
|
|
}
|
|
|
|
public void createNotificationChannel(@NonNull NotificationChannel notificationChannel) {
|
|
Api26Impl.createNotificationChannel(this.mNotificationManager, notificationChannel);
|
|
}
|
|
|
|
public void createNotificationChannel(@NonNull NotificationChannelCompat notificationChannelCompat) {
|
|
createNotificationChannel(notificationChannelCompat.getNotificationChannel());
|
|
}
|
|
|
|
public void createNotificationChannelGroup(@NonNull NotificationChannelGroup notificationChannelGroup) {
|
|
Api26Impl.createNotificationChannelGroup(this.mNotificationManager, notificationChannelGroup);
|
|
}
|
|
|
|
public void createNotificationChannelGroup(@NonNull NotificationChannelGroupCompat notificationChannelGroupCompat) {
|
|
createNotificationChannelGroup(notificationChannelGroupCompat.getNotificationChannelGroup());
|
|
}
|
|
|
|
public void createNotificationChannels(@NonNull List<NotificationChannel> list) {
|
|
Api26Impl.createNotificationChannels(this.mNotificationManager, list);
|
|
}
|
|
|
|
public void createNotificationChannelsCompat(@NonNull List<NotificationChannelCompat> list) {
|
|
if (list.isEmpty()) {
|
|
return;
|
|
}
|
|
ArrayList arrayList = new ArrayList(list.size());
|
|
Iterator<NotificationChannelCompat> it = list.iterator();
|
|
while (it.hasNext()) {
|
|
arrayList.add(it.next().getNotificationChannel());
|
|
}
|
|
Api26Impl.createNotificationChannels(this.mNotificationManager, arrayList);
|
|
}
|
|
|
|
public void createNotificationChannelGroups(@NonNull List<NotificationChannelGroup> list) {
|
|
Api26Impl.createNotificationChannelGroups(this.mNotificationManager, list);
|
|
}
|
|
|
|
public void createNotificationChannelGroupsCompat(@NonNull List<NotificationChannelGroupCompat> list) {
|
|
if (list.isEmpty()) {
|
|
return;
|
|
}
|
|
ArrayList arrayList = new ArrayList(list.size());
|
|
Iterator<NotificationChannelGroupCompat> it = list.iterator();
|
|
while (it.hasNext()) {
|
|
arrayList.add(it.next().getNotificationChannelGroup());
|
|
}
|
|
Api26Impl.createNotificationChannelGroups(this.mNotificationManager, arrayList);
|
|
}
|
|
|
|
public void deleteNotificationChannel(@NonNull String str) {
|
|
Api26Impl.deleteNotificationChannel(this.mNotificationManager, str);
|
|
}
|
|
|
|
public void deleteNotificationChannelGroup(@NonNull String str) {
|
|
Api26Impl.deleteNotificationChannelGroup(this.mNotificationManager, str);
|
|
}
|
|
|
|
public void deleteUnlistedNotificationChannels(@NonNull Collection<String> collection) {
|
|
for (NotificationChannel notificationChannel : Api26Impl.getNotificationChannels(this.mNotificationManager)) {
|
|
if (!collection.contains(Api26Impl.getId(notificationChannel)) && (Build.VERSION.SDK_INT < 30 || !collection.contains(Api30Impl.getParentChannelId(notificationChannel)))) {
|
|
Api26Impl.deleteNotificationChannel(this.mNotificationManager, Api26Impl.getId(notificationChannel));
|
|
}
|
|
}
|
|
}
|
|
|
|
@Nullable
|
|
public NotificationChannel getNotificationChannel(@NonNull String str) {
|
|
return Api26Impl.getNotificationChannel(this.mNotificationManager, str);
|
|
}
|
|
|
|
@Nullable
|
|
public NotificationChannelCompat getNotificationChannelCompat(@NonNull String str) {
|
|
NotificationChannel notificationChannel = getNotificationChannel(str);
|
|
if (notificationChannel != null) {
|
|
return new NotificationChannelCompat(notificationChannel);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
@Nullable
|
|
public NotificationChannel getNotificationChannel(@NonNull String str, @NonNull String str2) {
|
|
if (Build.VERSION.SDK_INT >= 30) {
|
|
return Api30Impl.getNotificationChannel(this.mNotificationManager, str, str2);
|
|
}
|
|
return getNotificationChannel(str);
|
|
}
|
|
|
|
@Nullable
|
|
public NotificationChannelCompat getNotificationChannelCompat(@NonNull String str, @NonNull String str2) {
|
|
NotificationChannel notificationChannel = getNotificationChannel(str, str2);
|
|
if (notificationChannel != null) {
|
|
return new NotificationChannelCompat(notificationChannel);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
@Nullable
|
|
public NotificationChannelGroup getNotificationChannelGroup(@NonNull String str) {
|
|
if (Build.VERSION.SDK_INT >= 28) {
|
|
return Api28Impl.getNotificationChannelGroup(this.mNotificationManager, str);
|
|
}
|
|
for (NotificationChannelGroup notificationChannelGroup : getNotificationChannelGroups()) {
|
|
if (Api26Impl.getId(notificationChannelGroup).equals(str)) {
|
|
return notificationChannelGroup;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
@Nullable
|
|
public NotificationChannelGroupCompat getNotificationChannelGroupCompat(@NonNull String str) {
|
|
if (Build.VERSION.SDK_INT >= 28) {
|
|
NotificationChannelGroup notificationChannelGroup = getNotificationChannelGroup(str);
|
|
if (notificationChannelGroup != null) {
|
|
return new NotificationChannelGroupCompat(notificationChannelGroup);
|
|
}
|
|
return null;
|
|
}
|
|
NotificationChannelGroup notificationChannelGroup2 = getNotificationChannelGroup(str);
|
|
if (notificationChannelGroup2 != null) {
|
|
return new NotificationChannelGroupCompat(notificationChannelGroup2, getNotificationChannels());
|
|
}
|
|
return null;
|
|
}
|
|
|
|
@NonNull
|
|
public List<NotificationChannel> getNotificationChannels() {
|
|
return Api26Impl.getNotificationChannels(this.mNotificationManager);
|
|
}
|
|
|
|
@NonNull
|
|
public List<NotificationChannelCompat> getNotificationChannelsCompat() {
|
|
List<NotificationChannel> notificationChannels = getNotificationChannels();
|
|
if (!notificationChannels.isEmpty()) {
|
|
ArrayList arrayList = new ArrayList(notificationChannels.size());
|
|
Iterator<NotificationChannel> it = notificationChannels.iterator();
|
|
while (it.hasNext()) {
|
|
arrayList.add(new NotificationChannelCompat(it.next()));
|
|
}
|
|
return arrayList;
|
|
}
|
|
return Collections.emptyList();
|
|
}
|
|
|
|
@NonNull
|
|
public List<NotificationChannelGroup> getNotificationChannelGroups() {
|
|
return Api26Impl.getNotificationChannelGroups(this.mNotificationManager);
|
|
}
|
|
|
|
@NonNull
|
|
public List<NotificationChannelGroupCompat> getNotificationChannelGroupsCompat() {
|
|
List<NotificationChannel> notificationChannels;
|
|
int i = Build.VERSION.SDK_INT;
|
|
List<NotificationChannelGroup> notificationChannelGroups = getNotificationChannelGroups();
|
|
if (!notificationChannelGroups.isEmpty()) {
|
|
if (i >= 28) {
|
|
notificationChannels = Collections.emptyList();
|
|
} else {
|
|
notificationChannels = getNotificationChannels();
|
|
}
|
|
ArrayList arrayList = new ArrayList(notificationChannelGroups.size());
|
|
for (NotificationChannelGroup notificationChannelGroup : notificationChannelGroups) {
|
|
if (Build.VERSION.SDK_INT >= 28) {
|
|
arrayList.add(new NotificationChannelGroupCompat(notificationChannelGroup));
|
|
} else {
|
|
arrayList.add(new NotificationChannelGroupCompat(notificationChannelGroup, notificationChannels));
|
|
}
|
|
}
|
|
return arrayList;
|
|
}
|
|
return Collections.emptyList();
|
|
}
|
|
|
|
@NonNull
|
|
public static Set<String> getEnabledListenerPackages(@NonNull Context context) {
|
|
Set<String> set;
|
|
String string = Settings.Secure.getString(context.getContentResolver(), SETTING_ENABLED_NOTIFICATION_LISTENERS);
|
|
synchronized (sEnabledNotificationListenersLock) {
|
|
if (string != null) {
|
|
try {
|
|
if (!string.equals(sEnabledNotificationListeners)) {
|
|
String[] split = string.split(CertificateUtil.DELIMITER, -1);
|
|
HashSet hashSet = new HashSet(split.length);
|
|
for (String str : split) {
|
|
ComponentName unflattenFromString = ComponentName.unflattenFromString(str);
|
|
if (unflattenFromString != null) {
|
|
hashSet.add(unflattenFromString.getPackageName());
|
|
}
|
|
}
|
|
sEnabledNotificationListenerPackages = hashSet;
|
|
sEnabledNotificationListeners = string;
|
|
}
|
|
} catch (Throwable th) {
|
|
throw th;
|
|
}
|
|
}
|
|
set = sEnabledNotificationListenerPackages;
|
|
}
|
|
return set;
|
|
}
|
|
|
|
public boolean canUseFullScreenIntent() {
|
|
int i = Build.VERSION.SDK_INT;
|
|
if (i < 29) {
|
|
return true;
|
|
}
|
|
if (i < 34) {
|
|
return this.mContext.checkSelfPermission("android.permission.USE_FULL_SCREEN_INTENT") == 0;
|
|
}
|
|
return Api34Impl.canUseFullScreenIntent(this.mNotificationManager);
|
|
}
|
|
|
|
private static boolean useSideChannelForNotification(Notification notification) {
|
|
Bundle extras = NotificationCompat.getExtras(notification);
|
|
return extras != null && extras.getBoolean(EXTRA_USE_SIDE_CHANNEL);
|
|
}
|
|
|
|
public int getCurrentInterruptionFilter() {
|
|
return Api23Impl.getCurrentInterruptionFilter(this.mNotificationManager);
|
|
}
|
|
|
|
private void pushSideChannelQueue(Task task) {
|
|
synchronized (sLock) {
|
|
try {
|
|
if (sSideChannelManager == null) {
|
|
sSideChannelManager = new SideChannelManager(this.mContext.getApplicationContext());
|
|
}
|
|
sSideChannelManager.queueTask(task);
|
|
} catch (Throwable th) {
|
|
throw th;
|
|
}
|
|
}
|
|
}
|
|
|
|
public static class SideChannelManager implements Handler.Callback, ServiceConnection {
|
|
private static final int MSG_QUEUE_TASK = 0;
|
|
private static final int MSG_RETRY_LISTENER_QUEUE = 3;
|
|
private static final int MSG_SERVICE_CONNECTED = 1;
|
|
private static final int MSG_SERVICE_DISCONNECTED = 2;
|
|
private final Context mContext;
|
|
private final Handler mHandler;
|
|
private final HandlerThread mHandlerThread;
|
|
private final Map<ComponentName, ListenerRecord> mRecordMap = new HashMap();
|
|
private Set<String> mCachedEnabledPackages = new HashSet();
|
|
|
|
public SideChannelManager(Context context) {
|
|
this.mContext = context;
|
|
HandlerThread handlerThread = new HandlerThread("NotificationManagerCompat");
|
|
this.mHandlerThread = handlerThread;
|
|
handlerThread.start();
|
|
this.mHandler = new Handler(handlerThread.getLooper(), this);
|
|
}
|
|
|
|
public void queueTask(Task task) {
|
|
this.mHandler.obtainMessage(0, task).sendToTarget();
|
|
}
|
|
|
|
@Override // android.os.Handler.Callback
|
|
public boolean handleMessage(Message message) {
|
|
int i = message.what;
|
|
if (i == 0) {
|
|
handleQueueTask((Task) message.obj);
|
|
return true;
|
|
}
|
|
if (i == 1) {
|
|
ServiceConnectedEvent serviceConnectedEvent = (ServiceConnectedEvent) message.obj;
|
|
handleServiceConnected(serviceConnectedEvent.componentName, serviceConnectedEvent.iBinder);
|
|
return true;
|
|
}
|
|
if (i == 2) {
|
|
handleServiceDisconnected((ComponentName) message.obj);
|
|
return true;
|
|
}
|
|
if (i != 3) {
|
|
return false;
|
|
}
|
|
handleRetryListenerQueue((ComponentName) message.obj);
|
|
return true;
|
|
}
|
|
|
|
private void handleQueueTask(Task task) {
|
|
updateListenerMap();
|
|
for (ListenerRecord listenerRecord : this.mRecordMap.values()) {
|
|
listenerRecord.taskQueue.add(task);
|
|
processListenerQueue(listenerRecord);
|
|
}
|
|
}
|
|
|
|
private void handleServiceConnected(ComponentName componentName, IBinder iBinder) {
|
|
ListenerRecord listenerRecord = this.mRecordMap.get(componentName);
|
|
if (listenerRecord != null) {
|
|
listenerRecord.service = INotificationSideChannel.Stub.asInterface(iBinder);
|
|
listenerRecord.retryCount = 0;
|
|
processListenerQueue(listenerRecord);
|
|
}
|
|
}
|
|
|
|
private void handleServiceDisconnected(ComponentName componentName) {
|
|
ListenerRecord listenerRecord = this.mRecordMap.get(componentName);
|
|
if (listenerRecord != null) {
|
|
ensureServiceUnbound(listenerRecord);
|
|
}
|
|
}
|
|
|
|
private void handleRetryListenerQueue(ComponentName componentName) {
|
|
ListenerRecord listenerRecord = this.mRecordMap.get(componentName);
|
|
if (listenerRecord != null) {
|
|
processListenerQueue(listenerRecord);
|
|
}
|
|
}
|
|
|
|
@Override // android.content.ServiceConnection
|
|
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
|
|
if (Log.isLoggable(NotificationManagerCompat.TAG, 3)) {
|
|
StringBuilder sb = new StringBuilder();
|
|
sb.append("Connected to service ");
|
|
sb.append(componentName);
|
|
}
|
|
this.mHandler.obtainMessage(1, new ServiceConnectedEvent(componentName, iBinder)).sendToTarget();
|
|
}
|
|
|
|
@Override // android.content.ServiceConnection
|
|
public void onServiceDisconnected(ComponentName componentName) {
|
|
if (Log.isLoggable(NotificationManagerCompat.TAG, 3)) {
|
|
StringBuilder sb = new StringBuilder();
|
|
sb.append("Disconnected from service ");
|
|
sb.append(componentName);
|
|
}
|
|
this.mHandler.obtainMessage(2, componentName).sendToTarget();
|
|
}
|
|
|
|
private void updateListenerMap() {
|
|
Set<String> enabledListenerPackages = NotificationManagerCompat.getEnabledListenerPackages(this.mContext);
|
|
if (enabledListenerPackages.equals(this.mCachedEnabledPackages)) {
|
|
return;
|
|
}
|
|
this.mCachedEnabledPackages = enabledListenerPackages;
|
|
List<ResolveInfo> queryIntentServices = this.mContext.getPackageManager().queryIntentServices(new Intent().setAction(NotificationManagerCompat.ACTION_BIND_SIDE_CHANNEL), 0);
|
|
HashSet<ComponentName> hashSet = new HashSet();
|
|
for (ResolveInfo resolveInfo : queryIntentServices) {
|
|
if (enabledListenerPackages.contains(resolveInfo.serviceInfo.packageName)) {
|
|
ServiceInfo serviceInfo = resolveInfo.serviceInfo;
|
|
ComponentName componentName = new ComponentName(serviceInfo.packageName, serviceInfo.name);
|
|
if (resolveInfo.serviceInfo.permission != null) {
|
|
Log.w(NotificationManagerCompat.TAG, "Permission present on component " + componentName + ", not adding listener record.");
|
|
} else {
|
|
hashSet.add(componentName);
|
|
}
|
|
}
|
|
}
|
|
for (ComponentName componentName2 : hashSet) {
|
|
if (!this.mRecordMap.containsKey(componentName2)) {
|
|
if (Log.isLoggable(NotificationManagerCompat.TAG, 3)) {
|
|
StringBuilder sb = new StringBuilder();
|
|
sb.append("Adding listener record for ");
|
|
sb.append(componentName2);
|
|
}
|
|
this.mRecordMap.put(componentName2, new ListenerRecord(componentName2));
|
|
}
|
|
}
|
|
Iterator<Map.Entry<ComponentName, ListenerRecord>> it = this.mRecordMap.entrySet().iterator();
|
|
while (it.hasNext()) {
|
|
Map.Entry<ComponentName, ListenerRecord> next = it.next();
|
|
if (!hashSet.contains(next.getKey())) {
|
|
if (Log.isLoggable(NotificationManagerCompat.TAG, 3)) {
|
|
StringBuilder sb2 = new StringBuilder();
|
|
sb2.append("Removing listener record for ");
|
|
sb2.append(next.getKey());
|
|
}
|
|
ensureServiceUnbound(next.getValue());
|
|
it.remove();
|
|
}
|
|
}
|
|
}
|
|
|
|
private boolean ensureServiceBound(ListenerRecord listenerRecord) {
|
|
if (listenerRecord.bound) {
|
|
return true;
|
|
}
|
|
boolean bindService = this.mContext.bindService(new Intent(NotificationManagerCompat.ACTION_BIND_SIDE_CHANNEL).setComponent(listenerRecord.componentName), this, 33);
|
|
listenerRecord.bound = bindService;
|
|
if (bindService) {
|
|
listenerRecord.retryCount = 0;
|
|
} else {
|
|
Log.w(NotificationManagerCompat.TAG, "Unable to bind to listener " + listenerRecord.componentName);
|
|
this.mContext.unbindService(this);
|
|
}
|
|
return listenerRecord.bound;
|
|
}
|
|
|
|
private void ensureServiceUnbound(ListenerRecord listenerRecord) {
|
|
if (listenerRecord.bound) {
|
|
this.mContext.unbindService(this);
|
|
listenerRecord.bound = false;
|
|
}
|
|
listenerRecord.service = null;
|
|
}
|
|
|
|
private void scheduleListenerRetry(ListenerRecord listenerRecord) {
|
|
if (this.mHandler.hasMessages(3, listenerRecord.componentName)) {
|
|
return;
|
|
}
|
|
int i = listenerRecord.retryCount;
|
|
int i2 = i + 1;
|
|
listenerRecord.retryCount = i2;
|
|
if (i2 > 6) {
|
|
Log.w(NotificationManagerCompat.TAG, "Giving up on delivering " + listenerRecord.taskQueue.size() + " tasks to " + listenerRecord.componentName + " after " + listenerRecord.retryCount + " retries");
|
|
listenerRecord.taskQueue.clear();
|
|
return;
|
|
}
|
|
int i3 = (1 << i) * 1000;
|
|
if (Log.isLoggable(NotificationManagerCompat.TAG, 3)) {
|
|
StringBuilder sb = new StringBuilder();
|
|
sb.append("Scheduling retry for ");
|
|
sb.append(i3);
|
|
sb.append(" ms");
|
|
}
|
|
this.mHandler.sendMessageDelayed(this.mHandler.obtainMessage(3, listenerRecord.componentName), i3);
|
|
}
|
|
|
|
private void processListenerQueue(ListenerRecord listenerRecord) {
|
|
if (Log.isLoggable(NotificationManagerCompat.TAG, 3)) {
|
|
StringBuilder sb = new StringBuilder();
|
|
sb.append("Processing component ");
|
|
sb.append(listenerRecord.componentName);
|
|
sb.append(", ");
|
|
sb.append(listenerRecord.taskQueue.size());
|
|
sb.append(" queued tasks");
|
|
}
|
|
if (listenerRecord.taskQueue.isEmpty()) {
|
|
return;
|
|
}
|
|
if (!ensureServiceBound(listenerRecord) || listenerRecord.service == null) {
|
|
scheduleListenerRetry(listenerRecord);
|
|
return;
|
|
}
|
|
while (true) {
|
|
Task peek = listenerRecord.taskQueue.peek();
|
|
if (peek == null) {
|
|
break;
|
|
}
|
|
try {
|
|
if (Log.isLoggable(NotificationManagerCompat.TAG, 3)) {
|
|
StringBuilder sb2 = new StringBuilder();
|
|
sb2.append("Sending task ");
|
|
sb2.append(peek);
|
|
}
|
|
peek.send(listenerRecord.service);
|
|
listenerRecord.taskQueue.remove();
|
|
} catch (DeadObjectException unused) {
|
|
if (Log.isLoggable(NotificationManagerCompat.TAG, 3)) {
|
|
StringBuilder sb3 = new StringBuilder();
|
|
sb3.append("Remote service has died: ");
|
|
sb3.append(listenerRecord.componentName);
|
|
}
|
|
} catch (RemoteException e) {
|
|
Log.w(NotificationManagerCompat.TAG, "RemoteException communicating with " + listenerRecord.componentName, e);
|
|
}
|
|
}
|
|
if (listenerRecord.taskQueue.isEmpty()) {
|
|
return;
|
|
}
|
|
scheduleListenerRetry(listenerRecord);
|
|
}
|
|
|
|
public static class ListenerRecord {
|
|
final ComponentName componentName;
|
|
INotificationSideChannel service;
|
|
boolean bound = false;
|
|
ArrayDeque<Task> taskQueue = new ArrayDeque<>();
|
|
int retryCount = 0;
|
|
|
|
public ListenerRecord(ComponentName componentName) {
|
|
this.componentName = componentName;
|
|
}
|
|
}
|
|
}
|
|
|
|
public static class ServiceConnectedEvent {
|
|
final ComponentName componentName;
|
|
final IBinder iBinder;
|
|
|
|
public ServiceConnectedEvent(ComponentName componentName, IBinder iBinder) {
|
|
this.componentName = componentName;
|
|
this.iBinder = iBinder;
|
|
}
|
|
}
|
|
|
|
public static class NotifyTask implements Task {
|
|
final int id;
|
|
final Notification notif;
|
|
final String packageName;
|
|
final String tag;
|
|
|
|
public NotifyTask(String str, int i, String str2, Notification notification) {
|
|
this.packageName = str;
|
|
this.id = i;
|
|
this.tag = str2;
|
|
this.notif = notification;
|
|
}
|
|
|
|
@Override // androidx.core.app.NotificationManagerCompat.Task
|
|
public void send(INotificationSideChannel iNotificationSideChannel) throws RemoteException {
|
|
iNotificationSideChannel.notify(this.packageName, this.id, this.tag, this.notif);
|
|
}
|
|
|
|
@NonNull
|
|
public String toString() {
|
|
return "NotifyTask[packageName:" + this.packageName + ", id:" + this.id + ", tag:" + this.tag + v8.i.e;
|
|
}
|
|
}
|
|
|
|
public static class CancelTask implements Task {
|
|
final boolean all;
|
|
final int id;
|
|
final String packageName;
|
|
final String tag;
|
|
|
|
public CancelTask(String str) {
|
|
this.packageName = str;
|
|
this.id = 0;
|
|
this.tag = null;
|
|
this.all = true;
|
|
}
|
|
|
|
public CancelTask(String str, int i, String str2) {
|
|
this.packageName = str;
|
|
this.id = i;
|
|
this.tag = str2;
|
|
this.all = false;
|
|
}
|
|
|
|
@Override // androidx.core.app.NotificationManagerCompat.Task
|
|
public void send(INotificationSideChannel iNotificationSideChannel) throws RemoteException {
|
|
if (this.all) {
|
|
iNotificationSideChannel.cancelAll(this.packageName);
|
|
} else {
|
|
iNotificationSideChannel.cancel(this.packageName, this.id, this.tag);
|
|
}
|
|
}
|
|
|
|
@NonNull
|
|
public String toString() {
|
|
return "CancelTask[packageName:" + this.packageName + ", id:" + this.id + ", tag:" + this.tag + ", all:" + this.all + v8.i.e;
|
|
}
|
|
}
|
|
|
|
@RequiresApi(23)
|
|
public static class Api23Impl {
|
|
private Api23Impl() {
|
|
}
|
|
|
|
public static List<StatusBarNotification> getActiveNotifications(NotificationManager notificationManager) {
|
|
StatusBarNotification[] activeNotifications = notificationManager.getActiveNotifications();
|
|
if (activeNotifications == null) {
|
|
return new ArrayList();
|
|
}
|
|
return Arrays.asList(activeNotifications);
|
|
}
|
|
|
|
public static int getCurrentInterruptionFilter(NotificationManager notificationManager) {
|
|
return notificationManager.getCurrentInterruptionFilter();
|
|
}
|
|
}
|
|
|
|
@RequiresApi(24)
|
|
public static class Api24Impl {
|
|
private Api24Impl() {
|
|
}
|
|
|
|
public static boolean areNotificationsEnabled(NotificationManager notificationManager) {
|
|
return notificationManager.areNotificationsEnabled();
|
|
}
|
|
|
|
public static int getImportance(NotificationManager notificationManager) {
|
|
return notificationManager.getImportance();
|
|
}
|
|
}
|
|
|
|
@RequiresApi(26)
|
|
public static class Api26Impl {
|
|
private Api26Impl() {
|
|
}
|
|
|
|
public static void createNotificationChannel(NotificationManager notificationManager, NotificationChannel notificationChannel) {
|
|
notificationManager.createNotificationChannel(notificationChannel);
|
|
}
|
|
|
|
public static NotificationChannel getNotificationChannel(NotificationManager notificationManager, String str) {
|
|
return notificationManager.getNotificationChannel(str);
|
|
}
|
|
|
|
public static void createNotificationChannels(NotificationManager notificationManager, List<NotificationChannel> list) {
|
|
notificationManager.createNotificationChannels(list);
|
|
}
|
|
|
|
public static List<NotificationChannel> getNotificationChannels(NotificationManager notificationManager) {
|
|
return notificationManager.getNotificationChannels();
|
|
}
|
|
|
|
public static void createNotificationChannelGroup(NotificationManager notificationManager, NotificationChannelGroup notificationChannelGroup) {
|
|
notificationManager.createNotificationChannelGroup(notificationChannelGroup);
|
|
}
|
|
|
|
public static void createNotificationChannelGroups(NotificationManager notificationManager, List<NotificationChannelGroup> list) {
|
|
notificationManager.createNotificationChannelGroups(list);
|
|
}
|
|
|
|
public static List<NotificationChannelGroup> getNotificationChannelGroups(NotificationManager notificationManager) {
|
|
return notificationManager.getNotificationChannelGroups();
|
|
}
|
|
|
|
public static void deleteNotificationChannel(NotificationManager notificationManager, String str) {
|
|
notificationManager.deleteNotificationChannel(str);
|
|
}
|
|
|
|
public static void deleteNotificationChannelGroup(NotificationManager notificationManager, String str) {
|
|
notificationManager.deleteNotificationChannelGroup(str);
|
|
}
|
|
|
|
public static String getId(NotificationChannel notificationChannel) {
|
|
return notificationChannel.getId();
|
|
}
|
|
|
|
public static String getId(NotificationChannelGroup notificationChannelGroup) {
|
|
return notificationChannelGroup.getId();
|
|
}
|
|
}
|
|
|
|
@RequiresApi(28)
|
|
public static class Api28Impl {
|
|
private Api28Impl() {
|
|
}
|
|
|
|
public static NotificationChannelGroup getNotificationChannelGroup(NotificationManager notificationManager, String str) {
|
|
return notificationManager.getNotificationChannelGroup(str);
|
|
}
|
|
}
|
|
|
|
@RequiresApi(30)
|
|
public static class Api30Impl {
|
|
private Api30Impl() {
|
|
}
|
|
|
|
public static String getParentChannelId(NotificationChannel notificationChannel) {
|
|
return notificationChannel.getParentChannelId();
|
|
}
|
|
|
|
public static NotificationChannel getNotificationChannel(NotificationManager notificationManager, String str, String str2) {
|
|
return notificationManager.getNotificationChannel(str, str2);
|
|
}
|
|
}
|
|
|
|
@RequiresApi(34)
|
|
public static class Api34Impl {
|
|
private Api34Impl() {
|
|
}
|
|
|
|
public static boolean canUseFullScreenIntent(NotificationManager notificationManager) {
|
|
return notificationManager.canUseFullScreenIntent();
|
|
}
|
|
}
|
|
}
|