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

Commit fceac76c authored by Tracy Zhou's avatar Tracy Zhou Committed by Android (Google) Code Review
Browse files

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

parents c435afa8 ccfab35b
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);