Add system service for accessing SystemConfig

Add SystemConfigService and associated AIDLs and permissions for
accessing SystemConfig. The service returns values obtained from a
static instance of com.android.server.SystemConfig.

Bug: 143112379
Test: atest SystemConfigTest
Change-Id: I1a863ae9f53db21d698376008e5b1da83309b141
diff --git a/api/system-current.txt b/api/system-current.txt
index bd97a80..0583a41 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -153,6 +153,7 @@
     field public static final String PROVIDE_TRUST_AGENT = "android.permission.PROVIDE_TRUST_AGENT";
     field public static final String QUERY_TIME_ZONE_RULES = "android.permission.QUERY_TIME_ZONE_RULES";
     field public static final String READ_ACTIVE_EMERGENCY_SESSION = "android.permission.READ_ACTIVE_EMERGENCY_SESSION";
+    field public static final String READ_CARRIER_APP_INFO = "android.permission.READ_CARRIER_APP_INFO";
     field public static final String READ_CELL_BROADCASTS = "android.permission.READ_CELL_BROADCASTS";
     field public static final String READ_CONTENT_RATING_SYSTEMS = "android.permission.READ_CONTENT_RATING_SYSTEMS";
     field public static final String READ_DEVICE_CONFIG = "android.permission.READ_DEVICE_CONFIG";
@@ -1683,6 +1684,7 @@
     field public static final String SECURE_ELEMENT_SERVICE = "secure_element";
     field public static final String STATS_MANAGER = "stats";
     field public static final String STATUS_BAR_SERVICE = "statusbar";
+    field public static final String SYSTEM_CONFIG_SERVICE = "system_config";
     field public static final String SYSTEM_UPDATE_SERVICE = "system_update";
     field public static final String TELEPHONY_IMS_SERVICE = "telephony_ims";
     field public static final String TELEPHONY_REGISTRY_SERVICE = "telephony_registry";
@@ -7006,6 +7008,11 @@
     field public static final int TUPLE_VALUE_TYPE = 7; // 0x7
   }
 
+  public class SystemConfigManager {
+    method @NonNull @RequiresPermission(android.Manifest.permission.READ_CARRIER_APP_INFO) public java.util.Set<java.lang.String> getDisabledUntilUsedPreinstalledCarrierApps();
+    method @NonNull @RequiresPermission(android.Manifest.permission.READ_CARRIER_APP_INFO) public java.util.Map<java.lang.String,java.util.List<java.lang.String>> getDisabledUntilUsedPreinstalledCarrierAssociatedApps();
+  }
+
   public class SystemProperties {
     method @NonNull public static String get(@NonNull String);
     method @NonNull public static String get(@NonNull String, @Nullable String);
diff --git a/api/test-current.txt b/api/test-current.txt
index 7ba943c..5b1f183 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -2167,6 +2167,11 @@
     method public void log(android.os.StrictMode.ViolationInfo);
   }
 
+  public class SystemConfigManager {
+    method @NonNull @RequiresPermission("android.permission.READ_CARRIER_APP_INFO") public java.util.Set<java.lang.String> getDisabledUntilUsedPreinstalledCarrierApps();
+    method @NonNull @RequiresPermission("android.permission.READ_CARRIER_APP_INFO") public java.util.Map<java.lang.String,java.util.List<java.lang.String>> getDisabledUntilUsedPreinstalledCarrierAssociatedApps();
+  }
+
   public class SystemProperties {
     method @NonNull public static String get(@NonNull String);
     method @NonNull public static String get(@NonNull String, @Nullable String);
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index ca3d0d7..c9dc45f 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -147,6 +147,7 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.ServiceManager.ServiceNotFoundException;
+import android.os.SystemConfigManager;
 import android.os.SystemUpdateManager;
 import android.os.SystemVibrator;
 import android.os.UserHandle;
@@ -617,6 +618,13 @@
                         return new SystemUpdateManager(service);
                     }});
 
+        registerService(Context.SYSTEM_CONFIG_SERVICE, SystemConfigManager.class,
+                new CachedServiceFetcher<SystemConfigManager>() {
+                    @Override
+                    public SystemConfigManager createService(ContextImpl ctx) {
+                        return new SystemConfigManager();
+                    }});
+
         registerService(Context.TELEPHONY_REGISTRY_SERVICE, TelephonyRegistryManager.class,
             new CachedServiceFetcher<TelephonyRegistryManager>() {
                 @Override
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 4815d78..5657b16 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -4971,6 +4971,14 @@
 
     /**
      * Use with {@link #getSystemService(String)} to retrieve an
+     * {@link android.os.SystemConfigManager}.
+     * @hide
+     */
+    @SystemApi
+    public static final String SYSTEM_CONFIG_SERVICE = "system_config";
+
+    /**
+     * Use with {@link #getSystemService(String)} to retrieve an
      * {@link android.telephony.ims.RcsMessageManager}.
      * @hide
      */
diff --git a/core/java/android/os/ISystemConfig.aidl b/core/java/android/os/ISystemConfig.aidl
new file mode 100644
index 0000000..d3b0298
--- /dev/null
+++ b/core/java/android/os/ISystemConfig.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2020 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 android.os;
+
+/**
+  * Binder interface to query SystemConfig in the system server.
+  * {@hide}
+  */
+interface ISystemConfig {
+    /**
+     * @see SystemConfigManager#getDisabledUntilUsedPreinstalledCarrierApps
+     */
+    List<String> getDisabledUntilUsedPreinstalledCarrierApps();
+
+    /**
+     * @see SystemConfigManager#getDisabledUntilUsedPreinstalledCarrierAssociatedApps
+     */
+    Map getDisabledUntilUsedPreinstalledCarrierAssociatedApps();
+}
diff --git a/core/java/android/os/SystemConfigManager.java b/core/java/android/os/SystemConfigManager.java
new file mode 100644
index 0000000..3a9ce2f
--- /dev/null
+++ b/core/java/android/os/SystemConfigManager.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2020 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 android.os;
+
+import android.Manifest;
+import android.annotation.NonNull;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.annotation.SystemService;
+import android.annotation.TestApi;
+import android.content.Context;
+import android.util.ArraySet;
+import android.util.Log;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+
+/**
+ * Allows apps outside the system process to access various bits of configuration defined in
+ * /etc/sysconfig and its counterparts on OEM and vendor partitions.
+ *
+ * TODO: Intended for access by system mainline modules only. Marking as SystemApi until the
+ * module-only API surface is available.
+ * @hide
+ */
+@SystemApi
+@TestApi
+@SystemService(Context.SYSTEM_CONFIG_SERVICE)
+public class SystemConfigManager {
+    private static final String TAG = SystemConfigManager.class.getSimpleName();
+
+    private final ISystemConfig mInterface;
+
+    /** @hide **/
+    public SystemConfigManager() {
+        mInterface = ISystemConfig.Stub.asInterface(
+                ServiceManager.getService(Context.SYSTEM_CONFIG_SERVICE));
+    }
+
+    /**
+     * Returns a set of package names for carrier apps that are preinstalled on the device but
+     * should be disabled until the matching carrier's SIM is inserted into the device.
+     * @return A set of package names.
+     */
+    @RequiresPermission(Manifest.permission.READ_CARRIER_APP_INFO)
+    public @NonNull Set<String> getDisabledUntilUsedPreinstalledCarrierApps() {
+        try {
+            List<String> apps = mInterface.getDisabledUntilUsedPreinstalledCarrierApps();
+            return new ArraySet<>(apps);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Caught remote exception");
+            return Collections.emptySet();
+        }
+    }
+
+    /**
+     * Returns a map that describes helper apps associated with carrier apps that, like the apps
+     * returned by {@link #getDisabledUntilUsedPreinstalledCarrierApps()}, should be disabled until
+     * the correct SIM is inserted into the device.
+     * @return A map with keys corresponding to package names returned by
+     *         {@link #getDisabledUntilUsedPreinstalledCarrierApps()} and values as lists of package
+     *         names of helper apps.
+     */
+    @RequiresPermission(Manifest.permission.READ_CARRIER_APP_INFO)
+    public @NonNull Map<String, List<String>>
+            getDisabledUntilUsedPreinstalledCarrierAssociatedApps() {
+        try {
+            return (Map<String, List<String>>)
+                    mInterface.getDisabledUntilUsedPreinstalledCarrierAssociatedApps();
+        } catch (RemoteException e) {
+            Log.e(TAG, "Caught remote exception");
+            return Collections.emptyMap();
+        }
+    }
+}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 31faff6..d841460 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2229,6 +2229,14 @@
     <permission android:name="android.permission.BIND_EUICC_SERVICE"
                 android:protectionLevel="signature|telephony" />
 
+    <!-- Required for reading information about carrier apps from SystemConfigManager.
+         <p>Protection level: signature|telephony
+         @SystemApi
+         @hide
+    -->
+    <permission android:name="android.permission.READ_CARRIER_APP_INFO"
+        android:protectionLevel="signature|telephony" />
+
     <!-- ================================== -->
     <!-- Permissions for sdcard interaction -->
     <!-- ================================== -->
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index eb1d1ab..3b0f67c 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -153,6 +153,7 @@
         <permission name="android.permission.MODIFY_PHONE_STATE"/>
         <permission name="android.permission.PACKAGE_USAGE_STATS"/>
         <permission name="android.permission.PERFORM_CDMA_PROVISIONING"/>
+        <permission name="android.permission.READ_CARRIER_APP_INFO"/>
         <permission name="android.permission.READ_NETWORK_USAGE_HISTORY"/>
         <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
         <permission name="android.permission.READ_SEARCH_INDEXABLES"/>
@@ -309,6 +310,7 @@
         <!-- Needed for test only -->
         <permission name="android.permission.PACKET_KEEPALIVE_OFFLOAD" />
         <permission name="android.permission.POWER_SAVER" />
+        <permission name="android.permission.READ_CARRIER_APP_INFO"/>
         <permission name="android.permission.READ_FRAME_BUFFER"/>
         <permission name="android.permission.READ_LOWPAN_CREDENTIAL"/>
         <!-- Needed for test only -->
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 347d6c2..8a809f2 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -218,7 +218,10 @@
     <!-- Permission required for CTS test - UiModeManagerTest -->
     <uses-permission android:name="android.permission.ENTER_CAR_MODE_PRIORITIZED"/>
 
-      <!-- Permission required for CTS test - CarModeInCallServiceTest -->
+    <!-- Permission required for CTS test - SystemConfigTest -->
+    <uses-permission android:name="android.permission.READ_CARRIER_APP_INFO"/>
+
+    <!-- Permission required for CTS test - CarModeInCallServiceTest -->
     <uses-permission android:name="android.permission.CONTROL_INCALL_EXPERIENCE"/>
 
     <!-- Permission requried for CTS test - CellBroadcastIntentsTest -->
diff --git a/services/java/com/android/server/SystemConfigService.java b/services/java/com/android/server/SystemConfigService.java
new file mode 100644
index 0000000..e8ab101
--- /dev/null
+++ b/services/java/com/android/server/SystemConfigService.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2020 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.server;
+
+import android.Manifest;
+import android.content.Context;
+import android.os.ISystemConfig;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Service class that runs inside the system_server process to handle queries to
+ * {@link com.android.server.SystemConfig}.
+ * @hide
+ */
+public class SystemConfigService extends SystemService {
+    private final Context mContext;
+
+    private final ISystemConfig.Stub mInterface = new ISystemConfig.Stub() {
+        @Override
+        public List<String> getDisabledUntilUsedPreinstalledCarrierApps() {
+            mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_CARRIER_APP_INFO,
+                    "getDisabledUntilUsedPreInstalledCarrierApps requires READ_CARRIER_APP_INFO");
+            return new ArrayList<>(
+                    SystemConfig.getInstance().getDisabledUntilUsedPreinstalledCarrierApps());
+        }
+
+        @Override
+        public Map getDisabledUntilUsedPreinstalledCarrierAssociatedApps() {
+            mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_CARRIER_APP_INFO,
+                    "getDisabledUntilUsedPreInstalledCarrierAssociatedApps requires"
+                            + " READ_CARRIER_APP_INFO");
+            return SystemConfig.getInstance()
+                    .getDisabledUntilUsedPreinstalledCarrierAssociatedApps();
+        }
+    };
+
+    public SystemConfigService(Context context) {
+        super(context);
+        mContext = context;
+    }
+
+    @Override
+    public void onStart() {
+        publishBinderService(Context.SYSTEM_CONFIG_SERVICE, mInterface);
+    }
+}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index bfec51c..38e1561 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -887,6 +887,11 @@
     private void startCoreServices(@NonNull TimingsTraceAndSlog t) {
         t.traceBegin("startCoreServices");
 
+        // Service for system config
+        t.traceBegin("StartSystemConfigService");
+        mSystemServiceManager.startService(SystemConfigService.class);
+        t.traceEnd();
+
         t.traceBegin("StartBatteryService");
         // Tracks the battery level.  Requires LightService.
         mSystemServiceManager.startService(BatteryService.class);