Skip to content

Commit 123692b

Browse files
authored
FACS: Control settings for Google apps (#3053)
1 parent 2efe8e3 commit 123692b

File tree

4 files changed

+104
-7
lines changed

4 files changed

+104
-7
lines changed

play-services-api/src/main/java/com/google/android/gms/facs/cache/GetActivityControlsSettingsResult.java

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,29 @@
55

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

8-
import org.microg.safeparcel.AutoSafeParcelable;
8+
import android.os.Parcel;
99

10-
public class GetActivityControlsSettingsResult extends AutoSafeParcelable {
10+
import androidx.annotation.NonNull;
11+
12+
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
13+
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
14+
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
15+
16+
@SafeParcelable.Class
17+
public class GetActivityControlsSettingsResult extends AbstractSafeParcelable {
18+
@Field(value = 1)
19+
public byte[] bytes;
20+
21+
@Constructor
22+
public GetActivityControlsSettingsResult(@Param(1) byte[] data) {
23+
this.bytes = data;
24+
}
25+
26+
@Override
27+
public void writeToParcel(@NonNull Parcel dest, int flags) {
28+
CREATOR.writeToParcel(this, dest, flags);
29+
}
30+
31+
public static final SafeParcelableCreatorAndWriter<GetActivityControlsSettingsResult> CREATOR = findCreator(GetActivityControlsSettingsResult.class);
1132

12-
public static final Creator<GetActivityControlsSettingsResult> CREATOR = new AutoCreator<>(GetActivityControlsSettingsResult.class);
1333
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2025 microG Project Team
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
option java_outer_classname = "ControlsSettings";
7+
8+
option java_package = "org.microg.gms.udc";
9+
option java_multiple_files = true;
10+
11+
message ActivityControlsSettings {
12+
repeated ActivityControlItem items = 1;
13+
optional GlobalSettings global = 2;
14+
}
15+
16+
message ActivityControlItem {
17+
optional int32 id = 1;
18+
optional int32 enabled = 2;
19+
optional int32 allowed = 3;
20+
optional int32 forced = 4;
21+
}
22+
23+
message GlobalSettings {
24+
optional int32 enabled = 1;
25+
optional int32 allowed = 2;
26+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/**
2+
* SPDX-FileCopyrightText: 2025 microG Project Team
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package org.microg.gms.udc
7+
8+
private enum class Controls(val id: Int) {
9+
APP_USAGE_TIME(1),
10+
SCREEN_TIME_LIMIT(2),
11+
APP_INSTALL(3),
12+
IN_APP_PURCHASE(4),
13+
LOCATION_SHARING(5),
14+
CALL_LOG(6),
15+
CONTACT(9),
16+
CALENDAR(10),
17+
CAMERA(15),
18+
MICROPHONE(17),
19+
STORAGE(18),
20+
NOTIFICATION(44),
21+
ACCESSIBILITY_SERVICE(45),
22+
DEVICE_ADMIN(46),
23+
SYSTEM_WINDOW_OVERLAY(48),
24+
SYSTEM_ALERT_WINDOW(61),
25+
FLOATING_WINDOW(80),
26+
PICTURE_IN_PICTURE(94),
27+
SYSTEM_UI_VISIBILITY(95),
28+
BACKGROUND_APP_RESTRICTION(101),
29+
BATTERY_OPTIMIZATION(102)
30+
}
31+
32+
private val ALLOW_CONTROLS_PACKAGES = mapOf(
33+
Pair("com.google.android.googlequicksearchbox", setOf(Controls.STORAGE, Controls.MICROPHONE, Controls.SYSTEM_WINDOW_OVERLAY)),
34+
)
35+
36+
fun getAllowControlsByPackage(packageName: String) : ByteArray? {
37+
val controls = ALLOW_CONTROLS_PACKAGES[packageName] ?: return null
38+
return ActivityControlsSettings.build {
39+
items(controls.map { controls -> ActivityControlItem(controls.id, 1, 1, 1) })
40+
global(GlobalSettings(1, 1))
41+
}.encode()
42+
}

play-services-core/src/main/kotlin/org/microg/gms/udc/FacsCacheService.kt

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,34 @@
55

66
package org.microg.gms.udc
77

8+
import android.content.Context
89
import android.os.Parcel
910
import android.util.Log
1011
import com.google.android.gms.common.api.Status
1112
import com.google.android.gms.common.internal.GetServiceRequest
1213
import com.google.android.gms.common.internal.IGmsCallbacks
1314
import com.google.android.gms.facs.cache.FacsCacheCallOptions
15+
import com.google.android.gms.facs.cache.GetActivityControlsSettingsResult
1416
import com.google.android.gms.facs.cache.internal.IFacsCacheCallbacks
1517
import com.google.android.gms.facs.cache.internal.IFacsCacheService
1618
import org.microg.gms.BaseService
1719
import org.microg.gms.common.GmsService
20+
import org.microg.gms.common.PackageUtils
1821
import org.microg.gms.utils.warnOnTransactionIssues
1922

2023
private const val TAG = "GmsFacsCache"
2124

2225
class FacsCacheService : BaseService(TAG, GmsService.FACS_CACHE) {
2326
override fun handleServiceRequest(callback: IGmsCallbacks, request: GetServiceRequest?, service: GmsService?) {
24-
callback.onPostInitComplete(0, FacsCacheServiceImpl().asBinder(), null)
27+
Log.d(TAG, "handleServiceRequest request=${request} ")
28+
val packageName = PackageUtils.getAndCheckCallingPackage(this, request?.packageName)
29+
?: throw IllegalArgumentException("Missing package name")
30+
callback.onPostInitComplete(0, FacsCacheServiceImpl(this, packageName).asBinder(), null)
2531
}
2632
}
2733

28-
class FacsCacheServiceImpl : IFacsCacheService.Stub() {
34+
class FacsCacheServiceImpl(val context: Context, val packageName: String) : IFacsCacheService.Stub() {
35+
2936
override fun forceSettingsCacheRefresh(callbacks: IFacsCacheCallbacks, options: FacsCacheCallOptions) {
3037
Log.d(TAG, "forceSettingsCacheRefresh")
3138
callbacks.onForceSettingsCacheRefreshResult(Status.CANCELED, null)
@@ -37,8 +44,10 @@ class FacsCacheServiceImpl : IFacsCacheService.Stub() {
3744
}
3845

3946
override fun getActivityControlsSettings(callbacks: IFacsCacheCallbacks, options: FacsCacheCallOptions) {
40-
Log.d(TAG, "getActivityControlsSettings")
41-
callbacks.onGetActivityControlsSettingsResult(Status.CANCELED, null)
47+
Log.d(TAG, "getActivityControlsSettings requestPackageName: $packageName, options: $options")
48+
getAllowControlsByPackage(packageName)?.let {
49+
callbacks.onGetActivityControlsSettingsResult(Status.SUCCESS, GetActivityControlsSettingsResult(it))
50+
} ?: callbacks.onGetActivityControlsSettingsResult(Status.CANCELED, null)
4251
}
4352

4453
override fun readDeviceLevelSettings(callbacks: IFacsCacheCallbacks) {

0 commit comments

Comments
 (0)