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

Commit 95f657d8 authored by Kyrylo Mikos's avatar Kyrylo Mikos Committed by Luca Stefani
Browse files

Implement expanded desktop feature

Author: Kyrylo Mikos <kiril.mik.os@gmail.com>
Date:   Mon Nov 17 13:56:05 2014 +0200

    Bringup expanded desktop and implement per-user configuration.

    Change-Id: I90d834d788b3050a3f4c11dda9b6d1a7d79546cc

Author: Adnan Begovic <adnan@cyngn.com>
Date:   Wed Feb 4 01:00:06 2015 -0800

    Create configurable default expanded desktop style.

    Change-Id: I90c7f8544cda9b91fb9b700fcf146f4e58b15a26

Author: Adnan Begovic <adnan@cyngn.com>
Date:   Wed Jan 21 21:52:35 2015 -0800

    Remove unused POLICY_CONTROL_SELECTED. Unbreak public api.

Change-Id: Ib0900349115442274fb08eb172de2567a8b00295
parent d58cc2df
Loading
Loading
Loading
Loading
+10 −1
Original line number Original line Diff line number Diff line
@@ -11617,7 +11617,7 @@ public final class Settings {
        /**
        /**
         * Defines global runtime overrides to window policy.
         * 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
         * @hide
         */
         */
@@ -11640,6 +11640,15 @@ public final class Settings {
         */
         */
        public static final String BLOCKED_SLICES = "blocked_slices";
        public static final String BLOCKED_SLICES = "blocked_slices";
        /**
         * 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,
         * Defines global zen mode.  ZEN_MODE_OFF, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
         * or ZEN_MODE_NO_INTERRUPTIONS.
         * or ZEN_MODE_NO_INTERRUPTIONS.
+16 −0
Original line number Original line Diff line number Diff line
@@ -1707,6 +1707,22 @@ public interface WindowManager extends ViewManager {
         */
         */
        public static final int PRIVATE_FLAG_STATUS_BAR_EXPANDED = 0x00800000;
        public static final int PRIVATE_FLAG_STATUS_BAR_EXPANDED = 0x00800000;


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

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

        /**
         * 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 = 0x04000000;

        /**
        /**
         * Control flags that are private to the platform.
         * Control flags that are private to the platform.
         * @hide
         * @hide
+173 −20
Original line number Original line Diff line number Diff line
@@ -14,7 +14,7 @@
 * limitations under the License.
 * limitations under the License.
 */
 */


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


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


import com.android.server.policy.WindowManagerPolicy.WindowState;

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


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


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


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


    public static int getSystemUiVisibility(WindowState win, LayoutParams attrs) {
    /**
        attrs = attrs != null ? attrs : win.getAttrs();
     * Accessible constants for Settings
        int vis = win != null ? win.getSystemUiVisibility()
     */
                : (attrs.systemUiVisibility | attrs.subtreeSystemUiVisibility);
    public final static class ImmersiveDefaultStyles {
        if (sImmersiveStatusFilter != null && sImmersiveStatusFilter.matches(attrs)) {
        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(int vis, LayoutParams attrs) {
        if (sImmersiveStatusFilter != null && sImmersiveStatusFilter.matches(attrs)
                && (sDefaultImmersiveStyle == ImmersiveDefaultStyles.IMMERSIVE_FULL ||
                sDefaultImmersiveStyle == ImmersiveDefaultStyles.IMMERSIVE_STATUS))  {
            vis |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
            vis |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                    | View.SYSTEM_UI_FLAG_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
            vis &= ~(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
            vis &= ~(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    | View.STATUS_BAR_TRANSLUCENT);
                    | 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
            vis |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
@@ -84,28 +94,75 @@ public class PolicyControl {
        return vis;
        return vis;
    }
    }


    public static int getWindowFlags(WindowState win, LayoutParams attrs) {
    public static int getWindowFlags(int flags, LayoutParams attrs) {
        attrs = attrs != null ? attrs : win.getAttrs();
        if (sImmersiveStatusFilter != null && sImmersiveStatusFilter.matches(attrs)
        int flags = attrs.flags;
                && (sDefaultImmersiveStyle == ImmersiveDefaultStyles.IMMERSIVE_FULL ||
        if (sImmersiveStatusFilter != null && sImmersiveStatusFilter.matches(attrs)) {
                sDefaultImmersiveStyle == ImmersiveDefaultStyles.IMMERSIVE_STATUS)) {
            flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
            flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
            flags &= ~(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
            flags &= ~(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
                    | WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
                    | 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;
            flags &= ~WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;
        }
        }
        return flags;
        return flags;
    }
    }


    public static int adjustClearableFlags(WindowState win, int clearableFlags) {
    public static int getPrivateWindowFlags(int privateFlags, LayoutParams attrs) {
        final LayoutParams attrs = win != null ? win.getAttrs() : null;
        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 int adjustClearableFlags(LayoutParams attrs, int clearableFlags) {
        if (sImmersiveStatusFilter != null && sImmersiveStatusFilter.matches(attrs)) {
        if (sImmersiveStatusFilter != null && sImmersiveStatusFilter.matches(attrs)) {
            clearableFlags &= ~View.SYSTEM_UI_FLAG_FULLSCREEN;
            clearableFlags &= ~View.SYSTEM_UI_FLAG_FULLSCREEN;
        }
        }
        return clearableFlags;
        return clearableFlags;
    }
    }


    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 boolean disableImmersiveConfirmation(String pkg) {
    public static boolean disableImmersiveConfirmation(String pkg) {
        return (sImmersivePreconfirmationsFilter != null
        return (sImmersivePreconfirmationsFilter != null
                && sImmersivePreconfirmationsFilter.matches(pkg))
                && sImmersivePreconfirmationsFilter.matches(pkg))
@@ -113,7 +170,11 @@ public class PolicyControl {
    }
    }


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

        String value = null;
        String value = null;
        try {
        try {
            value = Settings.Global.getStringForUser(context.getContentResolver(),
            value = Settings.Global.getStringForUser(context.getContentResolver(),
@@ -127,6 +188,94 @@ public class PolicyControl {
        }
        }
    }
    }


    public static void saveToSettings(Context context) {
        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(),
                Settings.Global.POLICY_CONTROL, 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);
        }
    }

    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 void dump(String prefix, PrintWriter pw) {
    public static void dump(String prefix, PrintWriter pw) {
        dump("sImmersiveStatusFilter", sImmersiveStatusFilter, prefix, pw);
        dump("sImmersiveStatusFilter", sImmersiveStatusFilter, prefix, pw);
        dump("sImmersiveNavigationFilter", sImmersiveNavigationFilter, prefix, pw);
        dump("sImmersiveNavigationFilter", sImmersiveNavigationFilter, prefix, pw);
@@ -208,6 +357,10 @@ public class PolicyControl {
            return !onBlacklist(packageName) && onWhitelist(packageName);
            return !onBlacklist(packageName) && onWhitelist(packageName);
        }
        }


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

        private boolean onBlacklist(String packageName) {
        private boolean onBlacklist(String packageName) {
            return mBlacklist.contains(packageName) || mBlacklist.contains(ALL);
            return mBlacklist.contains(packageName) || mBlacklist.contains(ALL);
        }
        }
+4 −2
Original line number Original line Diff line number Diff line
@@ -28,6 +28,7 @@ import android.util.Slog;
import android.util.proto.ProtoOutputStream;
import android.util.proto.ProtoOutputStream;
import android.view.View;
import android.view.View;
import android.view.WindowManager;
import android.view.WindowManager;
import android.view.WindowManagerPolicyControl;


import com.android.server.LocalServices;
import com.android.server.LocalServices;
import com.android.server.policy.WindowManagerPolicy.WindowState;
import com.android.server.policy.WindowManagerPolicy.WindowState;
@@ -138,9 +139,10 @@ public class BarController {


    public int applyTranslucentFlagLw(WindowState win, int vis, int oldVis) {
    public int applyTranslucentFlagLw(WindowState win, int vis, int oldVis) {
        if (mWin != null) {
        if (mWin != null) {
            if (win != null && (win.getAttrs().privateFlags
            WindowManager.LayoutParams attrs = win != null ? win.getAttrs() : null;
            if (attrs != null && (attrs.privateFlags
                    & WindowManager.LayoutParams.PRIVATE_FLAG_INHERIT_TRANSLUCENT_DECOR) == 0) {
                    & WindowManager.LayoutParams.PRIVATE_FLAG_INHERIT_TRANSLUCENT_DECOR) == 0) {
                int fl = PolicyControl.getWindowFlags(win, null);
                int fl = WindowManagerPolicyControl.getWindowFlags(attrs.flags, attrs);
                if ((fl & mTranslucentWmFlag) != 0) {
                if ((fl & mTranslucentWmFlag) != 0) {
                    vis |= mTranslucentFlag;
                    vis |= mTranslucentFlag;
                } else {
                } else {
+2 −1
Original line number Original line Diff line number Diff line
@@ -48,6 +48,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.view.WindowManager;
import android.view.WindowManagerPolicyControl;
import android.view.animation.Animation;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.view.animation.Interpolator;
@@ -144,7 +145,7 @@ public class ImmersiveModeConfirmation {
            boolean userSetupComplete, boolean navBarEmpty) {
            boolean userSetupComplete, boolean navBarEmpty) {
        mHandler.removeMessages(H.SHOW);
        mHandler.removeMessages(H.SHOW);
        if (isImmersiveMode) {
        if (isImmersiveMode) {
            final boolean disabled = PolicyControl.disableImmersiveConfirmation(pkg);
            final boolean disabled = WindowManagerPolicyControl.disableImmersiveConfirmation(pkg);
            if (DEBUG) Slog.d(TAG, String.format("immersiveModeChanged() disabled=%s mConfirmed=%s",
            if (DEBUG) Slog.d(TAG, String.format("immersiveModeChanged() disabled=%s mConfirmed=%s",
                    disabled, mConfirmed));
                    disabled, mConfirmed));
            if (!disabled
            if (!disabled
Loading