summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Lothian <rjlothian@google.com>2017-12-04 11:56:58 -0500
committerandroid-build-team Robot <android-build-team-robot@google.com>2018-02-09 21:28:03 +0000
commit0748edce4a8741611d0d856534ec8a5abeb920e5 (patch)
treeb4cbd3d1f5bef0f1b30a644d5e33278d12116569
parentfef1a3e7ca5ab18ede42c5729661459fcd691e09 (diff)
downloadbase-0748edce4a8741611d0d856534ec8a5abeb920e5.tar.gz
Handle onBindingDied in notification manager
On Android, if the process containing the service being bound to crashes before the bind succeeds, the app doing the binding won't get a success or failure callback. When that happens in this code, this leaves notif. manager thinking that a binding is in progress, so it never attempts to rebind until the device is rebooted. Bug: 69064494 Test: manual, crashed listener on proc start, verified not unbound forever Change-Id: Id2082744208e21a709d9453365f282449a2e9407 (cherry picked from commit 4a86a51b672617b02994fc812e4f96342daf424e) (cherry picked from commit 1936097afc3188ed5f2bb4e7211bb404364eeb38)
-rw-r--r--services/core/java/com/android/server/notification/ManagedServices.java29
1 files changed, 29 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java
index b7b91a76ebf3..625764cea550 100644
--- a/services/core/java/com/android/server/notification/ManagedServices.java
+++ b/services/core/java/com/android/server/notification/ManagedServices.java
@@ -39,8 +39,10 @@ import android.content.pm.ServiceInfo;
import android.content.pm.UserInfo;
import android.os.Binder;
import android.os.Build;
+import android.os.Handler;
import android.os.IBinder;
import android.os.IInterface;
+import android.os.Looper;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
@@ -82,6 +84,7 @@ abstract public class ManagedServices {
protected final String TAG = getClass().getSimpleName();
protected final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+ private static final int ON_BINDING_DIED_REBIND_DELAY_MS = 10000;
protected static final String ENABLED_SERVICES_SEPARATOR = ":";
/**
@@ -101,12 +104,15 @@ abstract public class ManagedServices {
private final IPackageManager mPm;
private final UserManager mUm;
private final Config mConfig;
+ private final Handler mHandler = new Handler(Looper.getMainLooper());
// contains connections to all connected services, including app services
// and system services
private final ArrayList<ManagedServiceInfo> mServices = new ArrayList<>();
// things that will be put into mServices as soon as they're ready
private final ArrayList<String> mServicesBinding = new ArrayList<>();
+ private final ArraySet<String> mServicesRebinding = new ArraySet<>();
+
// lists the component names of all enabled (and therefore potentially connected)
// app services for current profiles.
private ArraySet<ComponentName> mEnabledServicesForCurrentProfiles
@@ -823,6 +829,7 @@ abstract public class ManagedServices {
final String servicesBindingTag = name.toString() + "/" + userid;
if (mServicesBinding.contains(servicesBindingTag)) {
+ Slog.v(TAG, "Not registering " + name + " as bind is already in progress");
// stop registering this thing already! we're working on it
return;
}
@@ -871,6 +878,7 @@ abstract public class ManagedServices {
boolean added = false;
ManagedServiceInfo info = null;
synchronized (mMutex) {
+ mServicesRebinding.remove(servicesBindingTag);
mServicesBinding.remove(servicesBindingTag);
try {
mService = asInterface(binder);
@@ -892,6 +900,27 @@ abstract public class ManagedServices {
mServicesBinding.remove(servicesBindingTag);
Slog.v(TAG, getCaption() + " connection lost: " + name);
}
+
+ @Override
+ public void onBindingDied(ComponentName name) {
+ Slog.w(TAG, getCaption() + " binding died: " + name);
+ synchronized (mMutex) {
+ mServicesBinding.remove(servicesBindingTag);
+ mContext.unbindService(this);
+ if (!mServicesRebinding.contains(servicesBindingTag)) {
+ mServicesRebinding.add(servicesBindingTag);
+ mHandler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ registerService(name, userid);
+ }
+ }, ON_BINDING_DIED_REBIND_DELAY_MS);
+ } else {
+ Slog.v(TAG, getCaption() + " not rebinding as "
+ + "a previous rebind attempt was made: " + name);
+ }
+ }
+ }
};
if (!mContext.bindServiceAsUser(intent,
serviceConnection,