1 /*
2  * Copyright (C) 2020 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.server.wifi;
18 
19 import android.content.Context;
20 import android.database.ContentObserver;
21 import android.net.Uri;
22 import android.os.Handler;
23 import android.provider.Settings;
24 import android.util.Log;
25 
26 import com.android.internal.annotations.VisibleForTesting;
27 
28 import java.io.FileDescriptor;
29 import java.io.PrintWriter;
30 
31 /**
32  * Observer for adaptive connectivity enable settings changes.
33  * This is enabled by default. Will be toggled off via adb command or a settings
34  * toggle by the user to disable adaptive connectivity.
35  */
36 public class AdaptiveConnectivityEnabledSettingObserver {
37 
38     private static final String TAG = "WifiAdaptConnObserver";
39     /**
40      * Copy of the settings string. Can't directly use the constant because it is @hide.
41      * See {@link Settings.Secure#ADAPTIVE_CONNECTIVITY_ENABLED}.
42      * TODO(b/167709538): remove this hardcoded string and create new API in Wifi mainline.
43      */
44     @VisibleForTesting
45     public static final String SETTINGS_SECURE_ADAPTIVE_CONNECTIVITY_ENABLED =
46             "adaptive_connectivity_enabled";
47 
48     private final WifiMetrics mWifiMetrics;
49     private final FrameworkFacade mFrameworkFacade;
50     private final Context mContext;
51 
52     private final ContentObserver mContentObserver;
53 
54     private boolean mAdaptiveConnectivityEnabled = true;
55 
AdaptiveConnectivityEnabledSettingObserver(Handler handler, WifiMetrics wifiMetrics, FrameworkFacade frameworkFacade, Context context)56     public AdaptiveConnectivityEnabledSettingObserver(Handler handler,
57             WifiMetrics wifiMetrics, FrameworkFacade frameworkFacade,
58             Context context) {
59         mWifiMetrics = wifiMetrics;
60         mFrameworkFacade = frameworkFacade;
61         mContext = context;
62         mContentObserver = new ContentObserver(handler) {
63             @Override
64             public void onChange(boolean selfChange) {
65                 handleChange();
66             }
67         };
68     }
69 
handleChange()70     private void handleChange() {
71         mAdaptiveConnectivityEnabled = readValueFromSettings();
72         Log.d(TAG, "Adaptive connectivity status changed: " + mAdaptiveConnectivityEnabled);
73         mWifiMetrics.setAdaptiveConnectivityState(mAdaptiveConnectivityEnabled);
74         mWifiMetrics.logUserActionEvent(
75                 WifiMetrics.convertAdaptiveConnectivityStateToUserActionEventType(
76                         mAdaptiveConnectivityEnabled));
77     }
78 
79     /** Register settings change observer. */
initialize()80     public void initialize() {
81         Uri uri = Settings.Secure.getUriFor(SETTINGS_SECURE_ADAPTIVE_CONNECTIVITY_ENABLED);
82         if (uri == null) {
83             Log.e(TAG, "Adaptive connectivity user toggle does not exist in Settings");
84             return;
85         }
86         mFrameworkFacade.registerContentObserver(
87                 mContext, uri, true, mContentObserver);
88         mAdaptiveConnectivityEnabled = readValueFromSettings();
89         Log.d(TAG, "Adaptive connectivity status initialized to: " + mAdaptiveConnectivityEnabled);
90         mWifiMetrics.setAdaptiveConnectivityState(mAdaptiveConnectivityEnabled);
91     }
92 
readValueFromSettings()93     private boolean readValueFromSettings() {
94         return mFrameworkFacade.getSecureIntegerSetting(
95                 mContext, SETTINGS_SECURE_ADAPTIVE_CONNECTIVITY_ENABLED, 1) == 1;
96     }
97 
98     /** True if adaptive connectivity is enabled, false otherwise. */
get()99     public boolean get() {
100         return mAdaptiveConnectivityEnabled;
101     }
102 
103     /** Dump method for debugging */
dump(FileDescriptor fd, PrintWriter pw, String[] args)104     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
105         pw.println("Dump of AdaptiveConnectivityEnabledSettingObserver");
106         pw.println("mAdaptiveConnectivityEnabled=" + mAdaptiveConnectivityEnabled);
107     }
108 }
109