Merge "Supports showing Ime shortcuts in the system shortcuts UI." into udc-qpr-dev
This commit is contained in:
@@ -471,9 +471,22 @@ interface IWindowManager
|
|||||||
* Requests Keyboard Shortcuts from the displayed window.
|
* Requests Keyboard Shortcuts from the displayed window.
|
||||||
*
|
*
|
||||||
* @param receiver The receiver to deliver the results to.
|
* @param receiver The receiver to deliver the results to.
|
||||||
|
* @param deviceId The deviceId of KeyEvent by which this request is triggered, or -1 if it's
|
||||||
|
* not triggered by a KeyEvent.
|
||||||
|
* @see #requestImeKeyboardShortcuts(IResultReceiver, int)
|
||||||
*/
|
*/
|
||||||
void requestAppKeyboardShortcuts(IResultReceiver receiver, int deviceId);
|
void requestAppKeyboardShortcuts(IResultReceiver receiver, int deviceId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requests Keyboard Shortcuts from currently selected IME.
|
||||||
|
*
|
||||||
|
* @param receiver The receiver to deliver the results to.
|
||||||
|
* @param deviceId The deviceId of KeyEvent by which this request is triggered, or -1 if it's
|
||||||
|
* not triggered by a KeyEvent.
|
||||||
|
* @see #requestAppKeyboardShortcuts(IResultReceiver, int)
|
||||||
|
*/
|
||||||
|
void requestImeKeyboardShortcuts(IResultReceiver receiver, int deviceId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the current stable insets from the primary display.
|
* Retrieves the current stable insets from the primary display.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1384,14 +1384,27 @@ public interface WindowManager extends ViewManager {
|
|||||||
"android.window.PROPERTY_ACTIVITY_EMBEDDING_SPLITS_ENABLED";
|
"android.window.PROPERTY_ACTIVITY_EMBEDDING_SPLITS_ENABLED";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request for keyboard shortcuts to be retrieved asynchronously.
|
* Request for app's keyboard shortcuts to be retrieved asynchronously.
|
||||||
*
|
*
|
||||||
* @param receiver The callback to be triggered when the result is ready.
|
* @param receiver The callback to be triggered when the result is ready.
|
||||||
|
* @param deviceId The deviceId of KeyEvent by which this request is triggered, or -1 if it's
|
||||||
|
* not triggered by a KeyEvent.
|
||||||
*
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public void requestAppKeyboardShortcuts(final KeyboardShortcutsReceiver receiver, int deviceId);
|
public void requestAppKeyboardShortcuts(final KeyboardShortcutsReceiver receiver, int deviceId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request for ime's keyboard shortcuts to be retrieved asynchronously.
|
||||||
|
*
|
||||||
|
* @param receiver The callback to be triggered when the result is ready.
|
||||||
|
* @param deviceId The deviceId of KeyEvent by which this request is triggered, or -1 if it's
|
||||||
|
* not triggered by a KeyEvent.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
default void requestImeKeyboardShortcuts(KeyboardShortcutsReceiver receiver, int deviceId) {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the touch region for the current IME window, or an empty region if there is none.
|
* Return the touch region for the current IME window, or an empty region if there is none.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -215,14 +215,36 @@ public final class WindowManagerImpl implements WindowManager {
|
|||||||
@Override
|
@Override
|
||||||
public void send(int resultCode, Bundle resultData) throws RemoteException {
|
public void send(int resultCode, Bundle resultData) throws RemoteException {
|
||||||
List<KeyboardShortcutGroup> result =
|
List<KeyboardShortcutGroup> result =
|
||||||
resultData.getParcelableArrayList(PARCEL_KEY_SHORTCUTS_ARRAY, android.view.KeyboardShortcutGroup.class);
|
resultData.getParcelableArrayList(PARCEL_KEY_SHORTCUTS_ARRAY,
|
||||||
|
android.view.KeyboardShortcutGroup.class);
|
||||||
receiver.onKeyboardShortcutsReceived(result);
|
receiver.onKeyboardShortcutsReceived(result);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
WindowManagerGlobal.getWindowManagerService()
|
WindowManagerGlobal.getWindowManagerService()
|
||||||
.requestAppKeyboardShortcuts(resultReceiver, deviceId);
|
.requestAppKeyboardShortcuts(resultReceiver, deviceId);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
|
throw e.rethrowFromSystemServer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void requestImeKeyboardShortcuts(
|
||||||
|
final KeyboardShortcutsReceiver receiver, int deviceId) {
|
||||||
|
IResultReceiver resultReceiver = new IResultReceiver.Stub() {
|
||||||
|
@Override
|
||||||
|
public void send(int resultCode, Bundle resultData) throws RemoteException {
|
||||||
|
List<KeyboardShortcutGroup> result =
|
||||||
|
resultData.getParcelableArrayList(PARCEL_KEY_SHORTCUTS_ARRAY,
|
||||||
|
android.view.KeyboardShortcutGroup.class);
|
||||||
|
receiver.onKeyboardShortcutsReceived(result);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
WindowManagerGlobal.getWindowManagerService()
|
||||||
|
.requestImeKeyboardShortcuts(resultReceiver, deviceId);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
throw e.rethrowFromSystemServer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3379,6 +3379,12 @@
|
|||||||
"group": "WM_DEBUG_REMOTE_ANIMATIONS",
|
"group": "WM_DEBUG_REMOTE_ANIMATIONS",
|
||||||
"at": "com\/android\/server\/wm\/RemoteAnimationController.java"
|
"at": "com\/android\/server\/wm\/RemoteAnimationController.java"
|
||||||
},
|
},
|
||||||
|
"975028389": {
|
||||||
|
"message": "unable to call receiver for empty keyboard shortcuts",
|
||||||
|
"level": "ERROR",
|
||||||
|
"group": "WM_ERROR",
|
||||||
|
"at": "com\/android\/server\/wm\/WindowManagerService.java"
|
||||||
|
},
|
||||||
"975275467": {
|
"975275467": {
|
||||||
"message": "Set animatingExit: reason=remove\/isAnimating win=%s",
|
"message": "Set animatingExit: reason=remove\/isAnimating win=%s",
|
||||||
"level": "VERBOSE",
|
"level": "VERBOSE",
|
||||||
|
|||||||
@@ -56,7 +56,6 @@ import android.view.View.AccessibilityDelegate;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.view.WindowManager.KeyboardShortcutsReceiver;
|
|
||||||
import android.view.accessibility.AccessibilityNodeInfo;
|
import android.view.accessibility.AccessibilityNodeInfo;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
@@ -337,6 +336,12 @@ public final class KeyboardShortcutListSearch {
|
|||||||
mSpecialCharacterNames.put(KeyEvent.KEYCODE_MUHENKAN, "無変換");
|
mSpecialCharacterNames.put(KeyEvent.KEYCODE_MUHENKAN, "無変換");
|
||||||
mSpecialCharacterNames.put(KeyEvent.KEYCODE_HENKAN, "変換");
|
mSpecialCharacterNames.put(KeyEvent.KEYCODE_HENKAN, "変換");
|
||||||
mSpecialCharacterNames.put(KeyEvent.KEYCODE_KATAKANA_HIRAGANA, "かな");
|
mSpecialCharacterNames.put(KeyEvent.KEYCODE_KATAKANA_HIRAGANA, "かな");
|
||||||
|
mSpecialCharacterNames.put(KeyEvent.KEYCODE_ALT_LEFT, "Alt");
|
||||||
|
mSpecialCharacterNames.put(KeyEvent.KEYCODE_ALT_RIGHT, "Alt");
|
||||||
|
mSpecialCharacterNames.put(KeyEvent.KEYCODE_CTRL_LEFT, "Ctrl");
|
||||||
|
mSpecialCharacterNames.put(KeyEvent.KEYCODE_CTRL_RIGHT, "Ctrl");
|
||||||
|
mSpecialCharacterNames.put(KeyEvent.KEYCODE_SHIFT_LEFT, "Shift");
|
||||||
|
mSpecialCharacterNames.put(KeyEvent.KEYCODE_SHIFT_RIGHT, "Shift");
|
||||||
|
|
||||||
mModifierNames.put(KeyEvent.META_META_ON, "Meta");
|
mModifierNames.put(KeyEvent.META_META_ON, "Meta");
|
||||||
mModifierNames.put(KeyEvent.META_CTRL_ON, "Ctrl");
|
mModifierNames.put(KeyEvent.META_CTRL_ON, "Ctrl");
|
||||||
@@ -411,27 +416,45 @@ public final class KeyboardShortcutListSearch {
|
|||||||
mKeyCharacterMap = mBackupKeyCharacterMap;
|
mKeyCharacterMap = mBackupKeyCharacterMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean mAppShortcutsReceived;
|
||||||
|
private boolean mImeShortcutsReceived;
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
void showKeyboardShortcuts(int deviceId) {
|
void showKeyboardShortcuts(int deviceId) {
|
||||||
retrieveKeyCharacterMap(deviceId);
|
retrieveKeyCharacterMap(deviceId);
|
||||||
mWindowManager.requestAppKeyboardShortcuts(new KeyboardShortcutsReceiver() {
|
mAppShortcutsReceived = false;
|
||||||
@Override
|
mImeShortcutsReceived = false;
|
||||||
public void onKeyboardShortcutsReceived(
|
mWindowManager.requestAppKeyboardShortcuts(result -> {
|
||||||
final List<KeyboardShortcutGroup> result) {
|
// Add specific app shortcuts
|
||||||
// Add specific app shortcuts
|
if (result.isEmpty()) {
|
||||||
if (result.isEmpty()) {
|
mKeySearchResultMap.put(SHORTCUT_SPECIFICAPP_INDEX, false);
|
||||||
mKeySearchResultMap.put(SHORTCUT_SPECIFICAPP_INDEX, false);
|
} else {
|
||||||
} else {
|
mSpecificAppGroup.addAll(reMapToKeyboardShortcutMultiMappingGroup(result));
|
||||||
mSpecificAppGroup = reMapToKeyboardShortcutMultiMappingGroup(result);
|
mKeySearchResultMap.put(SHORTCUT_SPECIFICAPP_INDEX, true);
|
||||||
mKeySearchResultMap.put(SHORTCUT_SPECIFICAPP_INDEX, true);
|
}
|
||||||
}
|
mAppShortcutsReceived = true;
|
||||||
mFullShortsGroup.add(SHORTCUT_SYSTEM_INDEX, mSystemGroup);
|
if (mImeShortcutsReceived) {
|
||||||
mFullShortsGroup.add(SHORTCUT_INPUT_INDEX, mInputGroup);
|
mergeAndShowKeyboardShortcutsGroups();
|
||||||
mFullShortsGroup.add(SHORTCUT_OPENAPPS_INDEX, mOpenAppsGroup);
|
|
||||||
mFullShortsGroup.add(SHORTCUT_SPECIFICAPP_INDEX, mSpecificAppGroup);
|
|
||||||
showKeyboardShortcutSearchList(mFullShortsGroup);
|
|
||||||
}
|
}
|
||||||
}, deviceId);
|
}, deviceId);
|
||||||
|
mWindowManager.requestImeKeyboardShortcuts(result -> {
|
||||||
|
// Add specific Ime shortcuts
|
||||||
|
if (!result.isEmpty()) {
|
||||||
|
mInputGroup.addAll(reMapToKeyboardShortcutMultiMappingGroup(result));
|
||||||
|
}
|
||||||
|
mImeShortcutsReceived = true;
|
||||||
|
if (mAppShortcutsReceived) {
|
||||||
|
mergeAndShowKeyboardShortcutsGroups();
|
||||||
|
}
|
||||||
|
}, deviceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void mergeAndShowKeyboardShortcutsGroups() {
|
||||||
|
mFullShortsGroup.add(SHORTCUT_SYSTEM_INDEX, mSystemGroup);
|
||||||
|
mFullShortsGroup.add(SHORTCUT_INPUT_INDEX, mInputGroup);
|
||||||
|
mFullShortsGroup.add(SHORTCUT_OPENAPPS_INDEX, mOpenAppsGroup);
|
||||||
|
mFullShortsGroup.add(SHORTCUT_SPECIFICAPP_INDEX, mSpecificAppGroup);
|
||||||
|
showKeyboardShortcutSearchList(mFullShortsGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The original data structure is only for 1-to-1 shortcut mapping, so remap the old
|
// The original data structure is only for 1-to-1 shortcut mapping, so remap the old
|
||||||
|
|||||||
@@ -56,7 +56,6 @@ import android.view.View.AccessibilityDelegate;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.view.WindowManager.KeyboardShortcutsReceiver;
|
|
||||||
import android.view.accessibility.AccessibilityNodeInfo;
|
import android.view.accessibility.AccessibilityNodeInfo;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
@@ -129,6 +128,9 @@ public final class KeyboardShortcuts {
|
|||||||
private KeyCharacterMap mKeyCharacterMap;
|
private KeyCharacterMap mKeyCharacterMap;
|
||||||
private KeyCharacterMap mBackupKeyCharacterMap;
|
private KeyCharacterMap mBackupKeyCharacterMap;
|
||||||
|
|
||||||
|
@Nullable private List<KeyboardShortcutGroup> mReceivedAppShortcutGroups = null;
|
||||||
|
@Nullable private List<KeyboardShortcutGroup> mReceivedImeShortcutGroups = null;
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
KeyboardShortcuts(Context context, WindowManager windowManager) {
|
KeyboardShortcuts(Context context, WindowManager windowManager) {
|
||||||
this.mContext = new ContextThemeWrapper(
|
this.mContext = new ContextThemeWrapper(
|
||||||
@@ -324,6 +326,12 @@ public final class KeyboardShortcuts {
|
|||||||
mSpecialCharacterNames.put(KeyEvent.KEYCODE_MUHENKAN, "無変換");
|
mSpecialCharacterNames.put(KeyEvent.KEYCODE_MUHENKAN, "無変換");
|
||||||
mSpecialCharacterNames.put(KeyEvent.KEYCODE_HENKAN, "変換");
|
mSpecialCharacterNames.put(KeyEvent.KEYCODE_HENKAN, "変換");
|
||||||
mSpecialCharacterNames.put(KeyEvent.KEYCODE_KATAKANA_HIRAGANA, "かな");
|
mSpecialCharacterNames.put(KeyEvent.KEYCODE_KATAKANA_HIRAGANA, "かな");
|
||||||
|
mSpecialCharacterNames.put(KeyEvent.KEYCODE_ALT_LEFT, "Alt");
|
||||||
|
mSpecialCharacterNames.put(KeyEvent.KEYCODE_ALT_RIGHT, "Alt");
|
||||||
|
mSpecialCharacterNames.put(KeyEvent.KEYCODE_CTRL_LEFT, "Ctrl");
|
||||||
|
mSpecialCharacterNames.put(KeyEvent.KEYCODE_CTRL_RIGHT, "Ctrl");
|
||||||
|
mSpecialCharacterNames.put(KeyEvent.KEYCODE_SHIFT_LEFT, "Shift");
|
||||||
|
mSpecialCharacterNames.put(KeyEvent.KEYCODE_SHIFT_RIGHT, "Shift");
|
||||||
|
|
||||||
mModifierNames.put(KeyEvent.META_META_ON, "Meta");
|
mModifierNames.put(KeyEvent.META_META_ON, "Meta");
|
||||||
mModifierNames.put(KeyEvent.META_CTRL_ON, "Ctrl");
|
mModifierNames.put(KeyEvent.META_CTRL_ON, "Ctrl");
|
||||||
@@ -382,18 +390,36 @@ public final class KeyboardShortcuts {
|
|||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
void showKeyboardShortcuts(int deviceId) {
|
void showKeyboardShortcuts(int deviceId) {
|
||||||
retrieveKeyCharacterMap(deviceId);
|
retrieveKeyCharacterMap(deviceId);
|
||||||
mWindowManager.requestAppKeyboardShortcuts(new KeyboardShortcutsReceiver() {
|
mReceivedAppShortcutGroups = null;
|
||||||
@Override
|
mReceivedImeShortcutGroups = null;
|
||||||
public void onKeyboardShortcutsReceived(
|
mWindowManager.requestAppKeyboardShortcuts(
|
||||||
final List<KeyboardShortcutGroup> result) {
|
result -> {
|
||||||
result.add(getSystemShortcuts());
|
mReceivedAppShortcutGroups = result;
|
||||||
final KeyboardShortcutGroup appShortcuts = getDefaultApplicationShortcuts();
|
maybeMergeAndShowKeyboardShortcuts();
|
||||||
if (appShortcuts != null) {
|
}, deviceId);
|
||||||
result.add(appShortcuts);
|
mWindowManager.requestImeKeyboardShortcuts(
|
||||||
}
|
result -> {
|
||||||
showKeyboardShortcutsDialog(result);
|
mReceivedImeShortcutGroups = result;
|
||||||
}
|
maybeMergeAndShowKeyboardShortcuts();
|
||||||
}, deviceId);
|
}, deviceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void maybeMergeAndShowKeyboardShortcuts() {
|
||||||
|
if (mReceivedAppShortcutGroups == null || mReceivedImeShortcutGroups == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
List<KeyboardShortcutGroup> shortcutGroups = mReceivedAppShortcutGroups;
|
||||||
|
shortcutGroups.addAll(mReceivedImeShortcutGroups);
|
||||||
|
mReceivedAppShortcutGroups = null;
|
||||||
|
mReceivedImeShortcutGroups = null;
|
||||||
|
|
||||||
|
final KeyboardShortcutGroup defaultAppShortcuts =
|
||||||
|
getDefaultApplicationShortcuts();
|
||||||
|
if (defaultAppShortcuts != null) {
|
||||||
|
shortcutGroups.add(defaultAppShortcuts);
|
||||||
|
}
|
||||||
|
shortcutGroups.add(getSystemShortcuts());
|
||||||
|
showKeyboardShortcutsDialog(shortcutGroups);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void dismissKeyboardShortcuts() {
|
private void dismissKeyboardShortcuts() {
|
||||||
|
|||||||
@@ -76,5 +76,6 @@ public class KeyboardShortcutListSearchTest extends SysuiTestCase {
|
|||||||
mKeyboardShortcutListSearch.toggle(mContext, DEVICE_ID);
|
mKeyboardShortcutListSearch.toggle(mContext, DEVICE_ID);
|
||||||
|
|
||||||
verify(mWindowManager).requestAppKeyboardShortcuts(any(), anyInt());
|
verify(mWindowManager).requestAppKeyboardShortcuts(any(), anyInt());
|
||||||
|
verify(mWindowManager).requestImeKeyboardShortcuts(any(), anyInt());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,5 +75,6 @@ public class KeyboardShortcutsTest extends SysuiTestCase {
|
|||||||
mKeyboardShortcuts.toggle(mContext, DEVICE_ID);
|
mKeyboardShortcuts.toggle(mContext, DEVICE_ID);
|
||||||
|
|
||||||
verify(mWindowManager).requestAppKeyboardShortcuts(any(), anyInt());
|
verify(mWindowManager).requestAppKeyboardShortcuts(any(), anyInt());
|
||||||
|
verify(mWindowManager).requestImeKeyboardShortcuts(any(), anyInt());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7185,15 +7185,45 @@ public class WindowManagerService extends IWindowManager.Stub
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void requestAppKeyboardShortcuts(IResultReceiver receiver, int deviceId) {
|
public void requestAppKeyboardShortcuts(IResultReceiver receiver, int deviceId) {
|
||||||
mContext.enforceCallingOrSelfPermission(REGISTER_WINDOW_MANAGER_LISTENERS,
|
enforceRegisterWindowManagerListenersPermission("requestAppKeyboardShortcuts");
|
||||||
"requestAppKeyboardShortcuts");
|
|
||||||
|
|
||||||
|
WindowState focusedWindow = getFocusedWindow();
|
||||||
|
if (focusedWindow == null || focusedWindow.mClient == null) {
|
||||||
|
notifyReceiverWithEmptyBundle(receiver);
|
||||||
|
return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
WindowState focusedWindow = getFocusedWindow();
|
focusedWindow.mClient.requestAppKeyboardShortcuts(receiver, deviceId);
|
||||||
if (focusedWindow != null && focusedWindow.mClient != null) {
|
|
||||||
getFocusedWindow().mClient.requestAppKeyboardShortcuts(receiver, deviceId);
|
|
||||||
}
|
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
|
notifyReceiverWithEmptyBundle(receiver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void requestImeKeyboardShortcuts(IResultReceiver receiver, int deviceId) {
|
||||||
|
enforceRegisterWindowManagerListenersPermission("requestImeKeyboardShortcuts");
|
||||||
|
|
||||||
|
WindowState imeWindow = mRoot.getCurrentInputMethodWindow();
|
||||||
|
if (imeWindow == null || imeWindow.mClient == null) {
|
||||||
|
notifyReceiverWithEmptyBundle(receiver);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
imeWindow.mClient.requestAppKeyboardShortcuts(receiver, deviceId);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
notifyReceiverWithEmptyBundle(receiver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void enforceRegisterWindowManagerListenersPermission(String message) {
|
||||||
|
mContext.enforceCallingOrSelfPermission(REGISTER_WINDOW_MANAGER_LISTENERS, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void notifyReceiverWithEmptyBundle(IResultReceiver receiver) {
|
||||||
|
try {
|
||||||
|
receiver.send(0, Bundle.EMPTY);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
ProtoLog.e(WM_ERROR, "unable to call receiver for empty keyboard shortcuts");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ import static com.google.common.truth.Truth.assertThat;
|
|||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.Assert.assertNull;
|
||||||
import static org.junit.Assert.assertThrows;
|
import static org.junit.Assert.assertThrows;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
@@ -99,6 +100,7 @@ import androidx.test.filters.SmallTest;
|
|||||||
import androidx.test.platform.app.InstrumentationRegistry;
|
import androidx.test.platform.app.InstrumentationRegistry;
|
||||||
|
|
||||||
import com.android.compatibility.common.util.AdoptShellPermissionsRule;
|
import com.android.compatibility.common.util.AdoptShellPermissionsRule;
|
||||||
|
import com.android.internal.os.IResultReceiver;
|
||||||
|
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -905,6 +907,56 @@ public class WindowManagerServiceTests extends WindowTestsBase {
|
|||||||
argThat(h -> (h.inputConfig & InputConfig.SPY) == InputConfig.SPY));
|
argThat(h -> (h.inputConfig & InputConfig.SPY) == InputConfig.SPY));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRequestKeyboardShortcuts_noWindow() {
|
||||||
|
doNothing().when(mWm.mContext).enforceCallingOrSelfPermission(anyString(), anyString());
|
||||||
|
doReturn(null).when(mWm).getFocusedWindowLocked();
|
||||||
|
doReturn(null).when(mWm.mRoot).getCurrentInputMethodWindow();
|
||||||
|
|
||||||
|
TestResultReceiver receiver = new TestResultReceiver();
|
||||||
|
mWm.requestAppKeyboardShortcuts(receiver, 0);
|
||||||
|
assertNotNull(receiver.resultData);
|
||||||
|
assertTrue(receiver.resultData.isEmpty());
|
||||||
|
|
||||||
|
receiver = new TestResultReceiver();
|
||||||
|
mWm.requestImeKeyboardShortcuts(receiver, 0);
|
||||||
|
assertNotNull(receiver.resultData);
|
||||||
|
assertTrue(receiver.resultData.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRequestKeyboardShortcuts() throws RemoteException {
|
||||||
|
final IWindow window = mock(IWindow.class);
|
||||||
|
final IBinder binder = mock(IBinder.class);
|
||||||
|
doReturn(binder).when(window).asBinder();
|
||||||
|
final WindowState windowState =
|
||||||
|
createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "appWin", window);
|
||||||
|
doNothing().when(mWm.mContext).enforceCallingOrSelfPermission(anyString(), anyString());
|
||||||
|
doReturn(windowState).when(mWm).getFocusedWindowLocked();
|
||||||
|
doReturn(windowState).when(mWm.mRoot).getCurrentInputMethodWindow();
|
||||||
|
|
||||||
|
TestResultReceiver receiver = new TestResultReceiver();
|
||||||
|
mWm.requestAppKeyboardShortcuts(receiver, 0);
|
||||||
|
mWm.requestImeKeyboardShortcuts(receiver, 0);
|
||||||
|
verify(window, times(2)).requestAppKeyboardShortcuts(receiver, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
class TestResultReceiver implements IResultReceiver {
|
||||||
|
public android.os.Bundle resultData;
|
||||||
|
private final IBinder mBinder = mock(IBinder.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void send(int resultCode, android.os.Bundle resultData)
|
||||||
|
throws android.os.RemoteException {
|
||||||
|
this.resultData = resultData;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public android.os.IBinder asBinder() {
|
||||||
|
return mBinder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void setupActivityWithLaunchCookie(IBinder launchCookie, WindowContainerToken wct) {
|
private void setupActivityWithLaunchCookie(IBinder launchCookie, WindowContainerToken wct) {
|
||||||
final WindowContainer.RemoteToken remoteToken = mock(WindowContainer.RemoteToken.class);
|
final WindowContainer.RemoteToken remoteToken = mock(WindowContainer.RemoteToken.class);
|
||||||
when(remoteToken.toWindowContainerToken()).thenReturn(wct);
|
when(remoteToken.toWindowContainerToken()).thenReturn(wct);
|
||||||
|
|||||||
Reference in New Issue
Block a user