Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e9556a89 authored by dooyoung.hwang's avatar dooyoung.hwang
Browse files

Share one receiver for CurrentUserTracker

Each CurrentUserTracker has one receiver per one object.
This could cause unnecessary transaction as Tracker counts
increases. The idea of redcuing receiver is creating
one static receiver for CurrentUserTracker and share it
with all object.

Test: Check if Quicksetting order is changed properly
after switching user.

Change-Id: I8404829826391f8b315b42bbd0f50e77b783eeab
parent b37d8262
Loading
Loading
Loading
Loading
+74 −20
Original line number Diff line number Diff line
@@ -22,39 +22,93 @@ import android.content.Context;
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;
        return mUserReceiver.getCurrentUserId();
    }

    public void startTracking() {
        mUserReceiver.addTracker(mCallback);
    }

    public void stopTracking() {
        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())) {
            int oldUserId = mCurrentUserId;
            mCurrentUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
            if (oldUserId != mCurrentUserId) {
                onUserSwitched(mCurrentUserId);
                notifyUserSwitched(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0));
            }
        }

        public int getCurrentUserId() {
            return mCurrentUserId;
        }

    public void startTracking() {
        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);
        mContext.registerReceiver(this, filter);
                mAppContext.registerReceiver(this, filter);
                mReceiverRegistered = true;
            }
        }

    public void stopTracking() {
        mContext.unregisterReceiver(this);
        private void removeTracker(Consumer<Integer> callback) {
            if (mCallbacks.contains(callback)) {
                mCallbacks.remove(callback);
                if (mCallbacks.size() == 0 && mReceiverRegistered) {
                    mAppContext.unregisterReceiver(this);
                    mReceiverRegistered = false;
                }
            }
        }

    public abstract void onUserSwitched(int newUserId);
        private void notifyUserSwitched(int newUserId) {
            if (mCurrentUserId != newUserId) {
                mCurrentUserId = newUserId;
                for (Consumer<Integer> consumer : mCallbacks) {
                    consumer.accept(newUserId);
                }
            }
        }
    }
}