Merge "Switch to public API for surface view when rendering preview" into ub-launcher3-master
diff --git a/quickstep/src/com/android/launcher3/uioverrides/PreviewSurfaceRenderer.java b/quickstep/src/com/android/launcher3/uioverrides/PreviewSurfaceRenderer.java
deleted file mode 100644
index c7cce0b..0000000
--- a/quickstep/src/com/android/launcher3/uioverrides/PreviewSurfaceRenderer.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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.launcher3.uioverrides;
-
-import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
-
-import android.content.Context;
-import android.os.Bundle;
-import android.util.Size;
-import android.view.View;
-
-import com.android.launcher3.InvariantDeviceProfile;
-import com.android.launcher3.graphics.LauncherPreviewRenderer;
-import com.android.systemui.shared.system.SurfaceViewRequestReceiver;
-
-/** Render preview using surface view. */
-public class PreviewSurfaceRenderer {
-
- /** Handle a received surface view request. */
- public static void render(Context context, Bundle bundle) {
- String gridName = bundle.getString("name");
- bundle.remove("name");
- if (gridName == null) {
- gridName = InvariantDeviceProfile.getCurrentGridName(context);
- }
- final InvariantDeviceProfile idp = new InvariantDeviceProfile(context, gridName);
-
- MAIN_EXECUTOR.execute(() -> {
- View view = new LauncherPreviewRenderer(context, idp).getRenderedView();
- new SurfaceViewRequestReceiver().onReceive(context, bundle, view,
- new Size(view.getMeasuredWidth(), view.getMeasuredHeight()));
- });
- }
-}
diff --git a/src/com/android/launcher3/graphics/GridOptionsProvider.java b/src/com/android/launcher3/graphics/GridOptionsProvider.java
index 607aba9..af974f8 100644
--- a/src/com/android/launcher3/graphics/GridOptionsProvider.java
+++ b/src/com/android/launcher3/graphics/GridOptionsProvider.java
@@ -20,7 +20,6 @@
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.InvariantDeviceProfile.GridOption;
import com.android.launcher3.R;
-import com.android.launcher3.uioverrides.PreviewSurfaceRenderer;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -201,12 +200,11 @@
}
@Override
- public Bundle call(String method, String arg, Bundle extras) {
+ public Bundle call(String method, String arg, Bundle extras) {
if (!METHOD_GET_PREVIEW.equals(method)) {
return null;
}
- PreviewSurfaceRenderer.render(getContext(), extras);
- return null;
+ return new PreviewSurfaceRenderer(getContext(), extras).render();
}
}
diff --git a/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java b/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
new file mode 100644
index 0000000..20eec9a
--- /dev/null
+++ b/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
@@ -0,0 +1,128 @@
+/*
+ * 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.launcher3.graphics;
+
+import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+
+import android.content.Context;
+import android.hardware.display.DisplayManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Messenger;
+import android.view.Display;
+import android.view.SurfaceControlViewHost;
+import android.view.View;
+
+import com.android.launcher3.InvariantDeviceProfile;
+
+import java.util.concurrent.TimeUnit;
+
+/** Render preview using surface view. */
+public class PreviewSurfaceRenderer implements IBinder.DeathRecipient {
+
+ private static final String KEY_HOST_TOKEN = "host_token";
+ private static final String KEY_VIEW_WIDTH = "width";
+ private static final String KEY_VIEW_HEIGHT = "height";
+ private static final String KEY_DISPLAY_ID = "display_id";
+ private static final String KEY_SURFACE_PACKAGE = "surface_package";
+ private static final String KEY_CALLBACK = "callback";
+
+ private final Context mContext;
+ private final InvariantDeviceProfile mIdp;
+ private final IBinder mHostToken;
+ private final int mWidth;
+ private final int mHeight;
+ private final Display mDisplay;
+
+ private SurfaceControlViewHost mSurfaceControlViewHost;
+
+ PreviewSurfaceRenderer(Context context, Bundle bundle) {
+ mContext = context;
+
+ String gridName = bundle.getString("name");
+ bundle.remove("name");
+ if (gridName == null) {
+ gridName = InvariantDeviceProfile.getCurrentGridName(context);
+ }
+ mIdp = new InvariantDeviceProfile(context, gridName);
+
+ mHostToken = bundle.getBinder(KEY_HOST_TOKEN);
+ mWidth = bundle.getInt(KEY_VIEW_WIDTH);
+ mHeight = bundle.getInt(KEY_VIEW_HEIGHT);
+
+ final DisplayManager displayManager = (DisplayManager) context.getSystemService(
+ Context.DISPLAY_SERVICE);
+ mDisplay = displayManager.getDisplay(bundle.getInt(KEY_DISPLAY_ID));
+ }
+
+ /** Handle a received surface view request. */
+ Bundle render() {
+ if (mSurfaceControlViewHost != null) {
+ binderDied();
+ }
+
+ try {
+ mSurfaceControlViewHost = MAIN_EXECUTOR
+ .submit(() -> new SurfaceControlViewHost(mContext, mDisplay, mHostToken))
+ .get(5, TimeUnit.SECONDS);
+ mHostToken.linkToDeath(this, 0);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+
+ MAIN_EXECUTOR.execute(() -> {
+ View view = new LauncherPreviewRenderer(mContext, mIdp).getRenderedView();
+ // This aspect scales the view to fit in the surface and centers it
+ final float scale = Math.min(mWidth / (float) view.getMeasuredWidth(),
+ mHeight / (float) view.getMeasuredHeight());
+ view.setScaleX(scale);
+ view.setScaleY(scale);
+ view.setPivotX(0);
+ view.setPivotY(0);
+ view.setTranslationX((mWidth - scale * view.getWidth()) / 2);
+ view.setTranslationY((mHeight - scale * view.getHeight()) / 2);
+ mSurfaceControlViewHost.setView(view, view.getMeasuredWidth(),
+ view.getMeasuredHeight());
+ });
+
+ Bundle result = new Bundle();
+ result.putParcelable(KEY_SURFACE_PACKAGE, mSurfaceControlViewHost.getSurfacePackage());
+
+ Handler handler = new Handler(Looper.getMainLooper(), Loopermessage -> {
+ binderDied();
+ return true;
+ });
+ Messenger messenger = new Messenger(handler);
+ Message msg = Message.obtain();
+ msg.replyTo = messenger;
+ result.putParcelable(KEY_CALLBACK, msg);
+ return result;
+ }
+
+ @Override
+ public void binderDied() {
+ if (mSurfaceControlViewHost != null) {
+ mSurfaceControlViewHost.release();
+ mSurfaceControlViewHost = null;
+ }
+ mHostToken.unlinkToDeath(this, 0);
+ }
+}