blob: 84e9d185400d615722aa6d6c33f31bedba2f6a60 [file] [log] [blame]
/*
* Copyright (C) 2021 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 android.view.inputmethod.cts.util;
import static android.hardware.display.DisplayManager.DISPLAY_CATEGORY_PRESENTATION;
import static android.provider.Settings.Global.OVERLAY_DISPLAY_DEVICES;
import static android.view.Display.FLAG_TRUSTED;
import static com.android.compatibility.common.util.SystemUtil.runShellCommand;
import android.content.Context;
import android.hardware.display.DisplayManager;
import android.util.Size;
import android.view.Display;
import android.view.WindowManager;
import androidx.annotation.NonNull;
import com.android.compatibility.common.util.CommonTestUtils;
import com.android.compatibility.common.util.SystemUtil;
import java.util.StringJoiner;
import java.util.concurrent.atomic.AtomicReference;
/**
* A session to create/close the simulated overlay display for testing multi-display behavior.
*/
public final class SimulatedVirtualDisplaySession implements AutoCloseable {
private static final String OVERLAY_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS =
"should_show_system_decorations";
private final Display mDisplay;
private SimulatedVirtualDisplaySession(@NonNull Display display) {
mDisplay = display;
}
public static SimulatedVirtualDisplaySession create(@NonNull Context context,
int width, int height, int density, int displayImePolicy) {
final String displaySettingsStr = new StringJoiner(",")
// Display size/density configuration
.add(new Size(width, height) + "/" + density)
// Support system decoration to show IME on the simulated display by default
.add(OVERLAY_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS)
.toString();
putGlobalSetting(OVERLAY_DISPLAY_DEVICES, displaySettingsStr);
final DisplayManager dm = context.getSystemService(DisplayManager.class);
final WindowManager wm = context.getSystemService(WindowManager.class);
AtomicReference<Display> simulatedDisplay = new AtomicReference();
try {
CommonTestUtils.waitUntil("No simulated display found", 5,
() -> {
final Display[] displays = dm.getDisplays(DISPLAY_CATEGORY_PRESENTATION);
for (Display display : displays) {
final boolean isTrusted =
(display.getFlags() & FLAG_TRUSTED) == FLAG_TRUSTED;
if (isTrusted && display.getType() == Display.TYPE_OVERLAY) {
SystemUtil.runWithShellPermissionIdentity(() -> {
wm.setDisplayImePolicy(display.getDisplayId(),
displayImePolicy);
simulatedDisplay.set(display);
});
return true;
}
}
return false;
});
} catch (AssertionError | Exception e) {
deleteGlobalSetting(OVERLAY_DISPLAY_DEVICES);
throw new RuntimeException("Exception!", e);
}
return new SimulatedVirtualDisplaySession(simulatedDisplay.get());
}
private static void putGlobalSetting(String key, String value) {
runShellCommand("settings put global " + key + " " + value);
}
private static void deleteGlobalSetting(String key) {
runShellCommand("settings delete global " + key);
}
public int getDisplayId() {
return mDisplay.getDisplayId();
}
@Override
public void close() throws Exception {
deleteGlobalSetting(OVERLAY_DISPLAY_DEVICES);
}
}