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

Commit 5e1ff36d authored by Anton Potapov's avatar Anton Potapov
Browse files

Add force updating ManagedProfileController state on user change

Fixes: 254024780
Test: Manual + autotests
Change-Id: Ic276f886a4862ef20e773f1775d1f80c7f00b1cb
parent 53827bfa
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -608,7 +608,7 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, P

        if (TextUtils.isEmpty(tileList)) {
            tileList = res.getString(R.string.quick_settings_tiles);
            if (DEBUG) Log.d(TAG, "Loaded tile specs from config: " + tileList);
            if (DEBUG) Log.d(TAG, "Loaded tile specs from default config: " + tileList);
        } else {
            if (DEBUG) Log.d(TAG, "Loaded tile specs from setting: " + tileList);
        }
+3 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.service.quicksettings.Tile;
import android.view.View;
import android.widget.Switch;

import androidx.annotation.MainThread;
import androidx.annotation.Nullable;

import com.android.internal.logging.MetricsLogger;
@@ -91,11 +92,13 @@ public class WorkModeTile extends QSTileImpl<BooleanState> implements
    }

    @Override
    @MainThread
    public void onManagedProfileChanged() {
        refreshState(mProfileController.isWorkModeEnabled());
    }

    @Override
    @MainThread
    public void onManagedProfileRemoved() {
        mHost.removeTile(getTileSpec());
        mHost.unmarkTileAsAutoAdded(getTileSpec());
+15 −1
Original line number Diff line number Diff line
@@ -14,6 +14,8 @@

package com.android.systemui.statusbar.phone;

import androidx.annotation.MainThread;

import com.android.systemui.statusbar.phone.ManagedProfileController.Callback;
import com.android.systemui.statusbar.policy.CallbackController;

@@ -25,8 +27,20 @@ public interface ManagedProfileController extends CallbackController<Callback> {

    boolean isWorkModeEnabled();

    public interface Callback {
    /**
     * Callback to get updates about work profile status.
     */
    interface Callback {
        /**
         * Called when managed profile change is detected. This always runs on the main thread.
         */
        @MainThread
        void onManagedProfileChanged();

        /**
         * Called when managed profile removal is detected. This always runs on the main thread.
         */
        @MainThread
        void onManagedProfileRemoved();
    }
}
+34 −31
Original line number Diff line number Diff line
@@ -33,31 +33,28 @@ import java.util.concurrent.Executor;

import javax.inject.Inject;

/**
 */
@SysUISingleton
public class ManagedProfileControllerImpl implements ManagedProfileController {

    private final List<Callback> mCallbacks = new ArrayList<>();

    private final UserTrackerCallback mUserTrackerCallback = new UserTrackerCallback();
    private final Context mContext;
    private final Executor mMainExecutor;
    private final UserManager mUserManager;
    private final UserTracker mUserTracker;
    private final LinkedList<UserInfo> mProfiles;

    private boolean mListening;
    private int mCurrentUser;

    /**
     */
    @Inject
    public ManagedProfileControllerImpl(Context context, @Main Executor mainExecutor,
            UserTracker userTracker) {
            UserTracker userTracker, UserManager userManager) {
        mContext = context;
        mMainExecutor = mainExecutor;
        mUserManager = UserManager.get(mContext);
        mUserManager = userManager;
        mUserTracker = userTracker;
        mProfiles = new LinkedList<UserInfo>();
        mProfiles = new LinkedList<>();
    }

    @Override
@@ -100,16 +97,22 @@ public class ManagedProfileControllerImpl implements ManagedProfileController {
                }
            }
            if (mProfiles.size() == 0 && hadProfile && (user == mCurrentUser)) {
                for (Callback callback : mCallbacks) {
                    callback.onManagedProfileRemoved();
                }
                mMainExecutor.execute(this::notifyManagedProfileRemoved);
            }
            mCurrentUser = user;
        }
    }

    private void notifyManagedProfileRemoved() {
        for (Callback callback : mCallbacks) {
            callback.onManagedProfileRemoved();
        }
    }

    public boolean hasActiveProfile() {
        if (!mListening) reloadManagedProfiles();
        if (!mListening || mUserTracker.getUserId() != mCurrentUser) {
            reloadManagedProfiles();
        }
        synchronized (mProfiles) {
            return mProfiles.size() > 0;
        }
@@ -134,14 +137,14 @@ public class ManagedProfileControllerImpl implements ManagedProfileController {
        mListening = listening;
        if (listening) {
            reloadManagedProfiles();
            mUserTracker.addCallback(mUserChangedCallback, mMainExecutor);
            mUserTracker.addCallback(mUserTrackerCallback, mMainExecutor);
        } else {
            mUserTracker.removeCallback(mUserChangedCallback);
            mUserTracker.removeCallback(mUserTrackerCallback);
        }
    }

    private final UserTracker.Callback mUserChangedCallback =
            new UserTracker.Callback() {
    private final class UserTrackerCallback implements UserTracker.Callback {

        @Override
        public void onUserChanged(int newUser, @NonNull Context userContext) {
            reloadManagedProfiles();
@@ -157,5 +160,5 @@ public class ManagedProfileControllerImpl implements ManagedProfileController {
                callback.onManagedProfileChanged();
            }
        }
            };
    }
}
+88 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.statusbar.phone

import android.content.pm.UserInfo
import android.os.UserManager
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.settings.UserTracker
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.time.FakeSystemClock
import junit.framework.Assert
import org.junit.Before
import org.junit.Test
import org.mockito.Mock
import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations

@SmallTest
class ManagedProfileControllerImplTest : SysuiTestCase() {

    private val mainExecutor: FakeExecutor = FakeExecutor(FakeSystemClock())

    private lateinit var controller: ManagedProfileControllerImpl

    @Mock private lateinit var userTracker: UserTracker
    @Mock private lateinit var userManager: UserManager

    @Before
    fun setup() {
        MockitoAnnotations.initMocks(this)

        controller = ManagedProfileControllerImpl(context, mainExecutor, userTracker, userManager)
    }

    @Test
    fun hasWorkingProfile_isWorkModeEnabled_returnsTrue() {
        `when`(userTracker.userId).thenReturn(1)
        setupWorkingProfile(1)

        Assert.assertEquals(true, controller.hasActiveProfile())
    }

    @Test
    fun noWorkingProfile_isWorkModeEnabled_returnsFalse() {
        `when`(userTracker.userId).thenReturn(1)

        Assert.assertEquals(false, controller.hasActiveProfile())
    }

    @Test
    fun listeningUserChanges_isWorkModeEnabled_returnsTrue() {
        `when`(userTracker.userId).thenReturn(1)
        controller.addCallback(TestCallback)
        `when`(userTracker.userId).thenReturn(2)
        setupWorkingProfile(2)

        Assert.assertEquals(true, controller.hasActiveProfile())
    }

    private fun setupWorkingProfile(userId: Int) {
        `when`(userManager.getEnabledProfiles(userId))
            .thenReturn(
                listOf(UserInfo(userId, "test_user", "", 0, UserManager.USER_TYPE_PROFILE_MANAGED))
            )
    }

    private object TestCallback : ManagedProfileController.Callback {

        override fun onManagedProfileChanged() = Unit

        override fun onManagedProfileRemoved() = Unit
    }
}