Fix memory leaks in system_server
unlink DeathRecipients in a whole bunch of places to avoid memory leaks
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 62dc651..5ee29ac 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -3981,7 +3981,10 @@
             ProviderRecord pr = mProviderMap.get(name);
             if (pr.mProvider.asBinder() == provider.asBinder()) {
                 Log.i(TAG, "Removing dead content provider: " + name);
-                mProviderMap.remove(name);
+                ProviderRecord removed = mProviderMap.remove(name);
+                if (removed != null) {
+                    removed.mProvider.asBinder().unlinkToDeath(removed, 0);
+                }
             }
         }
     }
@@ -3990,7 +3993,10 @@
         ProviderRecord pr = mProviderMap.get(name);
         if (pr.mProvider.asBinder() == provider.asBinder()) {
             Log.i(TAG, "Removing dead content provider: " + name);
-            mProviderMap.remove(name);
+            ProviderRecord removed = mProviderMap.remove(name);
+            if (removed != null) {
+                removed.mProvider.asBinder().unlinkToDeath(removed, 0);
+            }
         }
     }
 
diff --git a/location/java/com/android/internal/location/GpsLocationProvider.java b/location/java/com/android/internal/location/GpsLocationProvider.java
index edd1ea0..4a51e31 100755
--- a/location/java/com/android/internal/location/GpsLocationProvider.java
+++ b/location/java/com/android/internal/location/GpsLocationProvider.java
@@ -617,6 +617,9 @@
             synchronized(mListeners) {
                 mListeners.remove(this);
             }
+            if (mListener != null) {
+                mListener.asBinder().unlinkToDeath(this, 0);
+            }
         }
     }
 
diff --git a/location/java/com/android/internal/location/LocationProviderProxy.java b/location/java/com/android/internal/location/LocationProviderProxy.java
index bd7088c..4ae424a 100644
--- a/location/java/com/android/internal/location/LocationProviderProxy.java
+++ b/location/java/com/android/internal/location/LocationProviderProxy.java
@@ -53,6 +53,12 @@
         }
     }
 
+    public void unlinkProvider() {
+        if (mProvider != null) {
+            mProvider.asBinder().unlinkToDeath(this, 0);
+        }
+    }
+
     public String getName() {
         return mName;
     }
@@ -255,5 +261,6 @@
     public void binderDied() {
         Log.w(TAG, "Location Provider " + mName + " died");
         mDead = true;
+        mProvider.asBinder().unlinkToDeath(this, 0);
     }
 }
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java
index fc37290..0f5b3fd 100644
--- a/services/java/com/android/server/LocationManagerService.java
+++ b/services/java/com/android/server/LocationManagerService.java
@@ -507,6 +507,7 @@
 
     private void removeProvider(LocationProviderProxy provider) {
         mProviders.remove(provider);
+        provider.unlinkProvider();
         mProvidersByName.remove(provider.getName());
     }
 
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index c5ea5fa9..79d78ad1 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -709,7 +709,10 @@
                     p.awakeOnSet = true;
                 }
             } else {
-                mPokeLocks.remove(token);
+                PokeLock rLock = mPokeLocks.remove(token);
+                if (rLock != null) {
+                    token.unlinkToDeath(rLock, 0);
+                }
             }
 
             int oldPokey = mPokey;
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 5df88b2..f5e2e3d 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -1875,7 +1875,9 @@
         private WifiLock removeLock(IBinder binder) {
             int index = findLockByBinder(binder);
             if (index >= 0) {
-                return mList.remove(index);
+                WifiLock ret = mList.remove(index);
+                ret.unlinkDeathRecipient();
+                return ret;
             } else {
                 return null;
             }
@@ -1987,6 +1989,10 @@
                 binderDied();
             }
         }
+
+        void unlinkDeathRecipient() {
+            mBinder.unlinkToDeath(this, 0);
+        }
     }
 
     private class Multicaster extends DeathRecipient {
@@ -2054,7 +2060,10 @@
 
     private void removeMulticasterLocked(int i, int uid)
     {
-        mMulticasters.remove(i);
+        Multicaster removed = mMulticasters.remove(i);
+        if (removed != null) {
+            removed.unlinkDeathRecipient();
+        }
         if (mMulticasters.size() == 0) {
             WifiNative.startPacketFiltering();
         }
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 9bad153..cfa625c 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -3407,7 +3407,10 @@
                 synchronized (mWindowMap) {
                     for (int i=0; i<mRotationWatchers.size(); i++) {
                         if (watcherBinder == mRotationWatchers.get(i).asBinder()) {
-                            mRotationWatchers.remove(i);
+                            IRotationWatcher removed = mRotationWatchers.remove(i);
+                            if (removed != null) {
+                                removed.asBinder().unlinkToDeath(this, 0);
+                            }
                             i--;
                         }
                     }
@@ -5442,6 +5445,7 @@
             } catch (RemoteException e) {
             }
             synchronized(mWindowMap) {
+                mClient.asBinder().unlinkToDeath(this, 0);
                 mClientDead = true;
                 killSessionLocked();
             }
diff --git a/services/java/com/android/server/status/StatusBarService.java b/services/java/com/android/server/status/StatusBarService.java
index 48cbace..b44168a 100644
--- a/services/java/com/android/server/status/StatusBarService.java
+++ b/services/java/com/android/server/status/StatusBarService.java
@@ -119,6 +119,7 @@
         public void binderDied() {
             Log.i(TAG, "binder died for pkg=" + pkg);
             disable(0, token, pkg);
+            token.unlinkToDeath(this, 0);
         }
     }
 
@@ -494,6 +495,7 @@
             if (what == 0 || !token.isBinderAlive()) {
                 if (tok != null) {
                     mDisableRecords.remove(i);
+                    tok.token.unlinkToDeath(tok, 0);
                 }
             } else {
                 if (tok == null) {