SdkActivityLauncherFactory.kt
/*
* Copyright 2023 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 androidx.privacysandbox.activity.provider
import android.os.Bundle
import android.os.IBinder
import androidx.privacysandbox.activity.core.ISdkActivityLauncher
import androidx.privacysandbox.activity.core.ISdkActivityLauncherCallback
import androidx.privacysandbox.activity.core.ProtocolConstants.SDK_ACTIVITY_LAUNCHER_BINDER_KEY
import androidx.privacysandbox.activity.core.SdkActivityLauncher
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlinx.coroutines.suspendCancellableCoroutine
object SdkActivityLauncherFactory {
/**
* Creates a [SdkActivityLauncher] using the given [launcherInfo] Bundle.
*
* You can create such a Bundle by calling [toLauncherInfo][androidx.privacysandbox.activity.client.toLauncherInfo].
* A [launcherInfo] is expected to have a valid SdkActivityLauncher Binder with
* `"sdkActivityLauncherBinderKey"` for a key, [IllegalArgumentException] is thrown otherwise.
*/
@JvmStatic
fun fromLauncherInfo(launcherInfo: Bundle): SdkActivityLauncher {
val remote: ISdkActivityLauncher? = ISdkActivityLauncher.Stub.asInterface(
launcherInfo.getBinder(SDK_ACTIVITY_LAUNCHER_BINDER_KEY)
)
requireNotNull(remote) { "Invalid SdkActivityLauncher info bundle." }
return SdkActivityLauncherProxy(remote)
}
private class SdkActivityLauncherProxy(
private val remote: ISdkActivityLauncher
) : SdkActivityLauncher {
override suspend fun launchSdkActivity(sdkActivityHandlerToken: IBinder): Boolean =
suspendCancellableCoroutine {
remote.launchSdkActivity(
sdkActivityHandlerToken,
object : ISdkActivityLauncherCallback.Stub() {
override fun onLaunchAccepted(sdkActivityHandlerToken: IBinder?) {
it.resume(true)
}
override fun onLaunchRejected(sdkActivityHandlerToken: IBinder?) {
it.resume(false)
}
override fun onLaunchError(message: String?) {
it.resumeWithException(RuntimeException(message))
}
})
}
}
}