SimpleDeviceConfig: Add initial implementation
This is a simple app that provisions the DeviceConfig settings namespace
on boot with values defined in a resource overlay. It is meant to be
delegated as the device configurator in the framework config
(config_deviceConfiguratorPackageName) to make sure it receives the
correct permissions.
This can be useful for e.g. configuring proprietary Google services
without delegating GMS as the device configurator to prevent it from
overriding custom default settings, or minimizing changes to core
framework code by making changes in DeviceConfig instead as intended by
Google.
diff --git a/Android.bp b/Android.bp
new file mode 100644
index 0000000..7f66b30
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1,23 @@
+// Copyright (C) 2020 The Proton AOSP 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.
+
+android_app {
+ name: "SimpleDeviceConfig",
+ srcs: ["src/**/*.java"],
+ resource_dirs: ["res"],
+ platform_apis: true,
+ certificate: "platform",
+ privileged: true,
+ manifest: "AndroidManifest.xml",
+}
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
new file mode 100644
index 0000000..b97ffbe
--- /dev/null
+++ b/AndroidManifest.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2020 The Proton AOSP 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="org.protonaosp.deviceconfig">
+
+ <uses-permission android:name="android.permission.READ_DEVICE_CONFIG" />
+ <uses-permission android:name="android.permission.WRITE_DEVICE_CONFIG" />
+ <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
+
+ <application
+ android:label="@string/app_name"
+ android:allowBackup="false"
+ android:requiredForAllUsers="true"
+ android:supportsRtl="true">
+
+ <receiver android:name=".BootReceiver"
+ android:directBootAware="true">
+ <intent-filter>
+ <action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
+ </intent-filter>
+ </receiver>
+
+ </application>
+
+</manifest>
diff --git a/res/values/config.xml b/res/values/config.xml
new file mode 100644
index 0000000..cc02141
--- /dev/null
+++ b/res/values/config.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2020 The Proton AOSP 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.
+-->
+<resources>
+ <string-array name="device_config" />
+</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
new file mode 100644
index 0000000..97b1efe
--- /dev/null
+++ b/res/values/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2020 The Proton AOSP 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.
+-->
+<resources>
+ <string name="app_name">Simple Device Configuration</string>
+</resources>
diff --git a/src/org/protonaosp/deviceconfig/BootReceiver.java b/src/org/protonaosp/deviceconfig/BootReceiver.java
new file mode 100644
index 0000000..a0c01c5
--- /dev/null
+++ b/src/org/protonaosp/deviceconfig/BootReceiver.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2007 The Proton AOSP 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 org.protonaosp.deviceconfig;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.provider.DeviceConfig;
+import android.util.Log;
+
+public class BootReceiver extends BroadcastReceiver {
+ private static final String TAG = "SimpleDeviceConfig";
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ new Thread(() -> {
+ Log.i(TAG, "Updating device config at boot");
+ updateConfig(context);
+ }).start();
+ }
+
+ private void updateConfig(Context context) {
+ // Set current properties
+ String[] rawProperties = context.getResources().getStringArray(R.array.device_config);
+ for (String property : rawProperties) {
+ String[] kv = property.split("=");
+ String fullKey = kv[0];
+ String[] nk = fullKey.split("/");
+
+ String namespace = nk[0];
+ String key = nk[1];
+ String value = kv[1];
+
+ DeviceConfig.setProperty(namespace, key, value, true);
+ }
+ }
+}