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

Unverified Commit 123692b6 authored by DaVinci9196's avatar DaVinci9196 Committed by GitHub
Browse files

FACS: Control settings for Google apps (#3053)

parent 2efe8e34
Loading
Loading
Loading
Loading
+23 −3
Original line number Diff line number Diff line
@@ -5,9 +5,29 @@

package com.google.android.gms.facs.cache;

import org.microg.safeparcel.AutoSafeParcelable;
import android.os.Parcel;

public class GetActivityControlsSettingsResult extends AutoSafeParcelable {
import androidx.annotation.NonNull;

import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;

@SafeParcelable.Class
public class GetActivityControlsSettingsResult extends AbstractSafeParcelable {
    @Field(value = 1)
    public byte[] bytes;

    @Constructor
    public GetActivityControlsSettingsResult(@Param(1) byte[] data) {
        this.bytes = data;
    }

    @Override
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        CREATOR.writeToParcel(this, dest, flags);
    }

    public static final SafeParcelableCreatorAndWriter<GetActivityControlsSettingsResult> CREATOR = findCreator(GetActivityControlsSettingsResult.class);

    public static final Creator<GetActivityControlsSettingsResult> CREATOR = new AutoCreator<>(GetActivityControlsSettingsResult.class);
}
+26 −0
Original line number Diff line number Diff line
/*
 * SPDX-FileCopyrightText: 2025 microG Project Team
 * SPDX-License-Identifier: Apache-2.0
 */

option java_outer_classname = "ControlsSettings";

option java_package = "org.microg.gms.udc";
option java_multiple_files = true;

message ActivityControlsSettings {
    repeated ActivityControlItem items = 1;
    optional GlobalSettings global = 2;
}

message ActivityControlItem {
    optional int32 id = 1;
    optional int32 enabled = 2;
    optional int32 allowed = 3;
    optional int32 forced = 4;
}

message GlobalSettings {
    optional int32 enabled = 1;
    optional int32 allowed = 2;
}
 No newline at end of file
+42 −0
Original line number Diff line number Diff line
/**
 * SPDX-FileCopyrightText: 2025 microG Project Team
 * SPDX-License-Identifier: Apache-2.0
 */

package org.microg.gms.udc

private enum class Controls(val id: Int) {
    APP_USAGE_TIME(1),
    SCREEN_TIME_LIMIT(2),
    APP_INSTALL(3),
    IN_APP_PURCHASE(4),
    LOCATION_SHARING(5),
    CALL_LOG(6),
    CONTACT(9),
    CALENDAR(10),
    CAMERA(15),
    MICROPHONE(17),
    STORAGE(18),
    NOTIFICATION(44),
    ACCESSIBILITY_SERVICE(45),
    DEVICE_ADMIN(46),
    SYSTEM_WINDOW_OVERLAY(48),
    SYSTEM_ALERT_WINDOW(61),
    FLOATING_WINDOW(80),
    PICTURE_IN_PICTURE(94),
    SYSTEM_UI_VISIBILITY(95),
    BACKGROUND_APP_RESTRICTION(101),
    BATTERY_OPTIMIZATION(102)
}

private val ALLOW_CONTROLS_PACKAGES = mapOf(
    Pair("com.google.android.googlequicksearchbox", setOf(Controls.STORAGE, Controls.MICROPHONE, Controls.SYSTEM_WINDOW_OVERLAY)),
)

fun getAllowControlsByPackage(packageName: String) : ByteArray? {
    val controls = ALLOW_CONTROLS_PACKAGES[packageName] ?: return null
    return ActivityControlsSettings.build {
        items(controls.map { controls -> ActivityControlItem(controls.id, 1, 1, 1) })
        global(GlobalSettings(1, 1))
    }.encode()
}
+13 −4
Original line number Diff line number Diff line
@@ -5,27 +5,34 @@

package org.microg.gms.udc

import android.content.Context
import android.os.Parcel
import android.util.Log
import com.google.android.gms.common.api.Status
import com.google.android.gms.common.internal.GetServiceRequest
import com.google.android.gms.common.internal.IGmsCallbacks
import com.google.android.gms.facs.cache.FacsCacheCallOptions
import com.google.android.gms.facs.cache.GetActivityControlsSettingsResult
import com.google.android.gms.facs.cache.internal.IFacsCacheCallbacks
import com.google.android.gms.facs.cache.internal.IFacsCacheService
import org.microg.gms.BaseService
import org.microg.gms.common.GmsService
import org.microg.gms.common.PackageUtils
import org.microg.gms.utils.warnOnTransactionIssues

private const val TAG = "GmsFacsCache"

class FacsCacheService : BaseService(TAG, GmsService.FACS_CACHE) {
    override fun handleServiceRequest(callback: IGmsCallbacks, request: GetServiceRequest?, service: GmsService?) {
        callback.onPostInitComplete(0, FacsCacheServiceImpl().asBinder(), null)
        Log.d(TAG, "handleServiceRequest request=${request} ")
        val packageName = PackageUtils.getAndCheckCallingPackage(this, request?.packageName)
            ?: throw IllegalArgumentException("Missing package name")
        callback.onPostInitComplete(0, FacsCacheServiceImpl(this, packageName).asBinder(), null)
    }
}

class FacsCacheServiceImpl : IFacsCacheService.Stub() {
class FacsCacheServiceImpl(val context: Context, val packageName: String) : IFacsCacheService.Stub() {

    override fun forceSettingsCacheRefresh(callbacks: IFacsCacheCallbacks, options: FacsCacheCallOptions) {
        Log.d(TAG, "forceSettingsCacheRefresh")
        callbacks.onForceSettingsCacheRefreshResult(Status.CANCELED, null)
@@ -37,8 +44,10 @@ class FacsCacheServiceImpl : IFacsCacheService.Stub() {
    }

    override fun getActivityControlsSettings(callbacks: IFacsCacheCallbacks, options: FacsCacheCallOptions) {
        Log.d(TAG, "getActivityControlsSettings")
        callbacks.onGetActivityControlsSettingsResult(Status.CANCELED, null)
        Log.d(TAG, "getActivityControlsSettings requestPackageName: $packageName, options: $options")
        getAllowControlsByPackage(packageName)?.let {
            callbacks.onGetActivityControlsSettingsResult(Status.SUCCESS, GetActivityControlsSettingsResult(it))
        } ?: callbacks.onGetActivityControlsSettingsResult(Status.CANCELED, null)
    }

    override fun readDeviceLevelSettings(callbacks: IFacsCacheCallbacks) {