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

Commit 2d2def57 authored by Automerger Merge Worker's avatar Automerger Merge Worker
Browse files

Merge "Make SurfaceView rendering generic in SysUI" into rvc-dev am: fceac76c

Change-Id: I6b1c4e525996c249044a751f25ebf2a839b77b0e
parents 3593bd68 fceac76c
Loading
Loading
Loading
Loading
+71 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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.systemui.shared.system;

import android.content.Context;
import android.graphics.PixelFormat;
import android.os.Bundle;
import android.os.IBinder;
import android.view.SurfaceControl;
import android.view.SurfaceControlViewHost;
import android.view.View;
import android.view.WindowManager;
import android.view.WindowlessWindowManager;

/**
 * A generic receiver that specifically handles SurfaceView request created by {@link
 * com.android.systemui.shared.system.SurfaceViewRequestUtils}.
 */
public class SurfaceViewRequestReceiver {

    private final int mOpacity;
    private SurfaceControlViewHost mSurfaceControlViewHost;

    public SurfaceViewRequestReceiver() {
        this(PixelFormat.TRANSPARENT);
    }

    public SurfaceViewRequestReceiver(int opacity) {
        mOpacity = opacity;
    }

    /** Called whenever a surface view request is received. */
    public void onReceive(Context context, Bundle bundle, View view) {
        if (mSurfaceControlViewHost != null) {
            mSurfaceControlViewHost.die();
        }
        SurfaceControl surfaceControl = SurfaceViewRequestUtils.getSurfaceControl(bundle);
        if (surfaceControl != null) {
            IBinder hostToken = SurfaceViewRequestUtils.getHostToken(bundle);

            WindowlessWindowManager windowlessWindowManager =
                    new WindowlessWindowManager(context.getResources().getConfiguration(),
                            surfaceControl, hostToken);
            mSurfaceControlViewHost = new SurfaceControlViewHost(context,
                    context.getDisplayNoVerify(), windowlessWindowManager);
            WindowManager.LayoutParams layoutParams =
                    new WindowManager.LayoutParams(
                            surfaceControl.getWidth(),
                            surfaceControl.getHeight(),
                            WindowManager.LayoutParams.TYPE_APPLICATION,
                            0,
                            mOpacity);

            mSurfaceControlViewHost.addView(view, layoutParams);
        }
    }
}
+55 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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.systemui.shared.system;

import android.annotation.Nullable;
import android.os.Bundle;
import android.os.IBinder;
import android.view.SurfaceControl;
import android.view.SurfaceView;

/** Util class that wraps a SurfaceView request into a bundle. */
public class SurfaceViewRequestUtils {
    private static final String KEY_HOST_TOKEN = "host_token";
    private static final String KEY_SURFACE_CONTROL = "surface_control";

    /** Creates a SurfaceView based bundle that stores the input host token and surface control. */
    public static Bundle createSurfaceBundle(SurfaceView surfaceView) {
        Bundle bundle = new Bundle();
        bundle.putBinder(KEY_HOST_TOKEN, surfaceView.getHostToken());
        bundle.putParcelable(KEY_SURFACE_CONTROL, surfaceView.getSurfaceControl());
        return bundle;
    }

    /**
     * Retrieves the SurfaceControl from an Intent created by
     * {@link #createSurfaceBundle(SurfaceView)}.
     **/
    public static SurfaceControl getSurfaceControl(Bundle bundle) {
        return bundle.getParcelable(KEY_SURFACE_CONTROL);
    }

    /**
     * Retrieves the input token from an Intent created by
     * {@link #createSurfaceBundle(SurfaceView)}.
     **/
    public static @Nullable IBinder getHostToken(Bundle bundle) {
        return bundle.getBinder(KEY_HOST_TOKEN);
    }

    private SurfaceViewRequestUtils() {}
}
+3 −26
Original line number Diff line number Diff line
@@ -18,50 +18,27 @@ package com.android.systemui.shared.system;

import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
import android.view.SurfaceControl;
import android.view.SurfaceView;

/** Utility class that is shared between SysUI and Launcher for Universal Smartspace features. */
public final class UniversalSmartspaceUtils {
    public static final String ACTION_REQUEST_SMARTSPACE_VIEW =
            "com.android.systemui.REQUEST_SMARTSPACE_VIEW";
    public static final String INTENT_BUNDLE_KEY = "bundle_key";

    private static final String SYSUI_PACKAGE = "com.android.systemui";
    private static final String INTENT_KEY_INPUT_BUNDLE = "input_bundle";
    private static final String BUNDLE_KEY_INPUT_TOKEN = "input_token";
    private static final String INTENT_KEY_SURFACE_CONTROL = "surface_control";

    /** Creates an intent to request that sysui draws the Smartspace to the SurfaceView. */
    public static Intent createRequestSmartspaceIntent(SurfaceView surfaceView) {
        Intent intent = new Intent(ACTION_REQUEST_SMARTSPACE_VIEW);

        Bundle inputBundle = new Bundle();
        inputBundle.putBinder(BUNDLE_KEY_INPUT_TOKEN, surfaceView.getHostToken());
        Bundle bundle = SurfaceViewRequestUtils.createSurfaceBundle(surfaceView);
        return intent
                .putExtra(INTENT_KEY_SURFACE_CONTROL, surfaceView.getSurfaceControl())
                .putExtra(INTENT_KEY_INPUT_BUNDLE, inputBundle)
                .putExtra(INTENT_BUNDLE_KEY, bundle)
                .setPackage(SYSUI_PACKAGE)
                .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
                        | Intent.FLAG_RECEIVER_FOREGROUND);
    }

    /**
     * Retrieves the SurfaceControl from an Intent created by
     * {@link #createRequestSmartspaceIntent(SurfaceView)}.
     **/
    public static SurfaceControl getSurfaceControl(Intent intent) {
        return intent.getParcelableExtra(INTENT_KEY_SURFACE_CONTROL);
    }

    /**
     * Retrieves the input token from an Intent created by
     * {@link #createRequestSmartspaceIntent(SurfaceView)}.
     **/
    public static IBinder getInputToken(Intent intent) {
        Bundle inputBundle = intent.getBundleExtra(INTENT_KEY_INPUT_BUNDLE);
        return inputBundle == null ? null : inputBundle.getBinder(BUNDLE_KEY_INPUT_TOKEN);
    }

    private UniversalSmartspaceUtils() {}
}
+9 −32
Original line number Diff line number Diff line
@@ -24,9 +24,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.UserHandle;
import android.text.TextUtils;
@@ -35,11 +33,7 @@ import android.util.AttributeSet;
import android.util.Log;
import android.util.Slog;
import android.util.TypedValue;
import android.view.SurfaceControl;
import android.view.SurfaceControlViewHost;
import android.view.View;
import android.view.WindowManager;
import android.view.WindowlessWindowManager;
import android.widget.GridLayout;
import android.widget.LinearLayout;
import android.widget.TextView;
@@ -49,6 +43,7 @@ import androidx.core.graphics.ColorUtils;
import com.android.internal.widget.LockPatternUtils;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.shared.system.SurfaceViewRequestReceiver;
import com.android.systemui.shared.system.UniversalSmartspaceUtils;
import com.android.systemui.statusbar.policy.ConfigurationController;

@@ -86,7 +81,6 @@ public class KeyguardStatusView extends GridLayout implements
    private int mIconTopMargin;
    private int mIconTopMarginWithHeader;
    private boolean mShowingHeader;
    private SurfaceControlViewHost mUniversalSmartspaceViewHost;

    private KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {

@@ -133,37 +127,20 @@ public class KeyguardStatusView extends GridLayout implements
        }
    };

    private BroadcastReceiver mUniversalSmartspaceBroadcastReceiver = new BroadcastReceiver() {
    private final BroadcastReceiver mUniversalSmartspaceBroadcastReceiver =
            new BroadcastReceiver() {
        private final SurfaceViewRequestReceiver mReceiver = new SurfaceViewRequestReceiver();

        @Override
        public void onReceive(Context context, Intent i) {
            // TODO(b/148159743): Restrict to Pixel Launcher.
            if (UniversalSmartspaceUtils.ACTION_REQUEST_SMARTSPACE_VIEW.equals(i.getAction())) {
                if (mUniversalSmartspaceViewHost != null) {
                    mUniversalSmartspaceViewHost.die();
                }
                SurfaceControl surfaceControl = UniversalSmartspaceUtils.getSurfaceControl(i);
                if (surfaceControl != null) {
                    IBinder input = UniversalSmartspaceUtils.getInputToken(i);

                    WindowlessWindowManager windowlessWindowManager =
                            new WindowlessWindowManager(context.getResources().getConfiguration(),
                                    surfaceControl, input);
                    mUniversalSmartspaceViewHost = new SurfaceControlViewHost(context,
                            context.getDisplayNoVerify(), windowlessWindowManager);
                    WindowManager.LayoutParams layoutParams =
                            new WindowManager.LayoutParams(
                                    surfaceControl.getWidth(),
                                    surfaceControl.getHeight(),
                                    WindowManager.LayoutParams.TYPE_APPLICATION,
                                    0,
                                    PixelFormat.TRANSPARENT);

                    mUniversalSmartspaceViewHost.addView(
                            inflate(context, R.layout.keyguard_status_area, null), layoutParams);
                }
                mReceiver.onReceive(context,
                        i.getBundleExtra(UniversalSmartspaceUtils.INTENT_BUNDLE_KEY),
                        inflate(mContext, R.layout.keyguard_status_area, null));
            }
        }
    };;
    };

    public KeyguardStatusView(Context context) {
        this(context, null, 0);