Merge "Add method to request window magnification connection"

This commit is contained in:
Ryan Lin
2020-03-16 06:24:01 +00:00
committed by Android (Google) Code Review
8 changed files with 311 additions and 6 deletions

View File

@@ -227,4 +227,12 @@ oneway interface IStatusBar
* display.
*/
void suppressAmbientDisplay(boolean suppress);
/**
* Requests {@link WindowMagnification} to set window magnification connection through
* {@link AccessibilityManager#setWindowMagnificationConnection(IWindowMagnificationConnection)}
*
* @param connect {@code true} if needs connection, otherwise set the connection to null.
*/
void requestWindowMagnificationConnection(boolean connect);
}

View File

@@ -28,37 +28,50 @@ import android.os.RemoteException;
import android.provider.Settings;
import android.util.Log;
import android.view.Display;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.IWindowMagnificationConnection;
import android.view.accessibility.IWindowMagnificationConnectionCallback;
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.R;
import com.android.systemui.SystemUI;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.statusbar.CommandQueue;
import javax.inject.Inject;
import javax.inject.Singleton;
/**
* Class to handle changes to setting window_magnification value.
* Class to handle the interaction with
* {@link com.android.server.accessibility.AccessibilityManagerService}. It invokes
* {@link AccessibilityManager#setWindowMagnificationConnection(IWindowMagnificationConnection)}
* when {@code IStatusBar#requestWindowMagnificationConnection(boolean)} is called.
*/
@Singleton
public class WindowMagnification extends SystemUI implements WindowMagnifierCallback {
public class WindowMagnification extends SystemUI implements WindowMagnifierCallback,
CommandQueue.Callbacks {
private static final String TAG = "WindowMagnification";
private static final int CONFIG_MASK =
ActivityInfo.CONFIG_DENSITY | ActivityInfo.CONFIG_ORIENTATION;
private WindowMagnificationController mWindowMagnificationController;
@VisibleForTesting
protected WindowMagnificationController mWindowMagnificationController;
private final Handler mHandler;
//TODO:Set it by the request from AccessibilityManager.
private WindowMagnificationConnectionImpl mWindowMagnificationConnectionImpl;
private final AccessibilityManager mAccessibilityManager;
private final CommandQueue mCommandQueue;
private WindowMagnificationConnectionImpl mWindowMagnificationConnectionImpl;
private Configuration mLastConfiguration;
@Inject
public WindowMagnification(Context context, @Main Handler mainHandler) {
public WindowMagnification(Context context, @Main Handler mainHandler,
CommandQueue commandQueue) {
super(context);
mHandler = mainHandler;
mLastConfiguration = new Configuration(context.getResources().getConfiguration());
mAccessibilityManager = (AccessibilityManager) mContext.getSystemService(
Context.ACCESSIBILITY_SERVICE);
mCommandQueue = commandQueue;
}
@Override
@@ -75,6 +88,7 @@ public class WindowMagnification extends SystemUI implements WindowMagnifierCall
@Override
public void start() {
mCommandQueue.addCallback(this);
mContext.getContentResolver().registerContentObserver(
Settings.Secure.getUriFor(Settings.Secure.WINDOW_MAGNIFICATION),
true, new ContentObserver(mHandler) {
@@ -150,6 +164,29 @@ public class WindowMagnification extends SystemUI implements WindowMagnifierCall
}
}
@Override
public void requestWindowMagnificationConnection(boolean connect) {
if (connect) {
setWindowMagnificationConnection();
} else {
clearWindowMagnificationConnection();
}
}
private void setWindowMagnificationConnection() {
if (mWindowMagnificationConnectionImpl == null) {
mWindowMagnificationConnectionImpl = new WindowMagnificationConnectionImpl(this,
mHandler);
}
mAccessibilityManager.setWindowMagnificationConnection(
mWindowMagnificationConnectionImpl);
}
private void clearWindowMagnificationConnection() {
mAccessibilityManager.setWindowMagnificationConnection(null);
//TODO: destroy controllers.
}
private static class WindowMagnificationConnectionImpl extends
IWindowMagnificationConnection.Stub {

View File

@@ -126,6 +126,7 @@ public class CommandQueue extends IStatusBar.Stub implements CallbackController<
private static final int MSG_HIDE_TOAST = 54 << MSG_SHIFT;
private static final int MSG_TRACING_STATE_CHANGED = 55 << MSG_SHIFT;
private static final int MSG_SUPPRESS_AMBIENT_DISPLAY = 56 << MSG_SHIFT;
private static final int MSG_REQUEST_WINDOW_MAGNIFICATION_CONNECTION = 57 << MSG_SHIFT;
public static final int FLAG_EXCLUDE_NONE = 0;
public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0;
@@ -338,6 +339,15 @@ public class CommandQueue extends IStatusBar.Stub implements CallbackController<
* @param enabled
*/
default void onTracingStateChanged(boolean enabled) { }
/**
* Requests {@link com.android.systemui.accessibility.WindowMagnification} to invoke
* {@code android.view.accessibility.AccessibilityManager#
* setWindowMagnificationConnection(IWindowMagnificationConnection)}
*
* @param connect {@code true} if needs connection, otherwise set the connection to null.
*/
default void requestWindowMagnificationConnection(boolean connect) { }
}
public CommandQueue(Context context) {
@@ -885,6 +895,14 @@ public class CommandQueue extends IStatusBar.Stub implements CallbackController<
}
}
@Override
public void requestWindowMagnificationConnection(boolean connect) {
synchronized (mLock) {
mHandler.obtainMessage(MSG_REQUEST_WINDOW_MAGNIFICATION_CONNECTION, connect)
.sendToTarget();
}
}
private void handleShowImeButton(int displayId, IBinder token, int vis, int backDisposition,
boolean showImeSwitcher, boolean isMultiClientImeEnabled) {
if (displayId == INVALID_DISPLAY) return;
@@ -1302,6 +1320,11 @@ public class CommandQueue extends IStatusBar.Stub implements CallbackController<
callbacks.suppressAmbientDisplay((boolean) msg.obj);
}
break;
case MSG_REQUEST_WINDOW_MAGNIFICATION_CONNECTION:
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).requestWindowMagnificationConnection((Boolean) msg.obj);
}
break;
}
}
}

View File

@@ -0,0 +1,118 @@
/*
* Copyright (C) 2020 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.accessibility;
import static org.junit.Assert.assertNotNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.verify;
import android.content.Context;
import android.os.RemoteException;
import android.testing.AndroidTestingRunner;
import android.view.Display;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.IWindowMagnificationConnection;
import android.view.accessibility.IWindowMagnificationConnectionCallback;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.CommandQueue;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
/**
* Tests for {@link android.view.accessibility.IWindowMagnificationConnection} retrieved from
* {@link WindowMagnification}
*/
@SmallTest
@RunWith(AndroidTestingRunner.class)
public class IWindowMagnificationConnectionTest extends SysuiTestCase {
private static final int TEST_DISPLAY = Display.DEFAULT_DISPLAY;
@Mock
private AccessibilityManager mAccessibilityManager;
@Mock
private CommandQueue mCommandQueue;
@Mock
private IWindowMagnificationConnectionCallback mConnectionCallback;
@Mock
private WindowMagnificationController mWindowMagnificationController;
private IWindowMagnificationConnection mIWindowMagnificationConnection;
private WindowMagnification mWindowMagnification;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
getContext().addMockSystemService(Context.ACCESSIBILITY_SERVICE, mAccessibilityManager);
doAnswer(invocation -> {
mIWindowMagnificationConnection = invocation.getArgument(0);
return null;
}).when(mAccessibilityManager).setWindowMagnificationConnection(
any(IWindowMagnificationConnection.class));
mWindowMagnification = new WindowMagnification(getContext(),
getContext().getMainThreadHandler(), mCommandQueue);
mWindowMagnification.mWindowMagnificationController = mWindowMagnificationController;
mWindowMagnification.requestWindowMagnificationConnection(true);
assertNotNull(mIWindowMagnificationConnection);
mIWindowMagnificationConnection.setConnectionCallback(mConnectionCallback);
}
@Test
public void enableWindowMagnification() throws RemoteException {
mIWindowMagnificationConnection.enableWindowMagnification(TEST_DISPLAY, 3.0f, Float.NaN,
Float.NaN);
waitForIdleSync();
verify(mWindowMagnificationController).enableWindowMagnification(3.0f, Float.NaN,
Float.NaN);
}
@Test
public void disableWindowMagnification_deleteWindowMagnification() throws RemoteException {
mIWindowMagnificationConnection.enableWindowMagnification(TEST_DISPLAY, 3.0f, Float.NaN,
Float.NaN);
waitForIdleSync();
mIWindowMagnificationConnection.disableWindowMagnification(TEST_DISPLAY);
waitForIdleSync();
verify(mWindowMagnificationController).deleteWindowMagnification();
}
@Test
public void setScale() throws RemoteException {
mIWindowMagnificationConnection.setScale(TEST_DISPLAY, 3.0f);
waitForIdleSync();
verify(mWindowMagnificationController).setScale(3.0f);
}
@Test
public void moveWindowMagnifier() throws RemoteException {
mIWindowMagnificationConnection.moveWindowMagnifier(TEST_DISPLAY, 100f, 200f);
waitForIdleSync();
verify(mWindowMagnificationController).moveWindowMagnifier(100f, 200f);
}
}

View File

@@ -0,0 +1,97 @@
/*
* Copyright (C) 2020 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.accessibility;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.verify;
import android.content.Context;
import android.graphics.Rect;
import android.os.RemoteException;
import android.testing.AndroidTestingRunner;
import android.view.Display;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.IWindowMagnificationConnection;
import android.view.accessibility.IWindowMagnificationConnectionCallback;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.CommandQueue;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
@SmallTest
@RunWith(AndroidTestingRunner.class)
public class WindowMagnificationTest extends SysuiTestCase {
@Mock
private AccessibilityManager mAccessibilityManager;
private CommandQueue mCommandQueue;
private WindowMagnification mWindowMagnification;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
getContext().addMockSystemService(Context.ACCESSIBILITY_SERVICE, mAccessibilityManager);
mCommandQueue = new CommandQueue(getContext());
mWindowMagnification = new WindowMagnification(getContext(),
getContext().getMainThreadHandler(), mCommandQueue);
mWindowMagnification.start();
}
@Test
public void requestWindowMagnificationConnection_setWindowMagnificationConnection() {
mCommandQueue.requestWindowMagnificationConnection(true);
waitForIdleSync();
verify(mAccessibilityManager).setWindowMagnificationConnection(any(
IWindowMagnificationConnection.class));
mCommandQueue.requestWindowMagnificationConnection(false);
waitForIdleSync();
verify(mAccessibilityManager).setWindowMagnificationConnection(null);
}
@Test
public void onWindowMagnifierBoundsChanged() throws RemoteException {
final IWindowMagnificationConnectionCallback connectionCallback = Mockito.mock(
IWindowMagnificationConnectionCallback.class);
final Rect testBounds = new Rect(0, 0, 500, 600);
doAnswer(invocation -> {
IWindowMagnificationConnection connection = invocation.getArgument(0);
connection.setConnectionCallback(connectionCallback);
return null;
}).when(mAccessibilityManager).setWindowMagnificationConnection(
any(IWindowMagnificationConnection.class));
mCommandQueue.requestWindowMagnificationConnection(true);
waitForIdleSync();
mWindowMagnification.onWindowMagnifierBoundsChanged(Display.DEFAULT_DISPLAY, testBounds);
verify(connectionCallback).onWindowMagnifierBoundsChanged(Display.DEFAULT_DISPLAY,
testBounds);
}
}

View File

@@ -455,4 +455,11 @@ public class CommandQueueTest extends SysuiTestCase {
waitForIdleSync();
verify(mCallbacks).suppressAmbientDisplay(true);
}
@Test
public void testRequestWindowMagnificationConnection() {
mCommandQueue.requestWindowMagnificationConnection(true);
waitForIdleSync();
verify(mCallbacks).requestWindowMagnificationConnection(true);
}
}

View File

@@ -137,4 +137,10 @@ public interface StatusBarManagerInternal {
/** @see com.android.internal.statusbar.IStatusBar#hideToast(String, IBinder) */
void hideToast(String packageName, IBinder token);
/**
* @see com.android.internal.statusbar.IStatusBar#requestWindowMagnificationConnection(boolean
* request)
*/
void requestWindowMagnificationConnection(boolean request);
}

View File

@@ -520,6 +520,15 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
} catch (RemoteException ex) { }
}
}
@Override
public void requestWindowMagnificationConnection(boolean request) {
if (mBar != null) {
try {
mBar.requestWindowMagnificationConnection(request);
} catch (RemoteException ex) { }
}
}
};
private final GlobalActionsProvider mGlobalActionsProvider = new GlobalActionsProvider() {