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

Commit 62c089ce authored by Yohei Yukawa's avatar Yohei Yukawa
Browse files

Mock local services in a more reliable way

This is a preparation before making

  InputMethodManagerService#mImeDrawsImeNavBarRes

multi-user ready.

As discussed in https://github.com/mockito/mockito/issues/2142, mocked
static methods are available only in the calling thread. For testing
purposes just calling

  LocalServices.addService()

to inject mocked local services then removing them with

  LocalServices.removeAllServicesForTest()

would be much more simpler and easier to understand.

Bug: 345519864
Test: atest FrameworksInputMethodSystemServerTests
Flag: TEST_ONLY
Change-Id: If2d5e8ae6e002de9698c6a8eda489a6824f244e7
parent c7aa0be4
Loading
Loading
Loading
Loading
+17 −14
Original line number Original line Diff line number Diff line
@@ -46,6 +46,7 @@ import android.os.Process;
import android.os.RemoteException;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.os.UserHandle;
import android.util.ArraySet;
import android.view.InputChannel;
import android.view.InputChannel;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.EditorInfo;
import android.window.ImeOnBackInvokedDispatcher;
import android.window.ImeOnBackInvokedDispatcher;
@@ -131,6 +132,14 @@ public class InputMethodManagerServiceTestBase {
    protected boolean mIsLargeScreen;
    protected boolean mIsLargeScreen;
    private InputManagerGlobal.TestSession mInputManagerGlobalSession;
    private InputManagerGlobal.TestSession mInputManagerGlobalSession;


    private final ArraySet<Class<?>> mRegisteredLocalServices = new ArraySet<>();

    protected <T> void addLocalServiceMock(Class<T> type, T service) {
        mRegisteredLocalServices.add(type);
        LocalServices.removeServiceForTest(type);
        LocalServices.addService(type, service);
    }

    @BeforeClass
    @BeforeClass
    public static void setupClass() {
    public static void setupClass() {
        // Make sure DeviceConfig's lazy-initialized ContentProvider gets
        // Make sure DeviceConfig's lazy-initialized ContentProvider gets
@@ -145,7 +154,6 @@ public class InputMethodManagerServiceTestBase {
                mockitoSession()
                mockitoSession()
                        .initMocks(this)
                        .initMocks(this)
                        .strictness(Strictness.LENIENT)
                        .strictness(Strictness.LENIENT)
                        .spyStatic(LocalServices.class)
                        .mockStatic(ServiceManager.class)
                        .mockStatic(ServiceManager.class)
                        .mockStatic(SystemServerInitThreadPool.class)
                        .mockStatic(SystemServerInitThreadPool.class)
                        .startMocking();
                        .startMocking();
@@ -160,18 +168,13 @@ public class InputMethodManagerServiceTestBase {
        mEditorInfo.packageName = TEST_EDITOR_PKG_NAME;
        mEditorInfo.packageName = TEST_EDITOR_PKG_NAME;


        // Injecting and mocking local services.
        // Injecting and mocking local services.
        doReturn(mMockWindowManagerInternal)
        addLocalServiceMock(WindowManagerInternal.class, mMockWindowManagerInternal);
                .when(() -> LocalServices.getService(WindowManagerInternal.class));
        addLocalServiceMock(ActivityManagerInternal.class, mMockActivityManagerInternal);
        doReturn(mMockActivityManagerInternal)
        addLocalServiceMock(PackageManagerInternal.class, mMockPackageManagerInternal);
                .when(() -> LocalServices.getService(ActivityManagerInternal.class));
        addLocalServiceMock(InputManagerInternal.class, mMockInputManagerInternal);
        doReturn(mMockPackageManagerInternal)
        addLocalServiceMock(UserManagerInternal.class, mMockUserManagerInternal);
                .when(() -> LocalServices.getService(PackageManagerInternal.class));
        addLocalServiceMock(ImeTargetVisibilityPolicy.class, mMockImeTargetVisibilityPolicy);
        doReturn(mMockInputManagerInternal)

                .when(() -> LocalServices.getService(InputManagerInternal.class));
        doReturn(mMockUserManagerInternal)
                .when(() -> LocalServices.getService(UserManagerInternal.class));
        doReturn(mMockImeTargetVisibilityPolicy)
                .when(() -> LocalServices.getService(ImeTargetVisibilityPolicy.class));
        doReturn(mMockIInputMethodManager)
        doReturn(mMockIInputMethodManager)
                .when(() -> ServiceManager.getServiceOrThrow(Context.INPUT_METHOD_SERVICE));
                .when(() -> ServiceManager.getServiceOrThrow(Context.INPUT_METHOD_SERVICE));
        doReturn(mMockIPlatformCompat)
        doReturn(mMockIPlatformCompat)
@@ -283,7 +286,7 @@ public class InputMethodManagerServiceTestBase {
        if (mInputManagerGlobalSession != null) {
        if (mInputManagerGlobalSession != null) {
            mInputManagerGlobalSession.close();
            mInputManagerGlobalSession.close();
        }
        }
        LocalServices.removeServiceForTest(InputMethodManagerInternal.class);
        mRegisteredLocalServices.forEach(LocalServices::removeServiceForTest);
    }
    }


    protected void verifyShowSoftInput(boolean setVisible, boolean showSoftInput)
    protected void verifyShowSoftInput(boolean setVisible, boolean showSoftInput)
+1 −3
Original line number Original line Diff line number Diff line
@@ -50,7 +50,6 @@ import com.android.internal.inputmethod.InputBindResult;
import com.android.internal.inputmethod.InputMethodDebug;
import com.android.internal.inputmethod.InputMethodDebug;
import com.android.internal.inputmethod.StartInputFlags;
import com.android.internal.inputmethod.StartInputFlags;
import com.android.internal.inputmethod.StartInputReason;
import com.android.internal.inputmethod.StartInputReason;
import com.android.server.LocalServices;
import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
import com.android.server.wm.WindowManagerInternal;
import com.android.server.wm.WindowManagerInternal;


@@ -270,8 +269,7 @@ public class InputMethodManagerServiceWindowGainedFocusTest


    @Test
    @Test
    public void startInputOrWindowGainedFocus_localeHintsOverride() throws RemoteException {
    public void startInputOrWindowGainedFocus_localeHintsOverride() throws RemoteException {
        doReturn(mMockVdmInternal).when(
        addLocalServiceMock(VirtualDeviceManagerInternal.class, mMockVdmInternal);
                () -> LocalServices.getService(VirtualDeviceManagerInternal.class));
        LocaleList overrideLocale = LocaleList.forLanguageTags("zh-CN");
        LocaleList overrideLocale = LocaleList.forLanguageTags("zh-CN");
        doReturn(overrideLocale).when(mMockVdmInternal).getPreferredLocaleListForUid(anyInt());
        doReturn(overrideLocale).when(mMockVdmInternal).getPreferredLocaleListForUid(anyInt());
        mockHasImeFocusAndRestoreImeVisibility(false /* restoreImeVisibility */);
        mockHasImeFocusAndRestoreImeVisibility(false /* restoreImeVisibility */);