1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.net.module.util;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.content.ContentResolver;
22 import android.content.Context;
23 import android.provider.Settings;
24 import android.text.TextUtils;
25 
26 /**
27  * Collection of connectivity settings utilities.
28  *
29  * @hide
30  */
31 public class ConnectivitySettingsUtils {
32     public static final int PRIVATE_DNS_MODE_OFF = 1;
33     public static final int PRIVATE_DNS_MODE_OPPORTUNISTIC = 2;
34     public static final int PRIVATE_DNS_MODE_PROVIDER_HOSTNAME = 3;
35 
36     public static final String PRIVATE_DNS_DEFAULT_MODE = "private_dns_default_mode";
37     public static final String PRIVATE_DNS_MODE = "private_dns_mode";
38     public static final String PRIVATE_DNS_MODE_OFF_STRING = "off";
39     public static final String PRIVATE_DNS_MODE_OPPORTUNISTIC_STRING = "opportunistic";
40     public static final String PRIVATE_DNS_MODE_PROVIDER_HOSTNAME_STRING = "hostname";
41     public static final String PRIVATE_DNS_SPECIFIER = "private_dns_specifier";
42 
43     /**
44      * Get private DNS mode as string.
45      *
46      * @param mode One of the private DNS values.
47      * @return A string of private DNS mode.
48      */
getPrivateDnsModeAsString(int mode)49     public static String getPrivateDnsModeAsString(int mode) {
50         switch (mode) {
51             case PRIVATE_DNS_MODE_OFF:
52                 return PRIVATE_DNS_MODE_OFF_STRING;
53             case PRIVATE_DNS_MODE_OPPORTUNISTIC:
54                 return PRIVATE_DNS_MODE_OPPORTUNISTIC_STRING;
55             case PRIVATE_DNS_MODE_PROVIDER_HOSTNAME:
56                 return PRIVATE_DNS_MODE_PROVIDER_HOSTNAME_STRING;
57             default:
58                 throw new IllegalArgumentException("Invalid private dns mode: " + mode);
59         }
60     }
61 
getPrivateDnsModeAsInt(String mode)62     private static int getPrivateDnsModeAsInt(String mode) {
63         switch (mode) {
64             case "off":
65                 return PRIVATE_DNS_MODE_OFF;
66             case "hostname":
67                 return PRIVATE_DNS_MODE_PROVIDER_HOSTNAME;
68             case "opportunistic":
69                 return PRIVATE_DNS_MODE_OPPORTUNISTIC;
70             default:
71                 throw new IllegalArgumentException("Invalid private dns mode: " + mode);
72         }
73     }
74 
75     /**
76      * Get private DNS mode from settings.
77      *
78      * @param context The Context to query the private DNS mode from settings.
79      * @return An integer of private DNS mode.
80      */
getPrivateDnsMode(@onNull Context context)81     public static int getPrivateDnsMode(@NonNull Context context) {
82         final ContentResolver cr = context.getContentResolver();
83         String mode = Settings.Global.getString(cr, PRIVATE_DNS_MODE);
84         if (TextUtils.isEmpty(mode)) mode = Settings.Global.getString(cr, PRIVATE_DNS_DEFAULT_MODE);
85         // If both PRIVATE_DNS_MODE and PRIVATE_DNS_DEFAULT_MODE are not set, choose
86         // PRIVATE_DNS_MODE_OPPORTUNISTIC as default mode.
87         if (TextUtils.isEmpty(mode)) return PRIVATE_DNS_MODE_OPPORTUNISTIC;
88         return getPrivateDnsModeAsInt(mode);
89     }
90 
91     /**
92      * Set private DNS mode to settings.
93      *
94      * @param context The {@link Context} to set the private DNS mode.
95      * @param mode The private dns mode. This should be one of the PRIVATE_DNS_MODE_* constants.
96      */
setPrivateDnsMode(@onNull Context context, int mode)97     public static void setPrivateDnsMode(@NonNull Context context, int mode) {
98         if (!(mode == PRIVATE_DNS_MODE_OFF
99                 || mode == PRIVATE_DNS_MODE_OPPORTUNISTIC
100                 || mode == PRIVATE_DNS_MODE_PROVIDER_HOSTNAME)) {
101             throw new IllegalArgumentException("Invalid private dns mode: " + mode);
102         }
103         Settings.Global.putString(context.getContentResolver(), PRIVATE_DNS_MODE,
104                 getPrivateDnsModeAsString(mode));
105     }
106 
107     /**
108      * Get specific private dns provider name from {@link Settings}.
109      *
110      * @param context The {@link Context} to query the setting.
111      * @return The specific private dns provider name, or null if no setting value.
112      */
113     @Nullable
getPrivateDnsHostname(@onNull Context context)114     public static String getPrivateDnsHostname(@NonNull Context context) {
115         return Settings.Global.getString(context.getContentResolver(), PRIVATE_DNS_SPECIFIER);
116     }
117 
118     /**
119      * Set specific private dns provider name to {@link Settings}.
120      *
121      * @param context The {@link Context} to set the setting.
122      * @param specifier The specific private dns provider name.
123      */
setPrivateDnsHostname(@onNull Context context, @Nullable String specifier)124     public static void setPrivateDnsHostname(@NonNull Context context, @Nullable String specifier) {
125         Settings.Global.putString(context.getContentResolver(), PRIVATE_DNS_SPECIFIER, specifier);
126     }
127 }
128