Skip to content

Commit

Permalink
Implement DeviceConfigUtils and service
Browse files Browse the repository at this point in the history
- Allow overriding device configs while using GMS as device configurator package

Change-Id: Ie7327610feca7a390915511088dfef831c946853
  • Loading branch information
jhenrique09 authored and basamaryan committed Aug 10, 2023
1 parent be4b12b commit f62826a
Show file tree
Hide file tree
Showing 7 changed files with 163 additions and 3 deletions.
19 changes: 17 additions & 2 deletions core/java/android/provider/DeviceConfig.java
Expand Up @@ -48,6 +48,8 @@
import java.util.Set;
import java.util.concurrent.Executor;

import com.android.internal.util.custom.DeviceConfigUtils;

/**
* Device level configuration parameters which can be tuned by a separate configuration service.
* Namespaces that end in "_native" such as {@link #NAMESPACE_NETD_NATIVE} are intended to be used
Expand Down Expand Up @@ -954,6 +956,9 @@ public static float getFloat(@NonNull String namespace, @NonNull String name,
@RequiresPermission(WRITE_DEVICE_CONFIG)
public static boolean setProperty(@NonNull String namespace, @NonNull String name,
@Nullable String value, boolean makeDefault) {
if (DeviceConfigUtils.shouldDenyDeviceConfigControl(namespace, name)){
return true;
}
ContentResolver contentResolver = ActivityThread.currentApplication().getContentResolver();
return Settings.Config.putString(contentResolver, namespace, name, value, makeDefault);
}
Expand All @@ -976,9 +981,15 @@ public static boolean setProperty(@NonNull String namespace, @NonNull String nam
@SystemApi
@RequiresPermission(WRITE_DEVICE_CONFIG)
public static boolean setProperties(@NonNull Properties properties) throws BadConfigException {
Map<String, String> keyValuesFiltered =
DeviceConfigUtils.filterDeviceConfigs(properties.getNamespace(), properties.mMap);
if (keyValuesFiltered.size() == 0){
return true;
}
ContentResolver contentResolver = ActivityThread.currentApplication().getContentResolver();
return Settings.Config.setStrings(contentResolver, properties.getNamespace(),
properties.mMap);
boolean result = Settings.Config.setStrings(contentResolver, properties.getNamespace(),
keyValuesFiltered);
return result;
}

/**
Expand All @@ -993,6 +1004,9 @@ public static boolean setProperties(@NonNull Properties properties) throws BadCo
@SystemApi
@RequiresPermission(WRITE_DEVICE_CONFIG)
public static boolean deleteProperty(@NonNull String namespace, @NonNull String name) {
if (DeviceConfigUtils.shouldDenyDeviceConfigControl(namespace, name)){
return true;
}
ContentResolver contentResolver = ActivityThread.currentApplication().getContentResolver();
return Settings.Config.deleteString(contentResolver, namespace, name);
}
Expand Down Expand Up @@ -1027,6 +1041,7 @@ public static boolean deleteProperty(@NonNull String namespace, @NonNull String
public static void resetToDefaults(@ResetMode int resetMode, @Nullable String namespace) {
ContentResolver contentResolver = ActivityThread.currentApplication().getContentResolver();
Settings.Config.resetToDefaults(contentResolver, resetMode, namespace);
DeviceConfigUtils.setDefaultProperties(contentResolver);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion core/java/android/provider/Settings.java
Expand Up @@ -18384,7 +18384,7 @@ public static Map<String, String> getStrings(@NonNull ContentResolver resolver,
* @hide
*/
@RequiresPermission(Manifest.permission.WRITE_DEVICE_CONFIG)
static boolean putString(@NonNull ContentResolver resolver, @NonNull String namespace,
public static boolean putString(@NonNull ContentResolver resolver, @NonNull String namespace,
@NonNull String name, @Nullable String value, boolean makeDefault) {
return sNameValueCache.putStringForUser(resolver, createCompositeName(namespace, name),
value, null, makeDefault, resolver.getUserId(),
Expand Down
97 changes: 97 additions & 0 deletions core/java/com/android/internal/util/custom/DeviceConfigUtils.java
@@ -0,0 +1,97 @@
/*
* Copyright (C) 2023 The Pixel Experience 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.internal.util.custom;

import android.content.ContentResolver;
import android.content.res.Resources;
import android.provider.Settings;
import android.util.Log;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import com.android.internal.util.ArrayUtils;

public class DeviceConfigUtils {

private static final String TAG = DeviceConfigUtils.class.getSimpleName();

private static String[] getDeviceConfigsOverride(){
String[] globalDeviceConfigs =
Resources.getSystem().getStringArray(com.android.internal.R.array.global_device_configs_override);
String[] deviceConfigs =
Resources.getSystem().getStringArray(com.android.internal.R.array.device_configs_override);
String[] allDeviceConfigs = Arrays.copyOf(globalDeviceConfigs, globalDeviceConfigs.length + deviceConfigs.length);
System.arraycopy(deviceConfigs, 0, allDeviceConfigs, globalDeviceConfigs.length, deviceConfigs.length);
return allDeviceConfigs;
}

public static boolean shouldDenyDeviceConfigControl(String namespace, String property) {
Log.d(TAG, "shouldAllowDeviceConfigControl, namespace=" + namespace + ", property=" + property);
for (String p : getDeviceConfigsOverride()) {
String[] kv = p.split("=");
String fullKey = kv[0];
String[] nsKey = fullKey.split("/");
if (nsKey[0] == namespace && nsKey[1] == property){
Log.d(TAG, "shouldAllowDeviceConfigControl, deny, namespace=" + namespace + ", property=" + property);
return true;
}
}
Log.d(TAG, "shouldAllowDeviceConfigControl, allow, namespace=" + namespace + ", property=" + property);
return false;
}

public static Map<String, String> filterDeviceConfigs(String namespace, Map<String, String> keyValues) {
Log.d(TAG, "shouldAllowDeviceConfigControl, namespace=" + namespace + ", properties=[" + String.join(",", keyValues.keySet()) + "]");
Map<String, String> keyValuesNew = new HashMap();
for (Map.Entry<String, String> entry : keyValues.entrySet()) {
keyValuesNew.put(entry.getKey(), entry.getValue());
}
for (String p : getDeviceConfigsOverride()) {
String[] kv = p.split("=");
String fullKey = kv[0];
String[] nsKey = fullKey.split("/");
if (nsKey[0] == namespace){
String key = nsKey[1];
String value = "";
if (kv.length > 1) {
value = kv[1];
}
keyValuesNew.put(key, value);
}
}
return keyValuesNew;
}

public static void setDefaultProperties(ContentResolver contentResolver) {
Log.d(TAG, "setDefaultProperties");
for (String p : getDeviceConfigsOverride()) {
String[] kv = p.split("=");
String fullKey = kv[0];
String[] nsKey = fullKey.split("/");

String namespace = nsKey[0];
String key = nsKey[1];
String value = "";
if (kv.length > 1) {
value = kv[1];
}
Settings.Config.putString(contentResolver, namespace, key, value, false);
}
}
}
5 changes: 5 additions & 0 deletions core/res/res/values/custom_config.xml
Expand Up @@ -138,4 +138,9 @@
<string name="config_pocketJudgeVendorSensorName"></string>
<string name="config_pocketJudgeVendorProximitySensorName"></string>

<!-- Define device configs on boot -->
<string-array name="global_device_configs_override" translatable="false">
</string-array>
<string-array name="device_configs_override" translatable="false">
</string-array>
</resources>
3 changes: 3 additions & 0 deletions core/res/res/values/custom_symbols.xml
Expand Up @@ -160,4 +160,7 @@
<java-symbol type="string" name="config_pocketJudgeVendorSensorName" />
<java-symbol type="string" name="config_pocketJudgeVendorProximitySensorName" />

<!-- Define device configs on boot -->
<java-symbol type="array" name="global_device_configs_override" />
<java-symbol type="array" name="device_configs_override" />
</resources>
@@ -0,0 +1,34 @@
/*
* Copyright (C) 2023 The PixelExperience Project
* SPDX-License-Identifier: Apache-2.0
*/

package com.android.server.custom;

import android.content.Context;
import com.android.server.SystemService;

import com.android.internal.util.custom.DeviceConfigUtils;

public class CustomDeviceConfigService extends SystemService {

private static final String TAG = "CustomDeviceConfigService";

private final Context mContext;

public CustomDeviceConfigService(Context context) {
super(context);
mContext = context;
}

@Override
public void onStart() {
}

@Override
public void onBootPhase(int phase) {
if (phase == PHASE_BOOT_COMPLETED) {
DeviceConfigUtils.setDefaultProperties(mContext.getContentResolver());
}
}
}
6 changes: 6 additions & 0 deletions services/java/com/android/server/SystemServer.java
Expand Up @@ -211,6 +211,7 @@
import com.android.server.uri.UriGrantsManagerService;
import com.android.server.usage.UsageStatsService;
import com.android.server.utils.TimingsTraceAndSlog;
import com.android.server.custom.CustomDeviceConfigService;
import com.android.server.vibrator.VibratorManagerService;
import com.android.server.vr.VrManagerService;
import com.android.server.webkit.WebViewUpdateService;
Expand Down Expand Up @@ -2538,6 +2539,11 @@ private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
mSystemServiceManager.startService(MediaMetricsManagerService.class);
t.traceEnd();

// CustomDeviceConfigService
t.traceBegin("StartCustomDeviceConfigService");
mSystemServiceManager.startService(CustomDeviceConfigService.class);
t.traceEnd();

// LineageHardware
if (!mOnlyCore){
t.traceBegin("StartLineageHardwareService");
Expand Down

0 comments on commit f62826a

Please sign in to comment.