mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-03-01 00:06:47 +00:00
Fixes: 155365052 Test: manually quick switches between different grid options Change-Id: I31dc14b0a50b5e3a5c81272b693303034fcf8b40
149 lines
5.4 KiB
Java
149 lines
5.4 KiB
Java
/*
|
|
* 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 android.view.animation.AccelerateDecelerateInterpolator;
|
|
|
|
import com.android.launcher3.InvariantDeviceProfile;
|
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
/** Render preview using surface view. */
|
|
public class PreviewSurfaceRenderer implements IBinder.DeathRecipient {
|
|
|
|
private static final int FADE_IN_ANIMATION_DURATION = 200;
|
|
|
|
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();
|
|
}
|
|
|
|
SurfaceControlViewHost.SurfacePackage surfacePackage;
|
|
try {
|
|
mSurfaceControlViewHost = MAIN_EXECUTOR
|
|
.submit(() -> new SurfaceControlViewHost(mContext, mDisplay, mHostToken))
|
|
.get(5, TimeUnit.SECONDS);
|
|
surfacePackage = mSurfaceControlViewHost.getSurfacePackage();
|
|
mHostToken.linkToDeath(this, 0);
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
return null;
|
|
}
|
|
|
|
MAIN_EXECUTOR.execute(() -> {
|
|
// If mSurfaceControlViewHost is null due to any reason (e.g. binder died,
|
|
// happening when user leaves the preview screen before preview rendering finishes),
|
|
// we should return here.
|
|
SurfaceControlViewHost host = mSurfaceControlViewHost;
|
|
if (host == null) {
|
|
return;
|
|
}
|
|
|
|
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);
|
|
view.setAlpha(0);
|
|
view.animate().alpha(1)
|
|
.setInterpolator(new AccelerateDecelerateInterpolator())
|
|
.setDuration(FADE_IN_ANIMATION_DURATION)
|
|
.start();
|
|
host.setView(view, view.getMeasuredWidth(),
|
|
view.getMeasuredHeight());
|
|
});
|
|
|
|
Bundle result = new Bundle();
|
|
result.putParcelable(KEY_SURFACE_PACKAGE, surfacePackage);
|
|
|
|
Handler handler = new Handler(Looper.getMainLooper(), message -> {
|
|
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) {
|
|
MAIN_EXECUTOR.execute(() -> {
|
|
mSurfaceControlViewHost.release();
|
|
mSurfaceControlViewHost = null;
|
|
});
|
|
}
|
|
mHostToken.unlinkToDeath(this, 0);
|
|
}
|
|
}
|