mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-02-20 11:18:21 +00:00
Using the first frame delay based on the display refresh rate instead of
hardcoding it to 16ms > Creating a utility class for caching display property changes Bug: 128940249 Change-Id: I6f9a214548de65bd1c8530508d665ee88312da4a
This commit is contained in:
166
src/com/android/launcher3/util/DefaultDisplay.java
Normal file
166
src/com/android/launcher3/util/DefaultDisplay.java
Normal file
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* Copyright (C) 2019 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.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Point;
|
||||
import android.hardware.display.DisplayManager;
|
||||
import android.hardware.display.DisplayManager.DisplayListener;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.util.Log;
|
||||
import android.view.Display;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Utility class to cache properties of default display to avoid a system RPC on every call.
|
||||
*/
|
||||
public class DefaultDisplay implements DisplayListener {
|
||||
|
||||
public static final MainThreadInitializedObject<DefaultDisplay> INSTANCE =
|
||||
new MainThreadInitializedObject<>(DefaultDisplay::new);
|
||||
|
||||
private static final String TAG = "DefaultDisplay";
|
||||
|
||||
public static final int CHANGE_SIZE = 1 << 0;
|
||||
public static final int CHANGE_ROTATION = 1 << 1;
|
||||
public static final int CHANGE_FRAME_DELAY = 1 << 2;
|
||||
|
||||
private final Context mContext;
|
||||
private final int mId;
|
||||
private final ArrayList<DisplayInfoChangeListener> mListeners = new ArrayList<>();
|
||||
private final Handler mChangeHandler;
|
||||
private Info mInfo;
|
||||
|
||||
private DefaultDisplay(Context context) {
|
||||
mContext = context;
|
||||
mInfo = new Info(context);
|
||||
mId = mInfo.id;
|
||||
mChangeHandler = new Handler(this::onChange);
|
||||
|
||||
context.getSystemService(DisplayManager.class)
|
||||
.registerDisplayListener(this, new Handler(UiThreadHelper.getBackgroundLooper()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void onDisplayAdded(int displayId) { }
|
||||
|
||||
@Override
|
||||
public final void onDisplayRemoved(int displayId) { }
|
||||
|
||||
@Override
|
||||
public final void onDisplayChanged(int displayId) {
|
||||
if (displayId != mId) {
|
||||
return;
|
||||
}
|
||||
|
||||
Info oldInfo = mInfo;
|
||||
Info info = new Info(mContext);
|
||||
|
||||
int change = 0;
|
||||
if (info.hasDifferentSize(oldInfo)) {
|
||||
change |= CHANGE_SIZE;
|
||||
}
|
||||
if (oldInfo.rotation != info.rotation) {
|
||||
change |= CHANGE_ROTATION;
|
||||
}
|
||||
if (info.singleFrameMs != oldInfo.singleFrameMs) {
|
||||
change |= CHANGE_FRAME_DELAY;
|
||||
}
|
||||
|
||||
if (change != 0) {
|
||||
mInfo = info;
|
||||
mChangeHandler.sendEmptyMessage(change);
|
||||
}
|
||||
}
|
||||
|
||||
public static int getSingleFrameMs(Context context) {
|
||||
return INSTANCE.get(context).getInfo().singleFrameMs;
|
||||
}
|
||||
|
||||
public Info getInfo() {
|
||||
return mInfo;
|
||||
}
|
||||
|
||||
public void addChangeListener(DisplayInfoChangeListener listener) {
|
||||
mListeners.add(listener);
|
||||
}
|
||||
|
||||
public void removeChangeListener(DisplayInfoChangeListener listener) {
|
||||
mListeners.remove(listener);
|
||||
}
|
||||
|
||||
private boolean onChange(Message msg) {
|
||||
for (int i = mListeners.size() - 1; i >= 0; i--) {
|
||||
mListeners.get(i).onDisplayInfoChanged(mInfo, msg.what);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static class Info {
|
||||
|
||||
public final int id;
|
||||
public final int rotation;
|
||||
public final int singleFrameMs;
|
||||
|
||||
public final Point realSize;
|
||||
public final Point smallestSize;
|
||||
public final Point largestSize;
|
||||
|
||||
private Info(Context context) {
|
||||
Display display = context.getSystemService(WindowManager.class).getDefaultDisplay();
|
||||
|
||||
id = display.getDisplayId();
|
||||
rotation = display.getRotation();
|
||||
|
||||
float refreshRate = display.getRefreshRate();
|
||||
singleFrameMs = refreshRate > 0 ? (int) (1000 / refreshRate) : 16;
|
||||
|
||||
realSize = new Point();
|
||||
smallestSize = new Point();
|
||||
largestSize = new Point();
|
||||
display.getRealSize(realSize);
|
||||
display.getCurrentSizeRange(smallestSize, largestSize);
|
||||
}
|
||||
|
||||
private boolean hasDifferentSize(Info info) {
|
||||
if (!realSize.equals(info.realSize)
|
||||
&& !realSize.equals(info.realSize.y, info.realSize.x)) {
|
||||
Log.d(TAG, String.format("Display size changed from %s to %s",
|
||||
info.realSize, realSize));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!smallestSize.equals(info.smallestSize) || !largestSize.equals(info.largestSize)) {
|
||||
Log.d(TAG, String.format("Available size changed from [%s, %s] to [%s, %s]",
|
||||
smallestSize, largestSize, info.smallestSize, info.largestSize));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for listening for display changes
|
||||
*/
|
||||
public interface DisplayInfoChangeListener {
|
||||
|
||||
void onDisplayInfoChanged(Info info, int flags);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user