Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bfce36ed authored by Mark Renouf's avatar Mark Renouf
Browse files

Adds SystemUiProxy / SystemUiProxyClient

This is a single interface for interacting with ScreenshotProxyService,
which should be renamed prioxy/SystemUiProxyService.

The other direct usages of the service through ServiceConnector
will be consolidated and this interface should be the standard
API.

Bug: 327613051
Test: compile
Flag: None; not used yet
Change-Id: Iace58c81b5fb5bbcb46d27bd2415be550b7c2bb9
parent decb0f1d
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -30,7 +30,7 @@ import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.withContext

/** Provides state from the main SystemUI process on behalf of the Screenshot process. */
internal class ScreenshotProxyService
class ScreenshotProxyService
@Inject
constructor(
    private val mExpansionMgr: ShadeExpansionStateManager,
+2 −1
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ import com.android.systemui.screenshot.TakeScreenshotService;
import com.android.systemui.screenshot.appclips.AppClipsScreenshotHelperService;
import com.android.systemui.screenshot.appclips.AppClipsService;
import com.android.systemui.screenshot.policy.ScreenshotPolicyModule;
import com.android.systemui.screenshot.proxy.SystemUiProxyModule;
import com.android.systemui.screenshot.ui.viewmodel.ScreenshotViewModel;

import dagger.Binds;
@@ -52,7 +53,7 @@ import dagger.multibindings.IntoMap;
/**
 * Defines injectable resources for Screenshots
 */
@Module(includes = ScreenshotPolicyModule.class)
@Module(includes = {ScreenshotPolicyModule.class, SystemUiProxyModule.class})
public abstract class ScreenshotModule {

    @Binds
+36 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.systemui.screenshot.proxy

/**
 * Provides a mechanism to interact with the main SystemUI process.
 *
 * ScreenshotService runs in an isolated process. Because of this, interactions with an outside
 * component with shared state must be accessed through this proxy to reach the correct instance.
 *
 * TODO: Rename and relocate 'ScreenshotProxyService' to this package and remove duplicate clients.
 */
interface SystemUiProxy {
    /** Indicate if the notification shade is "open"... (not in the fully collapsed position) */
    suspend fun isNotificationShadeExpanded(): Boolean

    /**
     * Request keyguard dismissal, raising keyguard credential entry if required and waits for
     * completion.
     */
    suspend fun dismissKeyguard()
}
+70 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.systemui.screenshot.proxy

import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.util.Log
import com.android.internal.infra.ServiceConnector
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.screenshot.IOnDoneCallback
import com.android.systemui.screenshot.IScreenshotProxy
import com.android.systemui.screenshot.ScreenshotProxyService
import javax.inject.Inject
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine
import kotlinx.coroutines.CompletableDeferred

private const val TAG = "SystemUiProxy"

/** An implementation of [SystemUiProxy] using [ScreenshotProxyService]. */
class SystemUiProxyClient @Inject constructor(@Application context: Context) : SystemUiProxy {
    @SuppressLint("ImplicitSamInstance")
    private val proxyConnector: ServiceConnector<IScreenshotProxy> =
        ServiceConnector.Impl(
            context,
            Intent(context, ScreenshotProxyService::class.java),
            Context.BIND_AUTO_CREATE or Context.BIND_WAIVE_PRIORITY or Context.BIND_NOT_VISIBLE,
            context.userId,
            IScreenshotProxy.Stub::asInterface
        )

    override suspend fun isNotificationShadeExpanded(): Boolean = suspendCoroutine { k ->
        proxyConnector
            .postForResult { it.isNotificationShadeExpanded }
            .whenComplete { expanded, error ->
                error?.also { Log.wtf(TAG, "isNotificationShadeExpanded", it) }
                k.resume(expanded ?: false)
            }
    }

    override suspend fun dismissKeyguard() {
        val completion = CompletableDeferred<Unit>()
        val onDoneBinder =
            object : IOnDoneCallback.Stub() {
                override fun onDone(success: Boolean) {
                    completion.complete(Unit)
                }
            }
        if (proxyConnector.run { it.dismissKeyguard(onDoneBinder) }) {
            completion.await()
        } else {
            Log.wtf(TAG, "Keyguard dismissal request failed")
        }
    }
}
+38 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.systemui.screenshot.proxy

import android.app.Service
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.screenshot.ScreenshotProxyService
import dagger.Binds
import dagger.Module
import dagger.multibindings.ClassKey
import dagger.multibindings.IntoMap

@Module
interface SystemUiProxyModule {

    @Binds
    @IntoMap
    @ClassKey(ScreenshotProxyService::class)
    fun bindScreenshotProxyService(service: ScreenshotProxyService): Service

    @Binds
    @SysUISingleton
    fun bindSystemUiProxy(systemUiProxyClient: SystemUiProxyClient): SystemUiProxy
}