ipc/android: Be a foreground service

This commit is contained in:
Ryan Pavlik 2020-11-13 14:21:46 -06:00 committed by Lubosz Sarnecki
parent b92646c778
commit 974e7bd1d5
4 changed files with 66 additions and 6 deletions
src/xrt/ipc/android
build.gradle
src/main
AndroidManifest.xml
java/org/freedesktop/monado/ipc

View file

@ -19,12 +19,15 @@ android {
minSdkVersion 26
targetSdkVersion project.sharedTargetSdk
// Single point of truth for this name.
// Single point of truth for these names.
def serviceAction = "org.freedesktop.monado.ipc.CONNECT"
def shutdownAction = "org.freedesktop.monado.ipc.SHUTDOWN"
manifestPlaceholders = [
serviceActionName: serviceAction
serviceActionName : serviceAction,
shutdownActionName: shutdownAction
]
buildConfigField("String", "SERVICE_ACTION", "\"${serviceAction}\"")
buildConfigField("String", "SHUTDOWN_ACTION", "\"${shutdownAction}\"")
}
buildTypes {

View file

@ -13,6 +13,7 @@
android:foregroundServiceType="connectedDevice|mediaPlayback">
<intent-filter>
<action android:name="${serviceActionName}" />
<action android:name="${shutdownActionName}" />
</intent-filter>
</service>
</application>

View file

@ -90,6 +90,9 @@ public class Client implements ServiceConnection {
if (context != null) {
context.unbindService(this);
}
if (intent != null) {
context.stopService(intent);
}
intent = null;
//! @todo do we close this first?
@ -176,7 +179,10 @@ public class Client implements ServiceConnection {
Intent intent = new Intent(BuildConfig.SERVICE_ACTION)
.setPackage(packageName);
context.startForegroundService(intent);
if (context.startForegroundService(intent) == null) {
Log.e(TAG, "startForegroundService: Service " + intent.toString() + " does not exist!");
return false;
}
if (!context.bindService(intent,
this,
Context.BIND_AUTO_CREATE

View file

@ -8,21 +8,71 @@
*/
package org.freedesktop.monado.ipc
import android.app.PendingIntent
import android.app.Service
import android.content.Intent
import android.content.pm.ServiceInfo
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
/**
* Minimal implementation of a Service.
* Implementation of a Service that provides the Monado AIDL interface.
*
* This is needed so that the APK can expose the binder service implemented in MonadoImpl.
*/
@AndroidEntryPoint
class MonadoService : Service() {
val monado: MonadoImpl = MonadoImpl()
private val binder = MonadoImpl()
@Inject
lateinit var serviceNotification: IServiceNotification
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
Log.d(TAG, "onStartCommand")
// if this isn't a restart
if (intent != null) {
when (intent.action) {
BuildConfig.SERVICE_ACTION -> handleStart()
BuildConfig.SHUTDOWN_ACTION -> handleShutdown()
}
}
return START_STICKY
}
private fun handleShutdown() {
stopForeground(true)
stopSelf()
}
override fun onBind(intent: Intent): IBinder? {
return monado
return binder
}
private fun handleStart() {
val pendingShutdownIntent = PendingIntent.getForegroundService(this,
0,
Intent(BuildConfig.SHUTDOWN_ACTION).setPackage(packageName),
0)
val notification = serviceNotification.buildNotification(this, pendingShutdownIntent)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
startForeground(serviceNotification.getNotificationId(),
notification,
ServiceInfo.FOREGROUND_SERVICE_TYPE_MANIFEST)
} else {
startForeground(serviceNotification.getNotificationId(),
notification)
}
}
companion object {
private const val TAG = "MonadoService"
}
}