Skip to content

Commit

Permalink
Merge pull request #46 from DtHnAme/3.0-preview
Browse files Browse the repository at this point in the history
fix: android 14 white screen issues
  • Loading branch information
sunshine0523 committed Nov 10, 2023
2 parents 0086700 + 9c97b81 commit a57314e
Show file tree
Hide file tree
Showing 9 changed files with 205 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,12 @@ public class FreeformDisplayDevice extends DisplayDevice implements IBinder.Deat
private int mWidth;
private int mHeight;
private int mDensityDpi;
private DisplayHidden.Mode mMode;
private Surface mSurface;
private DisplayDeviceInfo mInfo;
protected DisplayHidden.Mode mMode;
protected Surface mSurface;
protected DisplayDeviceInfo mInfo;

private final Callback mCallback;
private final IBinder mAppToken;
protected final Callback mCallback;
protected final IBinder mAppToken;

private int mPendingChanges;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,27 +51,15 @@ public void createFreeformLocked(String name, IMiFreeformDisplayCallback callbac
mFreeformDisplayDevices.put(appToken, device);
miFreeformDisplayCallbackArrayMap.put(device, callback);

new Thread(new Runnable() {
@Override
public void run() {
int count = 10;
LogicalDisplay display = findLogicalDisplayForDevice(device);
while (count-- > 0 && display == null) {
display = findLogicalDisplayForDevice(device);
Log.i(TAG, "findLogicalDisplayForDevice " + display);
if (display == null) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
try {
callback.onDisplayAdd(display.getDisplayIdLocked());
} catch (Exception ignored) {}
mHandler.postDelayed(() -> {
LogicalDisplay display = findLogicalDisplayForDevice(device);
MLog.i(TAG, "findLogicalDisplayForDevice " + display);
try {
callback.onDisplayAdd(display.getDisplayIdLocked());
} catch (Exception ignored) {

}
}).start();
}, 500);

try {
appToken.linkToDeath(device, 0);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,13 @@
package com.android.server.display;

import static com.android.server.display.DisplayDeviceInfo.FLAG_TRUSTED;

import android.content.Context;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.util.ArrayMap;
//@RefineAs(Display.class)
import android.util.Log;
import android.view.DisplayHidden;
import android.view.Surface;
//@RefineAs(SurfaceControl.class)
import android.view.SurfaceControlHidden;

import java.io.PrintWriter;

import io.sunshine0523.freeform.IMiFreeformDisplayCallback;
import io.sunshine0523.freeform.util.MLog;

Expand Down Expand Up @@ -60,35 +51,22 @@ public void createFreeformLocked(String name, IMiFreeformDisplayCallback callbac
mFreeformDisplayDevices.put(appToken, device);
miFreeformDisplayCallbackArrayMap.put(device, callback);

new Thread(new Runnable() {
@Override
public void run() {
int count = 10;
LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(device);
while (count-- > 0 && display == null) {
display = mLogicalDisplayMapper.getDisplayLocked(device);
Log.i(TAG, "findLogicalDisplayForDevice " + display);
if (display == null) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
try {
callback.onDisplayAdd(display.getDisplayIdLocked());
} catch (Exception ignored) {}
mHandler.postDelayed(() -> {
LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(device);
MLog.i(TAG, "findLogicalDisplayForDevice " + display);
try {
callback.onDisplayAdd(display.getDisplayIdLocked());
} catch (Exception e) {

}
}).start();
}, 500);

try {
appToken.linkToDeath(device, 0);
} catch (RemoteException ex) {
mFreeformDisplayDevices.remove(appToken);
device.destroyLocked(false);
}
//MLog.i(TAG, "createFreeformLocked");
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package com.android.server.display;

import android.content.Context;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.DisplayShapeHidden;
import android.view.Surface;

import io.sunshine0523.freeform.IMiFreeformDisplayCallback;

/**
* A display adapter that provides freeform displays on behalf of applications.
* <p>
* Display adapters are guarded by the {@link DisplayManagerService.SyncRoot} lock.
* </p>
* This adapter only support Android U
*/
public final class MiFreeformUDisplayAdapter extends MiFreeformDisplayAdapter {
private final LogicalDisplayMapper mLogicalDisplayMapper;

public MiFreeformUDisplayAdapter(
DisplayManagerService.SyncRoot syncRoot,
Context context,
Handler handler,
DisplayDeviceRepository listener,
LogicalDisplayMapper logicalDisplayMapper,
Handler uiHandler
) {
super(syncRoot, context, handler, listener, uiHandler, TAG);
mLogicalDisplayMapper = logicalDisplayMapper;
}

@Override
public void createFreeformLocked(String name, IMiFreeformDisplayCallback callback,
int width, int height, int densityDpi,
boolean secure, boolean ownContentOnly, boolean shouldShowSystemDecorations,
Surface surface, float refreshRate, long presentationDeadlineNanos) {
synchronized (getSyncRoot()) {
IBinder appToken = callback.asBinder();
FreeformFlags flags = new FreeformFlags(secure, ownContentOnly, shouldShowSystemDecorations);
IBinder displayToken = DisplayControl.createDisplay(UNIQUE_ID_PREFIX + name, flags.mSecure, refreshRate);
FreeformDisplayDevice device = new FreeformUDisplayDevice(displayToken, UNIQUE_ID_PREFIX + name, width, height, densityDpi,
refreshRate, presentationDeadlineNanos,
flags, surface, new Callback(callback, mHandler), callback.asBinder());

sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_ADDED);
mFreeformDisplayDevices.put(appToken, device);
miFreeformDisplayCallbackArrayMap.put(device, callback);

mHandler.postDelayed(() -> {
LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(device);
Log.i(TAG, "findLogicalDisplayForDevice " + display);
try {
callback.onDisplayAdd(display.getDisplayIdLocked());
} catch (Exception ignored) {

}
}, 500);

try {
appToken.linkToDeath(device, 0);
} catch (RemoteException ex) {
mFreeformDisplayDevices.remove(appToken);
device.destroyLocked(false);
}
}
}

@Override
public void resizeFreeform(IBinder appToken, int width, int height, int densityDpi) {
super.resizeFreeform(appToken, width, height, densityDpi);
}

@Override
public void releaseFreeform(IBinder appToken) {
super.releaseFreeform(appToken);
}

private class FreeformUDisplayDevice extends FreeformDisplayDevice {

FreeformUDisplayDevice(IBinder displayToken, String uniqueId,
int width, int height, int density,
float refreshRate, long presentationDeadlineNanos,
FreeformFlags flags, Surface surface,
Callback callback, IBinder appToken) {
super(displayToken, uniqueId,
width, height, density,
refreshRate, presentationDeadlineNanos,
flags, surface, callback, appToken);
}

@Override
public DisplayDeviceInfo getDisplayDeviceInfoLocked() {
super.getDisplayDeviceInfoLocked();
mInfo.displayShape = DisplayShapeHidden.createDefaultDisplayShape(mInfo.width, mInfo.height, false);

return mInfo;
}

@Override
public void destroyLocked(boolean binderAlive) {
if (mSurface != null) {
mSurface.release();
mSurface = null;
}
DisplayControl.destroyDisplay(getDisplayTokenLocked());
if (binderAlive) {
mCallback.dispatchDisplayStopped();
}

}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ private static void instanceMFService(Binder service) throws NoSuchFieldExceptio
Object mDisplayDeviceRepo = mDisplayDeviceRepoField.get(displayManagerServiceObj);
Object mLogicalDisplayMapper = mLogicalDisplayMapperField.get(displayManagerServiceObj);
Class<?> mfdaClass = classLoader.loadClass("com.android.server.display.MiFreeformTDisplayAdapter");
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
mfdaClass = classLoader.loadClass("com.android.server.display.MiFreeformUDisplayAdapter");
}
miFreeformDisplayAdapterObj = mfdaClass.getConstructors()[0].newInstance(mSyncRoot, mContext, mHandler, mDisplayDeviceRepo, mLogicalDisplayMapper, mUiHandler);
mfdaClass.getMethod("registerLocked").invoke(miFreeformDisplayAdapterObj);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ class FreeformWindow(

override fun onSurfaceTextureAvailable(surfaceTexture: SurfaceTexture, width: Int, height: Int) {
MLog.i(TAG, "onSurfaceTextureAvailable width:$width height:$height")
MiFreeformServiceHolder.createDisplay(freeformConfig, appConfig, Surface(surfaceTexture), this)
if (displayId < 0) {
MiFreeformServiceHolder.createDisplay(freeformConfig, appConfig, Surface(surfaceTexture), this)
}
surfaceTexture.setDefaultBufferSize(freeformConfig.freeformWidth, freeformConfig.freeformHeight)
}

Expand Down
13 changes: 13 additions & 0 deletions hidden-api/src/main/java/android/view/DisplayShapeHidden.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package android.view;

import dev.rikka.tools.refine.RefineAs;

@RefineAs(DisplayShape.class)
public class DisplayShapeHidden {

public static DisplayShape createDefaultDisplayShape(
int displayWidth, int displayHeight, boolean isScreenRound) {
throw new RuntimeException("Stub!");
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.android.server.display;

import android.os.IBinder;

public class DisplayControl {

/**
* Create a display in SurfaceFlinger.
*
* @param name The name of the display
* @param secure Whether this display is secure.
* @return The token reference for the display in SurfaceFlinger.
*/
public static IBinder createDisplay(String name, boolean secure) {
throw new RuntimeException("Stub!");
}

/**
* Create a display in SurfaceFlinger.
*
* @param name The name of the display
* @param secure Whether this display is secure.
* @param requestedRefreshRate The requested refresh rate in frames per second.
* For best results, specify a divisor of the physical refresh rate, e.g., 30 or 60 on
* 120hz display. If an arbitrary refresh rate is specified, the rate will be rounded
* up or down to a divisor of the physical display. If 0 is specified, the virtual
* display is refreshed at the physical display refresh rate.
* @return The token reference for the display in SurfaceFlinger.
*/
public static IBinder createDisplay(String name, boolean secure,
float requestedRefreshRate) {
throw new RuntimeException("Stub!");
}

/**
* Destroy a display in SurfaceFlinger.
*
* @param displayToken The display token for the display to be destroyed.
*/
public static void destroyDisplay(IBinder displayToken) {
throw new RuntimeException("Stub!");
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.android.server.display;

import android.view.DisplayHidden;
import android.view.DisplayShape;

final class DisplayDeviceInfo {
/**
Expand Down Expand Up @@ -118,6 +119,11 @@ final class DisplayDeviceInfo {
*/
public int flags;

/**
* The {@link RoundedCorners} if present or {@code null} otherwise.
*/
public DisplayShape displayShape;

/**
* The touch attachment, per {@link DisplayViewport#touch}.
*/
Expand Down

0 comments on commit a57314e

Please sign in to comment.