2021-07-24 02:37:17 +00:00
|
|
|
package androidx.core.app;
|
|
|
|
|
|
|
|
import android.app.AppOpsManager;
|
|
|
|
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.ApplicationInfo;
|
|
|
|
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.util.Log;
|
|
|
|
import androidx.annotation.GuardedBy;
|
|
|
|
import androidx.annotation.NonNull;
|
|
|
|
import androidx.annotation.Nullable;
|
|
|
|
import java.lang.reflect.InvocationTargetException;
|
|
|
|
import java.util.ArrayDeque;
|
2021-09-15 06:33:54 +00:00
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.Collection;
|
2021-07-24 02:37:17 +00:00
|
|
|
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;
|
2021-11-02 06:38:17 +00:00
|
|
|
import x.a.b.a.a;
|
2021-07-24 02:37:17 +00:00
|
|
|
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 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 Set<String> sEnabledNotificationListenerPackages = new HashSet();
|
|
|
|
@GuardedBy("sEnabledNotificationListenersLock")
|
|
|
|
private static String sEnabledNotificationListeners;
|
|
|
|
private static final Object sEnabledNotificationListenersLock = new Object();
|
|
|
|
private static final Object sLock = new Object();
|
|
|
|
@GuardedBy("sLock")
|
|
|
|
private static SideChannelManager sSideChannelManager;
|
|
|
|
private final Context mContext;
|
|
|
|
private final NotificationManager mNotificationManager;
|
|
|
|
|
|
|
|
public static class CancelTask implements Task {
|
|
|
|
public final boolean all;
|
|
|
|
|
|
|
|
/* renamed from: id reason: collision with root package name */
|
2021-12-17 21:59:34 +00:00
|
|
|
public final int f34id;
|
2021-07-24 02:37:17 +00:00
|
|
|
public final String packageName;
|
|
|
|
public final String tag;
|
|
|
|
|
|
|
|
public CancelTask(String str) {
|
|
|
|
this.packageName = str;
|
2021-12-17 21:59:34 +00:00
|
|
|
this.f34id = 0;
|
2021-07-24 02:37:17 +00:00
|
|
|
this.tag = null;
|
|
|
|
this.all = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
public CancelTask(String str, int i, String str2) {
|
|
|
|
this.packageName = str;
|
2021-12-17 21:59:34 +00:00
|
|
|
this.f34id = i;
|
2021-07-24 02:37:17 +00:00
|
|
|
this.tag = str2;
|
|
|
|
this.all = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override // androidx.core.app.NotificationManagerCompat.Task
|
|
|
|
public void send(a aVar) throws RemoteException {
|
|
|
|
if (this.all) {
|
|
|
|
aVar.cancelAll(this.packageName);
|
|
|
|
} else {
|
2021-12-17 21:59:34 +00:00
|
|
|
aVar.cancel(this.packageName, this.f34id, this.tag);
|
2021-07-24 02:37:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@NonNull
|
|
|
|
public String toString() {
|
|
|
|
StringBuilder sb = new StringBuilder("CancelTask[");
|
|
|
|
sb.append("packageName:");
|
|
|
|
sb.append(this.packageName);
|
|
|
|
sb.append(", id:");
|
2021-12-17 21:59:34 +00:00
|
|
|
sb.append(this.f34id);
|
2021-07-24 02:37:17 +00:00
|
|
|
sb.append(", tag:");
|
|
|
|
sb.append(this.tag);
|
|
|
|
sb.append(", all:");
|
2021-12-17 21:59:34 +00:00
|
|
|
return b.d.b.a.a.L(sb, this.all, "]");
|
2021-07-24 02:37:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static class NotifyTask implements Task {
|
|
|
|
|
|
|
|
/* renamed from: id reason: collision with root package name */
|
2021-12-17 21:59:34 +00:00
|
|
|
public final int f35id;
|
2021-07-24 02:37:17 +00:00
|
|
|
public final Notification notif;
|
|
|
|
public final String packageName;
|
|
|
|
public final String tag;
|
|
|
|
|
|
|
|
public NotifyTask(String str, int i, String str2, Notification notification) {
|
|
|
|
this.packageName = str;
|
2021-12-17 21:59:34 +00:00
|
|
|
this.f35id = i;
|
2021-07-24 02:37:17 +00:00
|
|
|
this.tag = str2;
|
|
|
|
this.notif = notification;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override // androidx.core.app.NotificationManagerCompat.Task
|
|
|
|
public void send(a aVar) throws RemoteException {
|
2021-12-17 21:59:34 +00:00
|
|
|
aVar.notify(this.packageName, this.f35id, this.tag, this.notif);
|
2021-07-24 02:37:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@NonNull
|
|
|
|
public String toString() {
|
|
|
|
StringBuilder sb = new StringBuilder("NotifyTask[");
|
|
|
|
sb.append("packageName:");
|
|
|
|
sb.append(this.packageName);
|
|
|
|
sb.append(", id:");
|
2021-12-17 21:59:34 +00:00
|
|
|
sb.append(this.f35id);
|
2021-07-24 02:37:17 +00:00
|
|
|
sb.append(", tag:");
|
2021-12-17 21:59:34 +00:00
|
|
|
return b.d.b.a.a.H(sb, this.tag, "]");
|
2021-07-24 02:37:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static class ServiceConnectedEvent {
|
|
|
|
public final ComponentName componentName;
|
|
|
|
public final IBinder iBinder;
|
|
|
|
|
|
|
|
public ServiceConnectedEvent(ComponentName componentName, IBinder iBinder) {
|
|
|
|
this.componentName = componentName;
|
|
|
|
this.iBinder = iBinder;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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 Set<String> mCachedEnabledPackages = new HashSet();
|
|
|
|
private final Context mContext;
|
|
|
|
private final Handler mHandler;
|
|
|
|
private final HandlerThread mHandlerThread;
|
|
|
|
private final Map<ComponentName, ListenerRecord> mRecordMap = new HashMap();
|
|
|
|
|
|
|
|
public static class ListenerRecord {
|
|
|
|
public boolean bound = false;
|
|
|
|
public final ComponentName componentName;
|
|
|
|
public int retryCount = 0;
|
|
|
|
public a service;
|
|
|
|
public ArrayDeque<Task> taskQueue = new ArrayDeque<>();
|
|
|
|
|
|
|
|
public ListenerRecord(ComponentName componentName) {
|
|
|
|
this.componentName = componentName;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public SideChannelManager(Context context) {
|
|
|
|
this.mContext = context;
|
|
|
|
HandlerThread handlerThread = new HandlerThread("NotificationManagerCompat");
|
|
|
|
this.mHandlerThread = handlerThread;
|
|
|
|
handlerThread.start();
|
|
|
|
this.mHandler = new Handler(handlerThread.getLooper(), this);
|
|
|
|
}
|
|
|
|
|
|
|
|
private boolean ensureServiceBound(ListenerRecord listenerRecord) {
|
|
|
|
if (listenerRecord.bound) {
|
|
|
|
return true;
|
|
|
|
}
|
2021-08-09 22:51:56 +00:00
|
|
|
boolean bindService = this.mContext.bindService(new Intent(NotificationManagerCompat.ACTION_BIND_SIDE_CHANNEL).setComponent(listenerRecord.componentName), this, 33);
|
2021-07-24 02:37:17 +00:00
|
|
|
listenerRecord.bound = bindService;
|
|
|
|
if (bindService) {
|
|
|
|
listenerRecord.retryCount = 0;
|
|
|
|
} else {
|
2021-12-17 21:59:34 +00:00
|
|
|
StringBuilder R = b.d.b.a.a.R("Unable to bind to listener ");
|
2021-11-05 06:48:17 +00:00
|
|
|
R.append(listenerRecord.componentName);
|
|
|
|
Log.w(NotificationManagerCompat.TAG, R.toString());
|
2021-07-24 02:37:17 +00:00
|
|
|
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 handleQueueTask(Task task) {
|
|
|
|
updateListenerMap();
|
|
|
|
for (ListenerRecord listenerRecord : this.mRecordMap.values()) {
|
|
|
|
listenerRecord.taskQueue.add(task);
|
|
|
|
processListenerQueue(listenerRecord);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void handleRetryListenerQueue(ComponentName componentName) {
|
|
|
|
ListenerRecord listenerRecord = this.mRecordMap.get(componentName);
|
|
|
|
if (listenerRecord != null) {
|
|
|
|
processListenerQueue(listenerRecord);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void handleServiceConnected(ComponentName componentName, IBinder iBinder) {
|
|
|
|
ListenerRecord listenerRecord = this.mRecordMap.get(componentName);
|
|
|
|
if (listenerRecord != null) {
|
2021-12-17 21:59:34 +00:00
|
|
|
listenerRecord.service = a.AbstractBinderC0357a.asInterface(iBinder);
|
2021-07-24 02:37:17 +00:00
|
|
|
listenerRecord.retryCount = 0;
|
|
|
|
processListenerQueue(listenerRecord);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void handleServiceDisconnected(ComponentName componentName) {
|
|
|
|
ListenerRecord listenerRecord = this.mRecordMap.get(componentName);
|
|
|
|
if (listenerRecord != null) {
|
|
|
|
ensureServiceUnbound(listenerRecord);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void processListenerQueue(ListenerRecord listenerRecord) {
|
2021-08-09 22:51:56 +00:00
|
|
|
if (Log.isLoggable(NotificationManagerCompat.TAG, 3)) {
|
2021-12-17 21:59:34 +00:00
|
|
|
StringBuilder R = b.d.b.a.a.R("Processing component ");
|
2021-11-05 06:48:17 +00:00
|
|
|
R.append(listenerRecord.componentName);
|
|
|
|
R.append(", ");
|
|
|
|
R.append(listenerRecord.taskQueue.size());
|
|
|
|
R.append(" queued tasks");
|
|
|
|
Log.d(NotificationManagerCompat.TAG, R.toString());
|
2021-07-24 02:37:17 +00:00
|
|
|
}
|
|
|
|
if (!listenerRecord.taskQueue.isEmpty()) {
|
|
|
|
if (!ensureServiceBound(listenerRecord) || listenerRecord.service == null) {
|
|
|
|
scheduleListenerRetry(listenerRecord);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
while (true) {
|
|
|
|
Task peek = listenerRecord.taskQueue.peek();
|
|
|
|
if (peek == null) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
try {
|
2021-08-09 22:51:56 +00:00
|
|
|
if (Log.isLoggable(NotificationManagerCompat.TAG, 3)) {
|
|
|
|
Log.d(NotificationManagerCompat.TAG, "Sending task " + peek);
|
2021-07-24 02:37:17 +00:00
|
|
|
}
|
|
|
|
peek.send(listenerRecord.service);
|
|
|
|
listenerRecord.taskQueue.remove();
|
|
|
|
} catch (DeadObjectException unused) {
|
2021-08-09 22:51:56 +00:00
|
|
|
if (Log.isLoggable(NotificationManagerCompat.TAG, 3)) {
|
2021-12-17 21:59:34 +00:00
|
|
|
StringBuilder R2 = b.d.b.a.a.R("Remote service has died: ");
|
2021-11-05 06:48:17 +00:00
|
|
|
R2.append(listenerRecord.componentName);
|
|
|
|
Log.d(NotificationManagerCompat.TAG, R2.toString());
|
2021-07-24 02:37:17 +00:00
|
|
|
}
|
|
|
|
} catch (RemoteException e) {
|
2021-12-17 21:59:34 +00:00
|
|
|
StringBuilder R3 = b.d.b.a.a.R("RemoteException communicating with ");
|
2021-11-05 06:48:17 +00:00
|
|
|
R3.append(listenerRecord.componentName);
|
|
|
|
Log.w(NotificationManagerCompat.TAG, R3.toString(), e);
|
2021-07-24 02:37:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!listenerRecord.taskQueue.isEmpty()) {
|
|
|
|
scheduleListenerRetry(listenerRecord);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void scheduleListenerRetry(ListenerRecord listenerRecord) {
|
|
|
|
if (!this.mHandler.hasMessages(3, listenerRecord.componentName)) {
|
|
|
|
int i = listenerRecord.retryCount + 1;
|
|
|
|
listenerRecord.retryCount = i;
|
|
|
|
if (i > 6) {
|
2021-12-17 21:59:34 +00:00
|
|
|
StringBuilder R = b.d.b.a.a.R("Giving up on delivering ");
|
2021-11-05 06:48:17 +00:00
|
|
|
R.append(listenerRecord.taskQueue.size());
|
|
|
|
R.append(" tasks to ");
|
|
|
|
R.append(listenerRecord.componentName);
|
|
|
|
R.append(" after ");
|
|
|
|
R.append(listenerRecord.retryCount);
|
|
|
|
R.append(" retries");
|
|
|
|
Log.w(NotificationManagerCompat.TAG, R.toString());
|
2021-07-24 02:37:17 +00:00
|
|
|
listenerRecord.taskQueue.clear();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
int i2 = (1 << (i - 1)) * 1000;
|
2021-08-09 22:51:56 +00:00
|
|
|
if (Log.isLoggable(NotificationManagerCompat.TAG, 3)) {
|
|
|
|
Log.d(NotificationManagerCompat.TAG, "Scheduling retry for " + i2 + " ms");
|
2021-07-24 02:37:17 +00:00
|
|
|
}
|
|
|
|
this.mHandler.sendMessageDelayed(this.mHandler.obtainMessage(3, listenerRecord.componentName), (long) i2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void updateListenerMap() {
|
|
|
|
Set<String> enabledListenerPackages = NotificationManagerCompat.getEnabledListenerPackages(this.mContext);
|
|
|
|
if (!enabledListenerPackages.equals(this.mCachedEnabledPackages)) {
|
|
|
|
this.mCachedEnabledPackages = enabledListenerPackages;
|
2021-08-09 22:51:56 +00:00
|
|
|
List<ResolveInfo> queryIntentServices = this.mContext.getPackageManager().queryIntentServices(new Intent().setAction(NotificationManagerCompat.ACTION_BIND_SIDE_CHANNEL), 0);
|
2021-07-24 02:37:17 +00:00
|
|
|
HashSet 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) {
|
2021-08-09 22:51:56 +00:00
|
|
|
Log.w(NotificationManagerCompat.TAG, "Permission present on component " + componentName + ", not adding listener record.");
|
2021-07-24 02:37:17 +00:00
|
|
|
} else {
|
|
|
|
hashSet.add(componentName);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Iterator it = hashSet.iterator();
|
|
|
|
while (it.hasNext()) {
|
|
|
|
ComponentName componentName2 = (ComponentName) it.next();
|
|
|
|
if (!this.mRecordMap.containsKey(componentName2)) {
|
2021-08-09 22:51:56 +00:00
|
|
|
if (Log.isLoggable(NotificationManagerCompat.TAG, 3)) {
|
|
|
|
Log.d(NotificationManagerCompat.TAG, "Adding listener record for " + componentName2);
|
2021-07-24 02:37:17 +00:00
|
|
|
}
|
|
|
|
this.mRecordMap.put(componentName2, new ListenerRecord(componentName2));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Iterator<Map.Entry<ComponentName, ListenerRecord>> it2 = this.mRecordMap.entrySet().iterator();
|
|
|
|
while (it2.hasNext()) {
|
|
|
|
Map.Entry<ComponentName, ListenerRecord> next = it2.next();
|
|
|
|
if (!hashSet.contains(next.getKey())) {
|
2021-08-09 22:51:56 +00:00
|
|
|
if (Log.isLoggable(NotificationManagerCompat.TAG, 3)) {
|
2021-12-17 21:59:34 +00:00
|
|
|
StringBuilder R = b.d.b.a.a.R("Removing listener record for ");
|
2021-11-05 06:48:17 +00:00
|
|
|
R.append(next.getKey());
|
|
|
|
Log.d(NotificationManagerCompat.TAG, R.toString());
|
2021-07-24 02:37:17 +00:00
|
|
|
}
|
|
|
|
ensureServiceUnbound(next.getValue());
|
|
|
|
it2.remove();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override // android.os.Handler.Callback
|
|
|
|
public boolean handleMessage(Message message) {
|
|
|
|
int i = message.what;
|
|
|
|
if (i == 0) {
|
|
|
|
handleQueueTask((Task) message.obj);
|
|
|
|
return true;
|
|
|
|
} else if (i == 1) {
|
|
|
|
ServiceConnectedEvent serviceConnectedEvent = (ServiceConnectedEvent) message.obj;
|
|
|
|
handleServiceConnected(serviceConnectedEvent.componentName, serviceConnectedEvent.iBinder);
|
|
|
|
return true;
|
|
|
|
} else if (i == 2) {
|
|
|
|
handleServiceDisconnected((ComponentName) message.obj);
|
|
|
|
return true;
|
|
|
|
} else if (i != 3) {
|
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
handleRetryListenerQueue((ComponentName) message.obj);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override // android.content.ServiceConnection
|
|
|
|
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
|
2021-08-09 22:51:56 +00:00
|
|
|
if (Log.isLoggable(NotificationManagerCompat.TAG, 3)) {
|
|
|
|
Log.d(NotificationManagerCompat.TAG, "Connected to service " + componentName);
|
2021-07-24 02:37:17 +00:00
|
|
|
}
|
|
|
|
this.mHandler.obtainMessage(1, new ServiceConnectedEvent(componentName, iBinder)).sendToTarget();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override // android.content.ServiceConnection
|
|
|
|
public void onServiceDisconnected(ComponentName componentName) {
|
2021-08-09 22:51:56 +00:00
|
|
|
if (Log.isLoggable(NotificationManagerCompat.TAG, 3)) {
|
|
|
|
Log.d(NotificationManagerCompat.TAG, "Disconnected from service " + componentName);
|
2021-07-24 02:37:17 +00:00
|
|
|
}
|
|
|
|
this.mHandler.obtainMessage(2, componentName).sendToTarget();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void queueTask(Task task) {
|
|
|
|
this.mHandler.obtainMessage(0, task).sendToTarget();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public interface Task {
|
|
|
|
void send(a aVar) throws RemoteException;
|
|
|
|
}
|
|
|
|
|
|
|
|
private NotificationManagerCompat(Context context) {
|
|
|
|
this.mContext = context;
|
|
|
|
this.mNotificationManager = (NotificationManager) context.getSystemService("notification");
|
|
|
|
}
|
|
|
|
|
|
|
|
@NonNull
|
|
|
|
public static NotificationManagerCompat from(@NonNull Context context) {
|
|
|
|
return new NotificationManagerCompat(context);
|
|
|
|
}
|
|
|
|
|
|
|
|
@NonNull
|
|
|
|
public static Set<String> getEnabledListenerPackages(@NonNull Context context) {
|
|
|
|
Set<String> set;
|
2021-08-09 22:51:56 +00:00
|
|
|
String string = Settings.Secure.getString(context.getContentResolver(), SETTING_ENABLED_NOTIFICATION_LISTENERS);
|
2021-07-24 02:37:17 +00:00
|
|
|
synchronized (sEnabledNotificationListenersLock) {
|
|
|
|
if (string != null) {
|
|
|
|
if (!string.equals(sEnabledNotificationListeners)) {
|
|
|
|
String[] split = string.split(":", -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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
set = sEnabledNotificationListenerPackages;
|
|
|
|
}
|
|
|
|
return set;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void pushSideChannelQueue(Task task) {
|
|
|
|
synchronized (sLock) {
|
|
|
|
if (sSideChannelManager == null) {
|
|
|
|
sSideChannelManager = new SideChannelManager(this.mContext.getApplicationContext());
|
|
|
|
}
|
|
|
|
sSideChannelManager.queueTask(task);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static boolean useSideChannelForNotification(Notification notification) {
|
|
|
|
Bundle extras = NotificationCompat.getExtras(notification);
|
2021-08-09 22:51:56 +00:00
|
|
|
return extras != null && extras.getBoolean(EXTRA_USE_SIDE_CHANNEL);
|
2021-07-24 02:37:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public boolean areNotificationsEnabled() {
|
|
|
|
if (Build.VERSION.SDK_INT >= 24) {
|
|
|
|
return this.mNotificationManager.areNotificationsEnabled();
|
|
|
|
}
|
|
|
|
AppOpsManager appOpsManager = (AppOpsManager) this.mContext.getSystemService("appops");
|
|
|
|
ApplicationInfo applicationInfo = this.mContext.getApplicationInfo();
|
|
|
|
String packageName = this.mContext.getApplicationContext().getPackageName();
|
|
|
|
int i = applicationInfo.uid;
|
|
|
|
try {
|
|
|
|
Class<?> cls = Class.forName(AppOpsManager.class.getName());
|
|
|
|
Class<?> cls2 = Integer.TYPE;
|
2021-08-09 22:51:56 +00:00
|
|
|
return ((Integer) cls.getMethod(CHECK_OP_NO_THROW, new Class[]{cls2, cls2, String.class}).invoke(appOpsManager, new Object[]{Integer.valueOf(((Integer) cls.getDeclaredField(OP_POST_NOTIFICATION).get(Integer.class)).intValue()), Integer.valueOf(i), packageName})).intValue() == 0;
|
2021-07-24 02:37:17 +00:00
|
|
|
} catch (ClassNotFoundException | IllegalAccessException | NoSuchFieldException | NoSuchMethodException | RuntimeException | InvocationTargetException unused) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void createNotificationChannel(@NonNull NotificationChannel notificationChannel) {
|
|
|
|
if (Build.VERSION.SDK_INT >= 26) {
|
|
|
|
this.mNotificationManager.createNotificationChannel(notificationChannel);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-15 06:33:54 +00:00
|
|
|
public void createNotificationChannel(@NonNull NotificationChannelCompat notificationChannelCompat) {
|
|
|
|
createNotificationChannel(notificationChannelCompat.getNotificationChannel());
|
|
|
|
}
|
|
|
|
|
2021-07-24 02:37:17 +00:00
|
|
|
public void createNotificationChannelGroup(@NonNull NotificationChannelGroup notificationChannelGroup) {
|
|
|
|
if (Build.VERSION.SDK_INT >= 26) {
|
|
|
|
this.mNotificationManager.createNotificationChannelGroup(notificationChannelGroup);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-15 06:33:54 +00:00
|
|
|
public void createNotificationChannelGroup(@NonNull NotificationChannelGroupCompat notificationChannelGroupCompat) {
|
|
|
|
createNotificationChannelGroup(notificationChannelGroupCompat.getNotificationChannelGroup());
|
|
|
|
}
|
|
|
|
|
2021-07-24 02:37:17 +00:00
|
|
|
public void createNotificationChannelGroups(@NonNull List<NotificationChannelGroup> list) {
|
|
|
|
if (Build.VERSION.SDK_INT >= 26) {
|
|
|
|
this.mNotificationManager.createNotificationChannelGroups(list);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-15 06:33:54 +00:00
|
|
|
public void createNotificationChannelGroupsCompat(@NonNull List<NotificationChannelGroupCompat> list) {
|
|
|
|
if (Build.VERSION.SDK_INT >= 26 && !list.isEmpty()) {
|
|
|
|
ArrayList arrayList = new ArrayList(list.size());
|
|
|
|
for (NotificationChannelGroupCompat notificationChannelGroupCompat : list) {
|
|
|
|
arrayList.add(notificationChannelGroupCompat.getNotificationChannelGroup());
|
|
|
|
}
|
|
|
|
this.mNotificationManager.createNotificationChannelGroups(arrayList);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-24 02:37:17 +00:00
|
|
|
public void createNotificationChannels(@NonNull List<NotificationChannel> list) {
|
|
|
|
if (Build.VERSION.SDK_INT >= 26) {
|
|
|
|
this.mNotificationManager.createNotificationChannels(list);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-15 06:33:54 +00:00
|
|
|
public void createNotificationChannelsCompat(@NonNull List<NotificationChannelCompat> list) {
|
|
|
|
if (Build.VERSION.SDK_INT >= 26 && !list.isEmpty()) {
|
|
|
|
ArrayList arrayList = new ArrayList(list.size());
|
|
|
|
for (NotificationChannelCompat notificationChannelCompat : list) {
|
|
|
|
arrayList.add(notificationChannelCompat.getNotificationChannel());
|
|
|
|
}
|
|
|
|
this.mNotificationManager.createNotificationChannels(arrayList);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-24 02:37:17 +00:00
|
|
|
public void deleteNotificationChannel(@NonNull String str) {
|
|
|
|
if (Build.VERSION.SDK_INT >= 26) {
|
|
|
|
this.mNotificationManager.deleteNotificationChannel(str);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void deleteNotificationChannelGroup(@NonNull String str) {
|
|
|
|
if (Build.VERSION.SDK_INT >= 26) {
|
|
|
|
this.mNotificationManager.deleteNotificationChannelGroup(str);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-15 06:33:54 +00:00
|
|
|
public void deleteUnlistedNotificationChannels(@NonNull Collection<String> collection) {
|
|
|
|
if (Build.VERSION.SDK_INT >= 26) {
|
|
|
|
for (NotificationChannel notificationChannel : this.mNotificationManager.getNotificationChannels()) {
|
|
|
|
if (!collection.contains(notificationChannel.getId()) && (Build.VERSION.SDK_INT < 30 || !collection.contains(notificationChannel.getParentChannelId()))) {
|
|
|
|
this.mNotificationManager.deleteNotificationChannel(notificationChannel.getId());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-24 02:37:17 +00:00
|
|
|
public int getImportance() {
|
2021-08-09 22:51:56 +00:00
|
|
|
return Build.VERSION.SDK_INT >= 24 ? this.mNotificationManager.getImportance() : IMPORTANCE_UNSPECIFIED;
|
2021-07-24 02:37:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Nullable
|
|
|
|
public NotificationChannel getNotificationChannel(@NonNull String str) {
|
|
|
|
if (Build.VERSION.SDK_INT >= 26) {
|
|
|
|
return this.mNotificationManager.getNotificationChannel(str);
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2021-09-15 06:33:54 +00:00
|
|
|
@Nullable
|
|
|
|
public NotificationChannel getNotificationChannel(@NonNull String str, @NonNull String str2) {
|
|
|
|
return Build.VERSION.SDK_INT >= 30 ? this.mNotificationManager.getNotificationChannel(str, str2) : getNotificationChannel(str);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Nullable
|
|
|
|
public NotificationChannelCompat getNotificationChannelCompat(@NonNull String str) {
|
|
|
|
NotificationChannel notificationChannel;
|
|
|
|
if (Build.VERSION.SDK_INT < 26 || (notificationChannel = getNotificationChannel(str)) == null) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
return new NotificationChannelCompat(notificationChannel);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Nullable
|
|
|
|
public NotificationChannelCompat getNotificationChannelCompat(@NonNull String str, @NonNull String str2) {
|
|
|
|
NotificationChannel notificationChannel;
|
|
|
|
if (Build.VERSION.SDK_INT < 26 || (notificationChannel = getNotificationChannel(str, str2)) == null) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
return new NotificationChannelCompat(notificationChannel);
|
|
|
|
}
|
|
|
|
|
2021-07-24 02:37:17 +00:00
|
|
|
@Nullable
|
|
|
|
public NotificationChannelGroup getNotificationChannelGroup(@NonNull String str) {
|
|
|
|
int i = Build.VERSION.SDK_INT;
|
|
|
|
if (i >= 28) {
|
|
|
|
return this.mNotificationManager.getNotificationChannelGroup(str);
|
|
|
|
}
|
|
|
|
if (i >= 26) {
|
|
|
|
for (NotificationChannelGroup notificationChannelGroup : getNotificationChannelGroups()) {
|
|
|
|
if (notificationChannelGroup.getId().equals(str)) {
|
|
|
|
return notificationChannelGroup;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2021-09-15 06:33:54 +00:00
|
|
|
@Nullable
|
|
|
|
public NotificationChannelGroupCompat getNotificationChannelGroupCompat(@NonNull String str) {
|
|
|
|
NotificationChannelGroup notificationChannelGroup;
|
|
|
|
int i = Build.VERSION.SDK_INT;
|
|
|
|
if (i >= 28) {
|
|
|
|
NotificationChannelGroup notificationChannelGroup2 = getNotificationChannelGroup(str);
|
|
|
|
if (notificationChannelGroup2 != null) {
|
|
|
|
return new NotificationChannelGroupCompat(notificationChannelGroup2);
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
} else if (i < 26 || (notificationChannelGroup = getNotificationChannelGroup(str)) == null) {
|
|
|
|
return null;
|
|
|
|
} else {
|
|
|
|
return new NotificationChannelGroupCompat(notificationChannelGroup, getNotificationChannels());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-24 02:37:17 +00:00
|
|
|
@NonNull
|
|
|
|
public List<NotificationChannelGroup> getNotificationChannelGroups() {
|
|
|
|
return Build.VERSION.SDK_INT >= 26 ? this.mNotificationManager.getNotificationChannelGroups() : Collections.emptyList();
|
|
|
|
}
|
|
|
|
|
2021-09-15 06:33:54 +00:00
|
|
|
@NonNull
|
|
|
|
public List<NotificationChannelGroupCompat> getNotificationChannelGroupsCompat() {
|
|
|
|
int i = Build.VERSION.SDK_INT;
|
|
|
|
if (i >= 26) {
|
|
|
|
List<NotificationChannelGroup> notificationChannelGroups = getNotificationChannelGroups();
|
|
|
|
if (!notificationChannelGroups.isEmpty()) {
|
|
|
|
List<NotificationChannel> emptyList = i >= 28 ? Collections.emptyList() : 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, emptyList));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return arrayList;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return Collections.emptyList();
|
|
|
|
}
|
|
|
|
|
2021-07-24 02:37:17 +00:00
|
|
|
@NonNull
|
|
|
|
public List<NotificationChannel> getNotificationChannels() {
|
|
|
|
return Build.VERSION.SDK_INT >= 26 ? this.mNotificationManager.getNotificationChannels() : Collections.emptyList();
|
|
|
|
}
|
|
|
|
|
2021-09-15 06:33:54 +00:00
|
|
|
@NonNull
|
|
|
|
public List<NotificationChannelCompat> getNotificationChannelsCompat() {
|
|
|
|
if (Build.VERSION.SDK_INT >= 26) {
|
|
|
|
List<NotificationChannel> notificationChannels = getNotificationChannels();
|
|
|
|
if (!notificationChannels.isEmpty()) {
|
|
|
|
ArrayList arrayList = new ArrayList(notificationChannels.size());
|
|
|
|
for (NotificationChannel notificationChannel : notificationChannels) {
|
|
|
|
arrayList.add(new NotificationChannelCompat(notificationChannel));
|
|
|
|
}
|
|
|
|
return arrayList;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return Collections.emptyList();
|
|
|
|
}
|
|
|
|
|
2021-07-24 02:37:17 +00:00
|
|
|
public void notify(int i, @NonNull Notification notification) {
|
|
|
|
notify(null, i, notification);
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
this.mNotificationManager.notify(str, i, notification);
|
|
|
|
}
|
|
|
|
}
|