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

Commit 9a7c0d61 authored by Massimo Carli's avatar Massimo Carli Committed by Android (Google) Code Review
Browse files

Merge "[1/n] Create Configuration for CompatUX Enhancements" into tm-qpr-dev

parents a6c8c2af 75845880
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -115,4 +115,10 @@
    <!-- Components support to launch multiple instances into split-screen -->
    <string-array name="config_appsSupportMultiInstancesSplit">
    </string-array>

    <!-- Whether the extended restart dialog is enabled -->
    <bool name="config_letterboxIsRestartDialogEnabled">false</bool>

    <!-- Whether the additional education about reachability is enabled -->
    <bool name="config_letterboxIsReachabilityEducationEnabled">false</bool>
</resources>
+119 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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.wm.shell.compatui;

import android.content.Context;
import android.provider.DeviceConfig;

import androidx.annotation.NonNull;

import com.android.wm.shell.R;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.annotations.ShellMainThread;
import com.android.wm.shell.dagger.WMSingleton;

import javax.inject.Inject;

/**
 * Configuration flags for the CompatUX implementation
 */
@WMSingleton
public class CompatUIConfiguration implements DeviceConfig.OnPropertiesChangedListener {

    static final String KEY_ENABLE_LETTERBOX_RESTART_DIALOG = "enable_letterbox_restart_dialog";

    static final String KEY_ENABLE_LETTERBOX_REACHABILITY_EDUCATION =
            "enable_letterbox_reachability_education";

    // Whether the extended restart dialog is enabled
    private boolean mIsRestartDialogEnabled;

    // Whether the additional education about reachability is enabled
    private boolean mIsReachabilityEducationEnabled;

    // Whether the extended restart dialog is enabled
    private boolean mIsRestartDialogOverrideEnabled;

    // Whether the additional education about reachability is enabled
    private boolean mIsReachabilityEducationOverrideEnabled;

    // Whether the extended restart dialog is allowed from backend
    private boolean mIsLetterboxRestartDialogAllowed;

    // Whether the additional education about reachability is allowed from backend
    private boolean mIsLetterboxReachabilityEducationAllowed;

    @Inject
    public CompatUIConfiguration(Context context, @ShellMainThread ShellExecutor mainExecutor) {
        mIsRestartDialogEnabled = context.getResources().getBoolean(
                R.bool.config_letterboxIsRestartDialogEnabled);
        mIsReachabilityEducationEnabled = context.getResources().getBoolean(
                R.bool.config_letterboxIsReachabilityEducationEnabled);
        mIsLetterboxRestartDialogAllowed = DeviceConfig.getBoolean(
                DeviceConfig.NAMESPACE_WINDOW_MANAGER, KEY_ENABLE_LETTERBOX_RESTART_DIALOG, false);
        mIsLetterboxReachabilityEducationAllowed = DeviceConfig.getBoolean(
                DeviceConfig.NAMESPACE_WINDOW_MANAGER, KEY_ENABLE_LETTERBOX_REACHABILITY_EDUCATION,
                false);
        DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_APP_COMPAT, mainExecutor,
                this);
    }

    /**
     * @return {@value true} if the restart dialog is enabled.
     */
    boolean isRestartDialogEnabled() {
        return mIsRestartDialogOverrideEnabled || (mIsRestartDialogEnabled
                && mIsLetterboxRestartDialogAllowed);
    }

    /**
     * Enables/Disables the restart education dialog
     */
    void setIsRestartDialogOverrideEnabled(boolean enabled) {
        mIsRestartDialogOverrideEnabled = enabled;
    }

    /**
     * @return {@value true} if the reachability education is enabled.
     */
    boolean isReachabilityEducationEnabled() {
        return mIsReachabilityEducationOverrideEnabled || (mIsReachabilityEducationEnabled
                && mIsLetterboxReachabilityEducationAllowed);
    }

    /**
     * Enables/Disables the reachability education
     */
    void setIsReachabilityEducationOverrideEnabled(boolean enabled) {
        mIsReachabilityEducationOverrideEnabled = enabled;
    }

    @Override
    public void onPropertiesChanged(@NonNull DeviceConfig.Properties properties) {
        // TODO(b/263349751): Update flag and default value to true
        if (properties.getKeyset().contains(KEY_ENABLE_LETTERBOX_RESTART_DIALOG)) {
            mIsLetterboxRestartDialogAllowed = DeviceConfig.getBoolean(
                    DeviceConfig.NAMESPACE_WINDOW_MANAGER, KEY_ENABLE_LETTERBOX_RESTART_DIALOG,
                    false);
        }
        if (properties.getKeyset().contains(KEY_ENABLE_LETTERBOX_REACHABILITY_EDUCATION)) {
            mIsLetterboxReachabilityEducationAllowed = DeviceConfig.getBoolean(
                    DeviceConfig.NAMESPACE_WINDOW_MANAGER,
                    KEY_ENABLE_LETTERBOX_REACHABILITY_EDUCATION, false);
        }
    }
}
+103 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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.wm.shell.compatui;

import com.android.wm.shell.dagger.WMSingleton;
import com.android.wm.shell.sysui.ShellCommandHandler;

import java.io.PrintWriter;
import java.util.function.Consumer;

import javax.inject.Inject;

/**
 * Handles the shell commands for the CompatUX.
 *
 * <p> Use with {@code adb shell dumpsys activity service SystemUIService WMShell compatui
 * &lt;command&gt;}.
 */
@WMSingleton
public final class CompatUIShellCommandHandler implements
        ShellCommandHandler.ShellCommandActionHandler {

    private final CompatUIConfiguration mCompatUIConfiguration;
    private final ShellCommandHandler mShellCommandHandler;

    @Inject
    public CompatUIShellCommandHandler(ShellCommandHandler shellCommandHandler,
            CompatUIConfiguration compatUIConfiguration) {
        mShellCommandHandler = shellCommandHandler;
        mCompatUIConfiguration = compatUIConfiguration;
    }

    void onInit() {
        mShellCommandHandler.addCommandCallback("compatui", this, this);
    }

    @Override
    public boolean onShellCommand(String[] args, PrintWriter pw) {
        if (args.length != 2) {
            pw.println("Invalid command: " + args[0]);
            return false;
        }
        switch (args[0]) {
            case "restartDialogEnabled":
                return invokeOrError(args[1], pw,
                        mCompatUIConfiguration::setIsRestartDialogOverrideEnabled);
            case "reachabilityEducationEnabled":
                return invokeOrError(args[1], pw,
                        mCompatUIConfiguration::setIsReachabilityEducationOverrideEnabled);
            default:
                pw.println("Invalid command: " + args[0]);
                return false;
        }
    }

    @Override
    public void printShellCommandHelp(PrintWriter pw, String prefix) {
        pw.println(prefix + "restartDialogEnabled [0|false|1|true]");
        pw.println(prefix + "  Enable/Disable the restart education dialog for Size Compat Mode");
        pw.println(prefix + "reachabilityEducationEnabled [0|false|1|true]");
        pw.println(prefix
                + "  Enable/Disable the restart education dialog for letterbox reachability");
        pw.println(prefix + "  Disable the restart education dialog for letterbox reachability");
    }

    private static boolean invokeOrError(String input, PrintWriter pw,
            Consumer<Boolean> setter) {
        Boolean asBoolean = strToBoolean(input);
        if (asBoolean == null) {
            pw.println("Error: expected true, 1, false, 0.");
            return false;
        }
        setter.accept(asBoolean);
        return true;
    }

    // Converts a String to boolean if possible or it returns null otherwise
    private static Boolean strToBoolean(String str) {
        switch(str) {
            case "1":
            case "true":
                return true;
            case "0":
            case "false":
                return false;
        }
        return null;
    }
}