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

Commit 84d55b03 authored by Nikhil Kumar's avatar Nikhil Kumar
Browse files

Moved KeyguardDismissHandler initialization in KeyguardDismissUtil

The KeyGuardDismissHandler was not being initialized for secondary users.
To fix this, the KeyguardDismissUtil is refactored to initialize the
dismissHandler during constructor injection.
This ensures that the dismissHandler is initialized for all users,
including secondary users.

Test: tested screen recording and share option from notification bar
on a secondary user
Test: atest RecordingServiceTest -c, atest SmartReplyViewTest -c
Bug: 274613098
Bug: 279559510

Change-Id: I4b439bebae93a09dcf76c6412598a0b640b8a215
parent 05b23ee4
Loading
Loading
Loading
Loading
+0 −13
Original line number Diff line number Diff line
@@ -500,7 +500,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
    private final AlternateBouncerInteractor mAlternateBouncerInteractor;

    private final PluginDependencyProvider mPluginDependencyProvider;
    private final KeyguardDismissUtil mKeyguardDismissUtil;
    private final ExtensionController mExtensionController;
    private final UserInfoControllerImpl mUserInfoControllerImpl;
    private final DemoModeController mDemoModeController;
@@ -787,7 +786,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
            InitController initController,
            @Named(TIME_TICK_HANDLER_NAME) Handler timeTickHandler,
            PluginDependencyProvider pluginDependencyProvider,
            KeyguardDismissUtil keyguardDismissUtil,
            ExtensionController extensionController,
            UserInfoControllerImpl userInfoControllerImpl,
            PhoneStatusBarPolicy phoneStatusBarPolicy,
@@ -884,7 +882,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
        mKeyguardViewMediatorCallback = viewMediatorCallback;
        mInitController = initController;
        mPluginDependencyProvider = pluginDependencyProvider;
        mKeyguardDismissUtil = keyguardDismissUtil;
        mExtensionController = extensionController;
        mUserInfoControllerImpl = userInfoControllerImpl;
        mIconPolicy = phoneStatusBarPolicy;
@@ -1742,7 +1739,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {

        mLightBarController.setBiometricUnlockController(mBiometricUnlockController);
        mMediaManager.setBiometricUnlockController(mBiometricUnlockController);
        mKeyguardDismissUtil.setDismissHandler(this::executeWhenUnlocked);
        Trace.endSection();
    }

@@ -2366,15 +2362,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
        mNotificationsController.resetUserExpandedStates();
    }

    private void executeWhenUnlocked(OnDismissAction action, boolean requiresShadeOpen,
            boolean afterKeyguardGone) {
        if (mKeyguardStateController.isShowing() && requiresShadeOpen) {
            mStatusBarStateController.setLeaveOpenOnKeyguardHide(true);
        }
        mActivityStarter.dismissKeyguardThenExecute(action, null /* cancelAction */,
                afterKeyguardGone /* afterKeyguardGone */);
    }

    /**
     * Notify the shade controller that the current user changed
     *
+18 −25
Original line number Diff line number Diff line
@@ -16,48 +16,41 @@

package com.android.systemui.statusbar.phone;

import android.util.Log;

import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.policy.KeyguardStateController;

import javax.inject.Inject;

/**
 * Executes actions that require the screen to be unlocked. Delegates the actual handling to an
 * implementation passed via {@link #setDismissHandler}.
 * Executes actions that require the screen to be unlocked.
 */
@SysUISingleton
public class KeyguardDismissUtil implements KeyguardDismissHandler {
    private static final String TAG = "KeyguardDismissUtil";
    private final KeyguardStateController mKeyguardStateController;

    private volatile KeyguardDismissHandler mDismissHandler;
    private final SysuiStatusBarStateController mStatusBarStateController;

    @Inject
    public KeyguardDismissUtil() {
    }
    private final ActivityStarter mActivityStarter;

    /** Sets the actual {@link KeyguardDismissHandler} implementation. */
    public void setDismissHandler(KeyguardDismissHandler dismissHandler) {
        mDismissHandler = dismissHandler;
    @Inject
    public KeyguardDismissUtil(KeyguardStateController keyguardStateController,
            SysuiStatusBarStateController statusBarStateController,
            ActivityStarter activityStarter) {
        mKeyguardStateController = keyguardStateController;
        mStatusBarStateController = statusBarStateController;
        mActivityStarter = activityStarter;
    }

    /**
     * Executes an action that requires the screen to be unlocked.
     *
     * <p>Must be called after {@link #setDismissHandler}.
     *
     * @param requiresShadeOpen does the shade need to be forced open when hiding the keyguard?
     */
    @Override
    public void executeWhenUnlocked(OnDismissAction action, boolean requiresShadeOpen,
            boolean afterKeyguardGone) {
        KeyguardDismissHandler dismissHandler = mDismissHandler;
        if (dismissHandler == null) {
            Log.wtf(TAG, "KeyguardDismissHandler not set.");
            action.onDismiss();
            return;
        if (mKeyguardStateController.isShowing() && requiresShadeOpen) {
            mStatusBarStateController.setLeaveOpenOnKeyguardHide(true);
        }
        dismissHandler.executeWhenUnlocked(action, requiresShadeOpen, afterKeyguardGone);
        mActivityStarter.dismissKeyguardThenExecute(action, null /* cancelAction */,
                afterKeyguardGone /* afterKeyguardGone */);
    }
}
+48 −13
Original line number Diff line number Diff line
@@ -16,9 +16,11 @@

package com.android.systemui.screenrecord;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
@@ -32,6 +34,7 @@ import android.content.Intent;
import android.os.Binder;
import android.os.Handler;
import android.os.RemoteException;
import android.os.UserHandle;
import android.testing.AndroidTestingRunner;

import androidx.test.filters.SmallTest;
@@ -41,7 +44,9 @@ import com.android.systemui.SysuiTestCase;
import com.android.systemui.media.MediaProjectionCaptureTarget;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.settings.UserContextProvider;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.phone.KeyguardDismissUtil;
import com.android.systemui.statusbar.policy.KeyguardStateController;

import org.junit.Before;
import org.junit.Test;
@@ -77,20 +82,38 @@ public class RecordingServiceTest extends SysuiTestCase {
    private UserContextProvider mUserContextTracker;
    @Captor
    private ArgumentCaptor<Runnable> mRunnableCaptor;
    private KeyguardDismissUtil mKeyguardDismissUtil = new KeyguardDismissUtil() {
        public void executeWhenUnlocked(ActivityStarter.OnDismissAction action,
                boolean requiresShadeOpen) {
            action.onDismiss();
        }
    };
    @Mock
    private KeyguardStateController mKeyguardStateController;
    @Mock
    private SysuiStatusBarStateController mStatusBarStateController;
    @Mock
    private ActivityStarter mActivityStarter;

    private static final String PERMISSION_SELF = "com.android.systemui.permission.SELF";

    private KeyguardDismissUtil mKeyguardDismissUtil = new KeyguardDismissUtil(
            mKeyguardStateController, mStatusBarStateController, mActivityStarter);

    private RecordingService mRecordingService;

    private class RecordingServiceTestable extends RecordingService {
        RecordingServiceTestable(
                RecordingController controller, Executor executor,
                Handler handler, UiEventLogger uiEventLogger,
                NotificationManager notificationManager,
                UserContextProvider userContextTracker, KeyguardDismissUtil keyguardDismissUtil) {
            super(controller, executor, handler,
                    uiEventLogger, notificationManager, userContextTracker, keyguardDismissUtil);
            attachBaseContext(mContext);
        }
    }

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
        mRecordingService = Mockito.spy(new RecordingService(mController, mExecutor, mHandler,
                mUiEventLogger, mNotificationManager, mUserContextTracker, mKeyguardDismissUtil));
        mRecordingService = Mockito.spy(new RecordingServiceTestable(mController, mExecutor,
                mHandler, mUiEventLogger, mNotificationManager,
                mUserContextTracker, mKeyguardDismissUtil));

        // Return actual context info
        doReturn(mContext).when(mRecordingService).getApplicationContext();
@@ -160,8 +183,7 @@ public class RecordingServiceTest extends SysuiTestCase {
        Intent startIntent = RecordingService.getStartIntent(mContext, 0, 0, false, null);
        mRecordingService.onStartCommand(startIntent, 0, 0);

        // Then the state is set to not recording
        verify(mController).updateState(false);
        assertUpdateState(false);
    }

    @Test
@@ -179,7 +201,7 @@ public class RecordingServiceTest extends SysuiTestCase {

        mRecordingService.onStopped();

        verify(mController).updateState(false);
        assertUpdateState(false);
    }

    @Test
@@ -224,8 +246,21 @@ public class RecordingServiceTest extends SysuiTestCase {
        verify(mExecutor).execute(mRunnableCaptor.capture());
        mRunnableCaptor.getValue().run();

        // Then the state is set to not recording and we cancel the notification
        verify(mController).updateState(false);
        assertUpdateState(false);
        verify(mNotificationManager).cancelAsUser(any(), anyInt(), any());
    }

    private void assertUpdateState(boolean state) {
        // Then the state is set to not recording, and we cancel the notification
        // non SYSTEM user doesn't have the reference to the correct controller,
        // so a broadcast is sent in case of non SYSTEM user.
        if (UserHandle.USER_SYSTEM == mContext.getUserId()) {
            verify(mController).updateState(state);
        } else {
            ArgumentCaptor<Intent> argumentCaptor = ArgumentCaptor.forClass(Intent.class);
            verify(mRecordingService).sendBroadcast(argumentCaptor.capture(), eq(PERMISSION_SELF));
            assertEquals(RecordingController.INTENT_UPDATE_STATE,
                    argumentCaptor.getValue().getAction());
        }
    }
}
+0 −2
Original line number Diff line number Diff line
@@ -287,7 +287,6 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
    @Mock private StatusBarTouchableRegionManager mStatusBarTouchableRegionManager;
    @Mock private ScreenPinningRequest mScreenPinningRequest;
    @Mock private PluginDependencyProvider mPluginDependencyProvider;
    @Mock private KeyguardDismissUtil mKeyguardDismissUtil;
    @Mock private ExtensionController mExtensionController;
    @Mock private UserInfoControllerImpl mUserInfoControllerImpl;
    @Mock private PhoneStatusBarPolicy mPhoneStatusBarPolicy;
@@ -516,7 +515,6 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
                mInitController,
                new Handler(TestableLooper.get(this).getLooper()),
                mPluginDependencyProvider,
                mKeyguardDismissUtil,
                mExtensionController,
                mUserInfoControllerImpl,
                mPhoneStatusBarPolicy,
+85 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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 static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

import android.testing.AndroidTestingRunner;

import androidx.test.filters.SmallTest;

import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.policy.KeyguardStateController;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

@RunWith(AndroidTestingRunner.class)
@SmallTest
public class KeyguardDismissUtilTest extends SysuiTestCase {
    @Mock
    private KeyguardStateController mKeyguardStateController;
    @Mock
    private SysuiStatusBarStateController mStatusBarStateController;
    @Mock
    private ActivityStarter mActivityStarter;
    @Mock
    private ActivityStarter.OnDismissAction mAction;

    private KeyguardDismissUtil mKeyguardDismissUtil;

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
        mKeyguardDismissUtil = new KeyguardDismissUtil(
                mKeyguardStateController, mStatusBarStateController, mActivityStarter);
    }

    @Test
    public void testSetLeaveOpenOnKeyguardHideWhenKeyGuardStateControllerIsShowing() {
        doReturn(true).when(mKeyguardStateController).isShowing();

        mKeyguardDismissUtil.executeWhenUnlocked(mAction, true /* requiresShadeOpen */,
                true /* afterKeyguardGone */);

        verify(mStatusBarStateController).setLeaveOpenOnKeyguardHide(true);

        verify(mActivityStarter).dismissKeyguardThenExecute(mAction, null, true);

    }

    @Test
    public void testSetLeaveOpenOnKeyguardHideWhenKeyGuardStateControllerIsNotShowing() {
        doReturn(false).when(mKeyguardStateController).isShowing();

        mKeyguardDismissUtil.executeWhenUnlocked(mAction, true /* requiresShadeOpen */,
                true /* afterKeyguardGone */);

        //no interaction with mStatusBarStateController
        verify(mStatusBarStateController, times(0)).setLeaveOpenOnKeyguardHide(true);

        verify(mActivityStarter).dismissKeyguardThenExecute(mAction, null, true);

    }
}
Loading