Merge "Share one receiver for CurrentUserTracker" am: 06d619ccfa am: a84c7ea396 am: 61e2ff5727
am: a1f9cd0ee6

Change-Id: Iffd6e087582c730323c7d9250cd3d5abba92015a
diff --git a/packages/SystemUI/src/com/android/systemui/settings/CurrentUserTracker.java b/packages/SystemUI/src/com/android/systemui/settings/CurrentUserTracker.java
index dd80750..005206f 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/CurrentUserTracker.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/CurrentUserTracker.java
@@ -22,39 +22,93 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 
-public abstract class CurrentUserTracker extends BroadcastReceiver {
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Consumer;
 
-    private Context mContext;
-    private int mCurrentUserId;
+public abstract class CurrentUserTracker {
+    private final UserReceiver mUserReceiver;
+
+    private Consumer<Integer> mCallback = this::onUserSwitched;
 
     public CurrentUserTracker(Context context) {
-        mContext = context;
+        mUserReceiver = UserReceiver.getInstance(context);
     }
 
     public int getCurrentUserId() {
-        return mCurrentUserId;
-    }
-
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) {
-            int oldUserId = mCurrentUserId;
-            mCurrentUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
-            if (oldUserId != mCurrentUserId) {
-                onUserSwitched(mCurrentUserId);
-            }
-        }
+        return mUserReceiver.getCurrentUserId();
     }
 
     public void startTracking() {
-        mCurrentUserId = ActivityManager.getCurrentUser();
-        IntentFilter filter = new IntentFilter(Intent.ACTION_USER_SWITCHED);
-        mContext.registerReceiver(this, filter);
+        mUserReceiver.addTracker(mCallback);
     }
 
     public void stopTracking() {
-        mContext.unregisterReceiver(this);
+        mUserReceiver.removeTracker(mCallback);
     }
 
     public abstract void onUserSwitched(int newUserId);
+
+    private static class UserReceiver extends BroadcastReceiver {
+        private static UserReceiver sInstance;
+
+        private Context mAppContext;
+        private boolean mReceiverRegistered;
+        private int mCurrentUserId;
+
+        private List<Consumer<Integer>> mCallbacks = new ArrayList<>();
+
+        private UserReceiver(Context context) {
+            mAppContext = context.getApplicationContext();
+        }
+
+        static UserReceiver getInstance(Context context) {
+            if (sInstance == null) {
+                sInstance = new UserReceiver(context);
+            }
+            return sInstance;
+        }
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) {
+                notifyUserSwitched(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0));
+            }
+        }
+
+        public int getCurrentUserId() {
+            return mCurrentUserId;
+        }
+
+        private void addTracker(Consumer<Integer> callback) {
+            if (!mCallbacks.contains(callback)) {
+                mCallbacks.add(callback);
+            }
+            if (!mReceiverRegistered) {
+                mCurrentUserId = ActivityManager.getCurrentUser();
+                IntentFilter filter = new IntentFilter(Intent.ACTION_USER_SWITCHED);
+                mAppContext.registerReceiver(this, filter);
+                mReceiverRegistered = true;
+            }
+        }
+
+        private void removeTracker(Consumer<Integer> callback) {
+            if (mCallbacks.contains(callback)) {
+                mCallbacks.remove(callback);
+                if (mCallbacks.size() == 0 && mReceiverRegistered) {
+                    mAppContext.unregisterReceiver(this);
+                    mReceiverRegistered = false;
+                }
+            }
+        }
+
+        private void notifyUserSwitched(int newUserId) {
+            if (mCurrentUserId != newUserId) {
+                mCurrentUserId = newUserId;
+                for (Consumer<Integer> consumer : mCallbacks) {
+                    consumer.accept(newUserId);
+                }
+            }
+        }
+    }
 }