mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2024-10-20 12:30:24 +00:00
ipc/android: Run spotlessApply to format Java and Kotlin code
This commit is contained in:
parent
fc3af6f711
commit
9840730169
|
@ -7,7 +7,6 @@
|
|||
* @ingroup ipc_android
|
||||
*/
|
||||
|
||||
|
||||
package org.freedesktop.monado.ipc;
|
||||
|
||||
import android.app.Activity;
|
||||
|
@ -37,50 +36,40 @@ import java.util.concurrent.Executors;
|
|||
|
||||
/**
|
||||
* Provides the client-side code to initiate connection to Monado IPC service.
|
||||
* <p>
|
||||
* This class will get loaded into the OpenXR client application by our native code.
|
||||
*
|
||||
* <p>This class will get loaded into the OpenXR client application by our native code.
|
||||
*/
|
||||
@Keep
|
||||
public class Client implements ServiceConnection {
|
||||
private static final String TAG = "monado-ipc-client";
|
||||
/**
|
||||
* Used to block until binder is ready.
|
||||
*/
|
||||
/** Used to block until binder is ready. */
|
||||
private final Object binderSync = new Object();
|
||||
/**
|
||||
* Keep track of the ipc_client_android instance over on the native side.
|
||||
*/
|
||||
/** Keep track of the ipc_client_android instance over on the native side. */
|
||||
private final NativeCounterpart nativeCounterpart;
|
||||
/**
|
||||
* Pointer to local IPC proxy: calling methods on it automatically transports arguments across binder IPC.
|
||||
* <p>
|
||||
* May be null!
|
||||
* Pointer to local IPC proxy: calling methods on it automatically transports arguments across
|
||||
* binder IPC.
|
||||
*
|
||||
* <p>May be null!
|
||||
*/
|
||||
@Keep
|
||||
public IMonado monado = null;
|
||||
@Keep public IMonado monado = null;
|
||||
/**
|
||||
* Indicates that we tried to connect but failed.
|
||||
* <p>
|
||||
* Used to distinguish a "not yet fully connected" null monado member from a "tried and failed"
|
||||
* null monado member.
|
||||
*
|
||||
* <p>Used to distinguish a "not yet fully connected" null monado member from a "tried and
|
||||
* failed" null monado member.
|
||||
*/
|
||||
@Keep
|
||||
public boolean failed = false;
|
||||
@Keep public boolean failed = false;
|
||||
/**
|
||||
* "Our" side of the socket pair - the other side is sent to the server automatically on connection.
|
||||
* "Our" side of the socket pair - the other side is sent to the server automatically on
|
||||
* connection.
|
||||
*/
|
||||
private ParcelFileDescriptor fd = null;
|
||||
/**
|
||||
* Context provided by app.
|
||||
*/
|
||||
/** Context provided by app. */
|
||||
private Context context = null;
|
||||
/**
|
||||
* Context of the runtime package
|
||||
*/
|
||||
/** Context of the runtime package */
|
||||
private Context runtimePackageContext = null;
|
||||
/**
|
||||
* Control system ui visibility
|
||||
*/
|
||||
/** Control system ui visibility */
|
||||
private SystemUiController systemUiController = null;
|
||||
|
||||
/**
|
||||
|
@ -110,9 +99,7 @@ public class Client implements ServiceConnection {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Let the native code notify us that it is no longer using this class.
|
||||
*/
|
||||
/** Let the native code notify us that it is no longer using this class. */
|
||||
@Keep
|
||||
public void markAsDiscardedByNative() {
|
||||
nativeCounterpart.markAsDiscardedByNative(TAG);
|
||||
|
@ -121,22 +108,21 @@ public class Client implements ServiceConnection {
|
|||
|
||||
/**
|
||||
* Bind to the Monado IPC service, and block until it is fully connected.
|
||||
* <p>
|
||||
* The IPC client code on Android should load this class (from the right package), instantiate
|
||||
* this class (retaining a reference to it!), and call this method.
|
||||
* <p>
|
||||
* This method must not be called from the main (UI) thread.
|
||||
*
|
||||
* @param context_ Context to use to make the connection. (We get the application context
|
||||
* from it.)
|
||||
* <p>The IPC client code on Android should load this class (from the right package),
|
||||
* instantiate this class (retaining a reference to it!), and call this method.
|
||||
*
|
||||
* <p>This method must not be called from the main (UI) thread.
|
||||
*
|
||||
* @param context_ Context to use to make the connection. (We get the application context from
|
||||
* it.)
|
||||
* @param packageName The package name containing the Monado runtime. The caller is guaranteed
|
||||
* to know this because it had to load this class from that package.
|
||||
* There's a define in xrt_config_android.h to use for this.
|
||||
* to know this because it had to load this class from that package. There's a define in
|
||||
* xrt_config_android.h to use for this.
|
||||
* @return the fd number - do not close! (dup if you want to be able to close it) Returns -1 if
|
||||
* something went wrong.
|
||||
* <p>
|
||||
* Various builds, variants, etc. will have different package names, but we must specify the
|
||||
* package name explicitly to avoid violating security restrictions.
|
||||
* something went wrong.
|
||||
* <p>Various builds, variants, etc. will have different package names, but we must specify
|
||||
* the package name explicitly to avoid violating security restrictions.
|
||||
*/
|
||||
@Keep
|
||||
public int blockingConnect(Context context_, String packageName) {
|
||||
|
@ -167,42 +153,49 @@ public class Client implements ServiceConnection {
|
|||
// TODO: just initiate MonadoView attachment and add callback to native code to
|
||||
// notify about Surface status and pass it to OpenXR application as a Session lifecycle
|
||||
// (ready ... synchronized ... visible ... focused)
|
||||
new Thread(()-> {
|
||||
boolean surfaceCreated = false;
|
||||
Activity activity = null;
|
||||
if (context_ instanceof Activity) {
|
||||
activity = (Activity) context_;
|
||||
}
|
||||
new Thread(
|
||||
() -> {
|
||||
boolean surfaceCreated = false;
|
||||
Activity activity = null;
|
||||
if (context_ instanceof Activity) {
|
||||
activity = (Activity) context_;
|
||||
}
|
||||
|
||||
try {
|
||||
// Determine whether runtime or client should create surface
|
||||
if (monado.canDrawOverOtherApps()) {
|
||||
WindowManager wm = (WindowManager) context_.getSystemService(Context.WINDOW_SERVICE);
|
||||
surfaceCreated = monado.createSurface(wm.getDefaultDisplay().getDisplayId(), false);
|
||||
} else {
|
||||
if (activity != null) {
|
||||
Surface surface = attachViewAndGetSurface(activity);
|
||||
surfaceCreated = (surface != null);
|
||||
if (surfaceCreated) {
|
||||
monado.passAppSurface(surface);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
// Determine whether runtime or client should create surface
|
||||
if (monado.canDrawOverOtherApps()) {
|
||||
WindowManager wm =
|
||||
(WindowManager)
|
||||
context_.getSystemService(
|
||||
Context.WINDOW_SERVICE);
|
||||
surfaceCreated =
|
||||
monado.createSurface(
|
||||
wm.getDefaultDisplay().getDisplayId(), false);
|
||||
} else {
|
||||
if (activity != null) {
|
||||
Surface surface = attachViewAndGetSurface(activity);
|
||||
surfaceCreated = (surface != null);
|
||||
if (surfaceCreated) {
|
||||
monado.passAppSurface(surface);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (!surfaceCreated) {
|
||||
Log.e(TAG, "Failed to create surface");
|
||||
handleFailure();
|
||||
return;
|
||||
}
|
||||
if (!surfaceCreated) {
|
||||
Log.e(TAG, "Failed to create surface");
|
||||
handleFailure();
|
||||
return;
|
||||
}
|
||||
|
||||
if (activity != null) {
|
||||
systemUiController = new SystemUiController(activity);
|
||||
systemUiController.hide();
|
||||
}
|
||||
}).start();
|
||||
if (activity != null) {
|
||||
systemUiController = new SystemUiController(activity);
|
||||
systemUiController.hide();
|
||||
}
|
||||
})
|
||||
.start();
|
||||
|
||||
// Create socket pair
|
||||
ParcelFileDescriptor theirs;
|
||||
|
@ -233,15 +226,13 @@ public class Client implements ServiceConnection {
|
|||
* Bind to the Monado IPC service - this asynchronously starts connecting (and launching the
|
||||
* service if it's not already running)
|
||||
*
|
||||
* @param context_ Context to use to make the connection. (We get the application context
|
||||
* from it.)
|
||||
* @param context_ Context to use to make the connection. (We get the application context from
|
||||
* it.)
|
||||
* @param packageName The package name containing the Monado runtime. The caller is guaranteed
|
||||
* to know this because it had to load this class from that package.
|
||||
* There's a define in xrt_config_android.h to use for this.
|
||||
* <p>
|
||||
* Various builds, variants, etc. will have different package names, but we
|
||||
* must specify the package name explicitly to avoid violating security
|
||||
* restrictions.
|
||||
* to know this because it had to load this class from that package. There's a define in
|
||||
* xrt_config_android.h to use for this.
|
||||
* <p>Various builds, variants, etc. will have different package names, but we must specify
|
||||
* the package name explicitly to avoid violating security restrictions.
|
||||
*/
|
||||
public boolean bind(Context context_, String packageName) {
|
||||
Log.i(TAG, "bind");
|
||||
|
@ -251,20 +242,20 @@ public class Client implements ServiceConnection {
|
|||
context = context_;
|
||||
}
|
||||
try {
|
||||
runtimePackageContext = context.createPackageContext(packageName,
|
||||
Context.CONTEXT_IGNORE_SECURITY | Context.CONTEXT_INCLUDE_CODE);
|
||||
runtimePackageContext =
|
||||
context.createPackageContext(
|
||||
packageName,
|
||||
Context.CONTEXT_IGNORE_SECURITY | Context.CONTEXT_INCLUDE_CODE);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
Log.e(TAG, "bind: Could not find package " + packageName);
|
||||
return false;
|
||||
}
|
||||
|
||||
Intent intent = new Intent(BuildConfig.SERVICE_ACTION)
|
||||
.setPackage(packageName);
|
||||
Intent intent = new Intent(BuildConfig.SERVICE_ACTION).setPackage(packageName);
|
||||
|
||||
if (!bindService(context, intent)) {
|
||||
Log.e(TAG,
|
||||
"bindService: Service " + intent + " could not be found to bind!");
|
||||
Log.e(TAG, "bindService: Service " + intent + " could not be found to bind!");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -276,8 +267,12 @@ public class Client implements ServiceConnection {
|
|||
boolean result;
|
||||
int flags = Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT | Context.BIND_ABOVE_CLIENT;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
result = context.bindService(intent, flags | Context.BIND_INCLUDE_CAPABILITIES,
|
||||
Executors.newSingleThreadExecutor(), this);
|
||||
result =
|
||||
context.bindService(
|
||||
intent,
|
||||
flags | Context.BIND_INCLUDE_CAPABILITIES,
|
||||
Executors.newSingleThreadExecutor(),
|
||||
this);
|
||||
} else {
|
||||
result = context.bindService(intent, this, flags);
|
||||
}
|
||||
|
@ -285,16 +280,13 @@ public class Client implements ServiceConnection {
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Some on-failure cleanup.
|
||||
*/
|
||||
/** Some on-failure cleanup. */
|
||||
private void handleFailure() {
|
||||
failed = true;
|
||||
shutdown();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Surface attachViewAndGetSurface(Activity activity) {
|
||||
@Nullable private Surface attachViewAndGetSurface(Activity activity) {
|
||||
MonadoView monadoView = MonadoView.attachToActivity(activity);
|
||||
SurfaceHolder holder = monadoView.waitGetSurfaceHolder(2000);
|
||||
Surface surface = null;
|
||||
|
@ -308,7 +300,7 @@ public class Client implements ServiceConnection {
|
|||
/**
|
||||
* Handle the asynchronous connection of the binder IPC.
|
||||
*
|
||||
* @param name should match the preceding intent, but not used.
|
||||
* @param name should match the preceding intent, but not used.
|
||||
* @param service the associated service, which we cast in this function.
|
||||
*/
|
||||
@Override
|
||||
|
@ -330,7 +322,7 @@ public class Client implements ServiceConnection {
|
|||
public void onServiceDisconnected(ComponentName name) {
|
||||
Log.i(TAG, "onServiceDisconnected");
|
||||
shutdown();
|
||||
//! @todo tell C/C++ that the world is crumbling, then close the fd here.
|
||||
// ! @todo tell C/C++ that the world is crumbling, then close the fd here.
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
* @ingroup ipc_android
|
||||
*/
|
||||
|
||||
|
||||
package org.freedesktop.monado.ipc;
|
||||
|
||||
import android.os.ParcelFileDescriptor;
|
||||
|
@ -23,12 +22,12 @@ import java.io.IOException;
|
|||
|
||||
/**
|
||||
* Java implementation of the IMonado IPC interface.
|
||||
* <p>
|
||||
* (This is the server-side code.)
|
||||
* <p>
|
||||
* All this does is delegate calls to native JNI implementations.
|
||||
* The warning suppression is because Android Studio tends to have a hard time finding
|
||||
* the (very real) implementations of these in service-lib.
|
||||
*
|
||||
* <p>(This is the server-side code.)
|
||||
*
|
||||
* <p>All this does is delegate calls to native JNI implementations. The warning suppression is
|
||||
* because Android Studio tends to have a hard time finding the (very real) implementations of these
|
||||
* in service-lib.
|
||||
*/
|
||||
@Keep
|
||||
public class MonadoImpl extends IMonado.Stub {
|
||||
|
@ -45,21 +44,21 @@ public class MonadoImpl extends IMonado.Stub {
|
|||
|
||||
public MonadoImpl(@NonNull SurfaceManager surfaceManager) {
|
||||
this.surfaceManager = surfaceManager;
|
||||
this.surfaceManager.setCallback(new SurfaceHolder.Callback() {
|
||||
@Override
|
||||
public void surfaceCreated(@NonNull SurfaceHolder holder) {
|
||||
Log.i(TAG, "surfaceCreated");
|
||||
passAppSurface(holder.getSurface());
|
||||
}
|
||||
this.surfaceManager.setCallback(
|
||||
new SurfaceHolder.Callback() {
|
||||
@Override
|
||||
public void surfaceCreated(@NonNull SurfaceHolder holder) {
|
||||
Log.i(TAG, "surfaceCreated");
|
||||
passAppSurface(holder.getSurface());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
|
||||
}
|
||||
@Override
|
||||
public void surfaceChanged(
|
||||
@NonNull SurfaceHolder holder, int format, int width, int height) {}
|
||||
|
||||
@Override
|
||||
public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
|
||||
}
|
||||
});
|
||||
@Override
|
||||
public void surfaceDestroyed(@NonNull SurfaceHolder holder) {}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -111,18 +110,16 @@ public class MonadoImpl extends IMonado.Stub {
|
|||
nativeShutdownServer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Native method that starts server.
|
||||
*/
|
||||
/** Native method that starts server. */
|
||||
@SuppressWarnings("JavaJniMissingFunction")
|
||||
private native void nativeStartServer();
|
||||
|
||||
/**
|
||||
* Native handling of receiving a surface: should convert it to an ANativeWindow then do stuff
|
||||
* with it.
|
||||
* <p>
|
||||
* Ignore warnings that this function is missing: it is not, it is just in a different module.
|
||||
* See `src/xrt/targets/service-lib/service_target.cpp` for the implementation.
|
||||
*
|
||||
* <p>Ignore warnings that this function is missing: it is not, it is just in a different
|
||||
* module. See `src/xrt/targets/service-lib/service_target.cpp` for the implementation.
|
||||
*
|
||||
* @param surface The surface to pass to native code
|
||||
* @todo figure out a good way to have a client ID
|
||||
|
@ -133,13 +130,13 @@ public class MonadoImpl extends IMonado.Stub {
|
|||
/**
|
||||
* Native handling of receiving an FD for a new client: the FD should be used to start up the
|
||||
* rest of the native IPC code on that socket.
|
||||
* <p>
|
||||
* This is essentially the entry point for the monado service on Android: if it's already
|
||||
*
|
||||
* <p>This is essentially the entry point for the monado service on Android: if it's already
|
||||
* running, this will be called in it. If it's not already running, a process will be created,
|
||||
* and this will be the first native code executed in that process.
|
||||
* <p>
|
||||
* Ignore warnings that this function is missing: it is not, it is just in a different module.
|
||||
* See `src/xrt/targets/service-lib/service_target.cpp` for the implementation.
|
||||
*
|
||||
* <p>Ignore warnings that this function is missing: it is not, it is just in a different
|
||||
* module. See `src/xrt/targets/service-lib/service_target.cpp` for the implementation.
|
||||
*
|
||||
* @param fd The incoming file descriptor: ownership is transferred to native code here.
|
||||
* @return 0 on success, anything else means the fd wasn't sent and ownership not transferred.
|
||||
|
|
|
@ -16,8 +16,8 @@ import android.os.Build
|
|||
import android.os.IBinder
|
||||
import android.util.Log
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import org.freedesktop.monado.auxiliary.IServiceNotification
|
||||
import javax.inject.Inject
|
||||
import org.freedesktop.monado.auxiliary.IServiceNotification
|
||||
|
||||
/**
|
||||
* Implementation of a Service that provides the Monado AIDL interface.
|
||||
|
@ -30,8 +30,7 @@ class MonadoService : Service(), Watchdog.ShutdownListener {
|
|||
|
||||
private lateinit var watchdog: Watchdog
|
||||
|
||||
@Inject
|
||||
lateinit var serviceNotification: IServiceNotification
|
||||
@Inject lateinit var serviceNotification: IServiceNotification
|
||||
|
||||
private lateinit var surfaceManager: SurfaceManager
|
||||
|
||||
|
@ -40,12 +39,14 @@ class MonadoService : Service(), Watchdog.ShutdownListener {
|
|||
|
||||
surfaceManager = SurfaceManager(this)
|
||||
binder = MonadoImpl(surfaceManager)
|
||||
watchdog = Watchdog(
|
||||
// If the surface comes from client, just stop the service when client disconnected
|
||||
// because the surface belongs to the client.
|
||||
if (surfaceManager.canDrawOverlays()) BuildConfig.WATCHDOG_TIMEOUT_MILLISECONDS else 0,
|
||||
this
|
||||
)
|
||||
watchdog =
|
||||
Watchdog(
|
||||
// If the surface comes from client, just stop the service when client disconnected
|
||||
// because the surface belongs to the client.
|
||||
if (surfaceManager.canDrawOverlays()) BuildConfig.WATCHDOG_TIMEOUT_MILLISECONDS
|
||||
else 0,
|
||||
this
|
||||
)
|
||||
watchdog.startMonitor()
|
||||
|
||||
// start the service so it could be foregrounded
|
||||
|
@ -58,7 +59,7 @@ class MonadoService : Service(), Watchdog.ShutdownListener {
|
|||
super.onDestroy()
|
||||
Log.d(TAG, "onDestroy")
|
||||
|
||||
binder.shutdown();
|
||||
binder.shutdown()
|
||||
watchdog.stopMonitor()
|
||||
surfaceManager.destroySurface()
|
||||
}
|
||||
|
@ -76,7 +77,7 @@ class MonadoService : Service(), Watchdog.ShutdownListener {
|
|||
}
|
||||
|
||||
override fun onBind(intent: Intent): IBinder? {
|
||||
Log.d(TAG, "onBind");
|
||||
Log.d(TAG, "onBind")
|
||||
watchdog.onClientConnected()
|
||||
return binder
|
||||
}
|
||||
|
@ -87,12 +88,13 @@ class MonadoService : Service(), Watchdog.ShutdownListener {
|
|||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
flags = PendingIntent.FLAG_IMMUTABLE
|
||||
}
|
||||
val pendingShutdownIntent = PendingIntent.getForegroundService(
|
||||
this,
|
||||
0,
|
||||
Intent(BuildConfig.SHUTDOWN_ACTION).setPackage(packageName),
|
||||
flags
|
||||
)
|
||||
val pendingShutdownIntent =
|
||||
PendingIntent.getForegroundService(
|
||||
this,
|
||||
0,
|
||||
Intent(BuildConfig.SHUTDOWN_ACTION).setPackage(packageName),
|
||||
flags
|
||||
)
|
||||
|
||||
val notification = serviceNotification.buildNotification(this, pendingShutdownIntent)
|
||||
|
||||
|
@ -103,21 +105,18 @@ class MonadoService : Service(), Watchdog.ShutdownListener {
|
|||
ServiceInfo.FOREGROUND_SERVICE_TYPE_MANIFEST
|
||||
)
|
||||
} else {
|
||||
startForeground(
|
||||
serviceNotification.getNotificationId(),
|
||||
notification
|
||||
)
|
||||
startForeground(serviceNotification.getNotificationId(), notification)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onUnbind(intent: Intent?): Boolean {
|
||||
Log.d(TAG, "onUnbind");
|
||||
Log.d(TAG, "onUnbind")
|
||||
watchdog.onClientDisconnected()
|
||||
return true;
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onRebind(intent: Intent?) {
|
||||
Log.d(TAG, "onRebind");
|
||||
Log.d(TAG, "onRebind")
|
||||
watchdog.onClientConnected()
|
||||
}
|
||||
|
||||
|
|
|
@ -24,9 +24,7 @@ import java.util.concurrent.TimeUnit
|
|||
import java.util.concurrent.locks.Condition
|
||||
import java.util.concurrent.locks.ReentrantLock
|
||||
|
||||
/**
|
||||
* Class that creates/manages surface on display.
|
||||
*/
|
||||
/** Class that creates/manages surface on display. */
|
||||
class SurfaceManager(context: Context) : SurfaceHolder.Callback {
|
||||
private val appContext: Context = context.applicationContext
|
||||
private val surfaceLock: ReentrantLock = ReentrantLock()
|
||||
|
@ -109,8 +107,8 @@ class SurfaceManager(context: Context) : SurfaceHolder.Callback {
|
|||
/**
|
||||
* Check if current process has the capability to draw over other applications.
|
||||
*
|
||||
* Implementation of [Settings.canDrawOverlays] checks both context and UID,
|
||||
* therefore this cannot be done in client side.
|
||||
* Implementation of [Settings.canDrawOverlays] checks both context and UID, therefore this
|
||||
* cannot be done in client side.
|
||||
*
|
||||
* @return True if current process can draw over other applications; otherwise false.
|
||||
*/
|
||||
|
@ -118,16 +116,12 @@ class SurfaceManager(context: Context) : SurfaceHolder.Callback {
|
|||
return Settings.canDrawOverlays(appContext)
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy created surface.
|
||||
*/
|
||||
/** Destroy created surface. */
|
||||
fun destroySurface() {
|
||||
viewHelper.removeView()
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper class that manages surface view.
|
||||
*/
|
||||
/** Helper class that manages surface view. */
|
||||
private class ViewHelper(private val callback: SurfaceHolder.Callback) {
|
||||
private var view: SurfaceView? = null
|
||||
private var displayContext: Context? = null
|
||||
|
@ -162,9 +156,7 @@ class SurfaceManager(context: Context) : SurfaceHolder.Callback {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether given display is the one being used right now.
|
||||
*/
|
||||
/** Check whether given display is the one being used right now. */
|
||||
@Suppress("DEPRECATION")
|
||||
private fun isSameDisplay(context: Context, display: Display): Boolean {
|
||||
val wm = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
|
||||
|
@ -186,7 +178,7 @@ class SurfaceManager(context: Context) : SurfaceHolder.Callback {
|
|||
lp.flags = if (focusable) VIEW_FLAG_FOCUSABLE else VIEW_FLAG_NOT_FOCUSABLE
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||
lp.layoutInDisplayCutoutMode =
|
||||
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
|
||||
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
|
||||
}
|
||||
|
||||
val wm = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
|
||||
|
@ -212,12 +204,11 @@ class SurfaceManager(context: Context) : SurfaceHolder.Callback {
|
|||
@Suppress("DEPRECATION")
|
||||
private const val VIEW_FLAG_NOT_FOCUSABLE =
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN or
|
||||
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
|
||||
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "SurfaceManager"
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -13,9 +13,7 @@ import android.os.HandlerThread
|
|||
import android.os.Message
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
|
||||
/**
|
||||
* Client watchdog, to determine whether runtime service should be stopped.
|
||||
*/
|
||||
/** Client watchdog, to determine whether runtime service should be stopped. */
|
||||
class Watchdog(
|
||||
private val shutdownDelayMilliseconds: Long,
|
||||
private val shutdownListener: ShutdownListener
|
||||
|
@ -25,14 +23,10 @@ class Watchdog(
|
|||
* all the callbacks run on background thread.
|
||||
*/
|
||||
interface ShutdownListener {
|
||||
/**
|
||||
* Callback to be invoked when last client disconnected.
|
||||
*/
|
||||
/** Callback to be invoked when last client disconnected. */
|
||||
fun onPrepareShutdown()
|
||||
|
||||
/**
|
||||
* Callback to be invoked when shutdown delay ended and there's no new client connected.
|
||||
*/
|
||||
/** Callback to be invoked when shutdown delay ended and there's no new client connected. */
|
||||
fun onShutdown()
|
||||
}
|
||||
|
||||
|
@ -45,15 +39,17 @@ class Watchdog(
|
|||
fun startMonitor() {
|
||||
shutdownThread = HandlerThread("monado-client-watchdog")
|
||||
shutdownThread.start()
|
||||
shutdownHandler = object : Handler(shutdownThread.looper) {
|
||||
override fun handleMessage(msg: Message) {
|
||||
when (msg.what) {
|
||||
MSG_SHUTDOWN -> if (clientCount.get() == 0) {
|
||||
shutdownListener.onShutdown()
|
||||
shutdownHandler =
|
||||
object : Handler(shutdownThread.looper) {
|
||||
override fun handleMessage(msg: Message) {
|
||||
when (msg.what) {
|
||||
MSG_SHUTDOWN ->
|
||||
if (clientCount.get() == 0) {
|
||||
shutdownListener.onShutdown()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun stopMonitor() {
|
||||
|
|
Loading…
Reference in a new issue