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

Commit 2bb09a09 authored by Kyrylo Mikos's avatar Kyrylo Mikos Committed by Michael Bestas
Browse files

Implement expanded desktop feature

This squashes the following commits:

Bringup expanded desktop and implement per-user configuration.

Change-Id: I90d834d788b3050a3f4c11dda9b6d1a7d79546cc

Create configurable default expanded desktop style.

Change-Id: I90c7f8544cda9b91fb9b700fcf146f4e58b15a26

Remove unused POLICY_CONTROL_SELECTED. Unbreak public api.

Change-Id: Ib0900349115442274fb08eb172de2567a8b00295
parent d801d231
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -9995,12 +9995,21 @@ public final class Settings {
        /**
         * Defines global runtime overrides to window policy.
         *
         * See {@link com.android.server.policy.PolicyControl} for value format.
         * See {@link android.view.WindowManagerPolicyControl} for value format.
         *
         * @hide
         */
        public static final String POLICY_CONTROL = "policy_control";

        /**
         * Defines global runtime overrides to window policy style.
         *
         * See {@link android.view.WindowManagerPolicyControl} for value definitions.
         *
         * @hide
         */
        public static final String POLICY_CONTROL_STYLE = "policy_control_style";

        /**
         * Defines global zen mode.  ZEN_MODE_OFF, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
         * or ZEN_MODE_NO_INTERRUPTIONS.
+16 −0
Original line number Diff line number Diff line
@@ -1433,6 +1433,22 @@ public interface WindowManager extends ViewManager {
        @RequiresPermission(permission.DEVICE_POWER)
        public static final int PRIVATE_FLAG_ACQUIRES_SLEEP_TOKEN = 0x00200000;

        /**
         * @hide
         */
        public static final int PRIVATE_FLAG_STATUS_HIDE_FORCED = 0x00800000;

        /**
         * @hide
         */
        public static final int PRIVATE_FLAG_NAV_HIDE_FORCED = 0x01000000;

        /**
         * The window had not set FULLSCREEN flag so don't handle it as fullscreen in layoutWindowLw
         * @hide
         */
        public static final int PRIVATE_FLAG_WAS_NOT_FULLSCREEN = 0x02000000;

        /**
         * Window flag: Overrides default power key behavior
         * @hide
+2 −0
Original line number Diff line number Diff line
@@ -622,6 +622,8 @@ public interface WindowManagerPolicy {
         * @param listener callback to call when display can be turned off
         */
        void screenTurningOff(ScreenOffListener listener);

        void addSystemUIVisibilityFlag(int flags);
    }

    public interface PointerEventListener {
+202 −9
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@
 * limitations under the License.
 */

package com.android.server.policy;
package android.view;

import android.app.ActivityManager;
import android.content.Context;
@@ -22,13 +22,12 @@ import android.os.UserHandle;
import android.provider.Settings;
import android.util.ArraySet;
import android.util.Slog;
import android.view.View;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.view.WindowManagerPolicy.WindowState;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Iterator;

/**
 * Runtime adjustments applied to the global window policy.
@@ -47,8 +46,10 @@ import java.io.StringWriter;
 *
 * Separate multiple name-value pairs with ':'
 *   e.g. "immersive.status=apps:immersive.preconfirms=*"
 *
 *   @hide
 */
public class PolicyControl {
public class WindowManagerPolicyControl {
    private static String TAG = "PolicyControl";
    private static boolean DEBUG = false;

@@ -57,22 +58,36 @@ public class PolicyControl {
    private static final String NAME_IMMERSIVE_NAVIGATION = "immersive.navigation";
    private static final String NAME_IMMERSIVE_PRECONFIRMATIONS = "immersive.preconfirms";

    private static int sDefaultImmersiveStyle;
    private static String sSettingValue;
    private static Filter sImmersivePreconfirmationsFilter;
    private static Filter sImmersiveStatusFilter;
    private static Filter sImmersiveNavigationFilter;

    /**
     * Accessible constants for Settings
     */
    public final static class ImmersiveDefaultStyles {
        public final static int IMMERSIVE_FULL = 0;
        public final static int IMMERSIVE_STATUS = 1;
        public final static int IMMERSIVE_NAVIGATION = 2;
    }

    public static int getSystemUiVisibility(WindowState win, LayoutParams attrs) {
        attrs = attrs != null ? attrs : win.getAttrs();
        int vis = win != null ? win.getSystemUiVisibility() : attrs.systemUiVisibility;
        if (sImmersiveStatusFilter != null && sImmersiveStatusFilter.matches(attrs)) {
        if (sImmersiveStatusFilter != null && sImmersiveStatusFilter.matches(attrs)
                && (sDefaultImmersiveStyle == ImmersiveDefaultStyles.IMMERSIVE_FULL ||
                sDefaultImmersiveStyle == ImmersiveDefaultStyles.IMMERSIVE_STATUS))  {
            vis |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                    | View.SYSTEM_UI_FLAG_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
            vis &= ~(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    | View.STATUS_BAR_TRANSLUCENT);
        }
        if (sImmersiveNavigationFilter != null && sImmersiveNavigationFilter.matches(attrs)) {
        if (sImmersiveNavigationFilter != null && sImmersiveNavigationFilter.matches(attrs)
                && (sDefaultImmersiveStyle == ImmersiveDefaultStyles.IMMERSIVE_FULL ||
                sDefaultImmersiveStyle == ImmersiveDefaultStyles.IMMERSIVE_NAVIGATION)) {
            vis |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
@@ -85,17 +100,71 @@ public class PolicyControl {
    public static int getWindowFlags(WindowState win, LayoutParams attrs) {
        attrs = attrs != null ? attrs : win.getAttrs();
        int flags = attrs.flags;
        if (sImmersiveStatusFilter != null && sImmersiveStatusFilter.matches(attrs)) {

        if (sImmersiveStatusFilter != null && sImmersiveStatusFilter.matches(attrs)
                && (sDefaultImmersiveStyle == ImmersiveDefaultStyles.IMMERSIVE_FULL ||
                sDefaultImmersiveStyle == ImmersiveDefaultStyles.IMMERSIVE_STATUS)) {
            flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
            flags &= ~(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
                    | WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
        }
        if (sImmersiveNavigationFilter != null && sImmersiveNavigationFilter.matches(attrs)) {
        if (sImmersiveNavigationFilter != null && sImmersiveNavigationFilter.matches(attrs)
                && (sDefaultImmersiveStyle == ImmersiveDefaultStyles.IMMERSIVE_FULL ||
                sDefaultImmersiveStyle == ImmersiveDefaultStyles.IMMERSIVE_NAVIGATION)) {
            flags &= ~WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;
        }
        return flags;
    }

    public static int getPrivateWindowFlags(WindowState win, LayoutParams attrs) {
        attrs = attrs != null ? attrs : win.getAttrs();
        int privateFlags = attrs.privateFlags;

        if (sImmersiveStatusFilter != null && sImmersiveNavigationFilter != null &&
                sImmersiveStatusFilter.isEnabledForAll()
                && sImmersiveNavigationFilter.isEnabledForAll()) {

            if ((attrs.flags & LayoutParams.FLAG_FULLSCREEN) == 0) {
                privateFlags |= LayoutParams.PRIVATE_FLAG_WAS_NOT_FULLSCREEN;
            }

            switch (sDefaultImmersiveStyle) {
                case ImmersiveDefaultStyles.IMMERSIVE_FULL:
                    privateFlags |= LayoutParams.PRIVATE_FLAG_NAV_HIDE_FORCED;
                    privateFlags |= LayoutParams.PRIVATE_FLAG_STATUS_HIDE_FORCED;
                    return privateFlags;
                case ImmersiveDefaultStyles.IMMERSIVE_STATUS:
                    privateFlags |= LayoutParams.PRIVATE_FLAG_STATUS_HIDE_FORCED;
                    return privateFlags;
                case ImmersiveDefaultStyles.IMMERSIVE_NAVIGATION:
                    privateFlags |= LayoutParams.PRIVATE_FLAG_NAV_HIDE_FORCED;
                    return privateFlags;
                }
        }

        if (sImmersiveStatusFilter != null && sImmersiveStatusFilter.matches(attrs)) {
            if ((attrs.flags & LayoutParams.FLAG_FULLSCREEN) == 0) {
                privateFlags |= LayoutParams.PRIVATE_FLAG_WAS_NOT_FULLSCREEN;
            }
            privateFlags |= LayoutParams.PRIVATE_FLAG_STATUS_HIDE_FORCED;
        }

        if (sImmersiveNavigationFilter != null && sImmersiveNavigationFilter.matches(attrs)) {
            privateFlags |= LayoutParams.PRIVATE_FLAG_NAV_HIDE_FORCED;
        }

        return privateFlags;
    }

    public static boolean immersiveStatusFilterMatches(String packageName) {
        return sImmersiveStatusFilter != null && sImmersiveStatusFilter.matches(packageName);
    }

    public static boolean immersiveNavigationFilterMatches(String packageName) {
        return sImmersiveNavigationFilter != null
                && sImmersiveNavigationFilter.matches(packageName);
    }

    public static int adjustClearableFlags(WindowState win, int clearableFlags) {
        final LayoutParams attrs = win != null ? win.getAttrs() : null;
        if (sImmersiveStatusFilter != null && sImmersiveStatusFilter.matches(attrs)) {
@@ -111,11 +180,16 @@ public class PolicyControl {
    }

    public static void reloadFromSetting(Context context) {
        reloadStyleFromSetting(context, Settings.Global.POLICY_CONTROL_STYLE);
        reloadFromSetting(context, Settings.Global.POLICY_CONTROL);
    }

    public static void reloadFromSetting(Context context, String key) {
        if (DEBUG) Slog.d(TAG, "reloadFromSetting()");
        String value = null;
        try {
            value = Settings.Global.getStringForUser(context.getContentResolver(),
                    Settings.Global.POLICY_CONTROL,
                    key,
                    UserHandle.USER_CURRENT);
            if (sSettingValue != null && sSettingValue.equals(value)) return;
            setFilters(value);
@@ -125,6 +199,121 @@ public class PolicyControl {
        }
    }

    public static void reloadStyleFromSetting(Context context, String key) {
        sDefaultImmersiveStyle = Settings.Global.getInt(context.getContentResolver(),
                key, WindowManagerPolicyControl.ImmersiveDefaultStyles.IMMERSIVE_FULL);
        if (DEBUG) Slog.d(TAG, "reloadStyleFromSetting " + sDefaultImmersiveStyle);
    }

    public static void saveToSettings(Context context) {
        saveToSettings(context, Settings.Global.POLICY_CONTROL);
    }

    public static void saveToSettings(Context context, String key) {
        StringBuilder value = new StringBuilder();
        boolean needSemicolon = false;
        if (sImmersiveStatusFilter != null) {
            writeFilter(NAME_IMMERSIVE_STATUS, sImmersiveStatusFilter, value);
            needSemicolon = true;
        }
        if (sImmersiveNavigationFilter != null) {
            if (needSemicolon) {
                value.append(":");
            }
            writeFilter(NAME_IMMERSIVE_NAVIGATION, sImmersiveNavigationFilter, value);
        }

        Settings.Global.putString(context.getContentResolver(), key, value.toString());
    }

    public static void saveStyleToSettings(Context context, int value) {
        Settings.Global.putInt(context.getContentResolver(),
                Settings.Global.POLICY_CONTROL_STYLE, value);
        sDefaultImmersiveStyle = value;
    }

    public static void addToStatusWhiteList(String packageName) {
        if (sImmersiveStatusFilter == null) {
            sImmersiveStatusFilter = new Filter(new ArraySet<String>(), new ArraySet<String>());
        }

        if (!sImmersiveStatusFilter.mWhitelist.contains(packageName)) {
            sImmersiveStatusFilter.mWhitelist.add(packageName);
        }
    }

    public static void addToNavigationWhiteList(String packageName) {
        if (sImmersiveNavigationFilter == null) {
            sImmersiveNavigationFilter = new Filter(new ArraySet<String>(), new ArraySet<String>());
        }

        if (!sImmersiveNavigationFilter.mWhitelist.contains(packageName)) {
            sImmersiveNavigationFilter.mWhitelist.add(packageName);
        }
    }

    public static void removeFromWhiteLists(String packageName) {
        if (sImmersiveStatusFilter != null) {
            sImmersiveStatusFilter.mWhitelist.remove(packageName);
        }
        if (sImmersiveNavigationFilter != null) {
            sImmersiveNavigationFilter.mWhitelist.remove(packageName);
        }
    }

    public static ArraySet<String> getWhiteLists() {
        ArraySet<String> result = new ArraySet<>();

        if (sImmersiveStatusFilter != null) {
            result.addAll(sImmersiveStatusFilter.mWhitelist);
        }
        if (sImmersiveNavigationFilter != null
                && sImmersiveNavigationFilter != sImmersiveStatusFilter) {
            result.addAll(sImmersiveNavigationFilter.mWhitelist);
        }

        return result;
    }

    private static void writeFilter(String name, Filter filter, StringBuilder stringBuilder) {
        if (filter.mWhitelist.isEmpty() && filter.mBlacklist.isEmpty()) {
            return;
        }
        stringBuilder.append(name);
        stringBuilder.append("=");

        boolean needComma = false;
        if (!filter.mWhitelist.isEmpty()) {
            writePackages(filter.mWhitelist, stringBuilder, false);
            needComma = true;
        }
        if (!filter.mBlacklist.isEmpty()) {
            if (needComma) {
                stringBuilder.append(",");
            }
            writePackages(filter.mBlacklist, stringBuilder, true);
        }
    }

    private static void writePackages(ArraySet<String> set, StringBuilder stringBuilder,
                                      boolean isBlackList) {
        Iterator<String> iterator = set.iterator();
        while (iterator.hasNext()) {
            if (isBlackList) {
                stringBuilder.append("-");
            }
            String name = iterator.next();
            stringBuilder.append(name);
            if (iterator.hasNext()) {
                stringBuilder.append(",");
            }
        }
    }

    public static boolean isImmersiveFiltersActive() {
        return sImmersiveStatusFilter != null || sImmersiveNavigationFilter != null;
    }

    public static void dump(String prefix, PrintWriter pw) {
        dump("sImmersiveStatusFilter", sImmersiveStatusFilter, prefix, pw);
        dump("sImmersiveNavigationFilter", sImmersiveNavigationFilter, prefix, pw);
@@ -206,6 +395,10 @@ public class PolicyControl {
            return !onBlacklist(packageName) && onWhitelist(packageName);
        }

        public boolean isEnabledForAll() {
            return mWhitelist.contains(ALL);
        }

        private boolean onBlacklist(String packageName) {
            return mBlacklist.contains(packageName) || mBlacklist.contains(ALL);
        }
+2 −1
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.WindowManagerPolicy.WindowState;
import android.view.WindowManagerPolicyControl;

import com.android.server.LocalServices;
import com.android.server.statusbar.StatusBarManagerInternal;
@@ -126,7 +127,7 @@ public class BarController {
        if (mWin != null) {
            if (win != null && (win.getAttrs().privateFlags
                    & WindowManager.LayoutParams.PRIVATE_FLAG_INHERIT_TRANSLUCENT_DECOR) == 0) {
                int fl = PolicyControl.getWindowFlags(win, null);
                int fl = WindowManagerPolicyControl.getWindowFlags(win, null);
                if ((fl & mTranslucentWmFlag) != 0) {
                    vis |= mTranslucentFlag;
                } else {
Loading