blob: b9171ac4e7635cc5140f5b95916609528c0fdfd4 [file] [log] [blame]
Joshua Duong85a65e22018-11-08 06:56:45 -08001/*
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 */
16package com.android.settings.development;
17
18import android.content.ContentResolver;
19import android.content.Context;
20import android.database.ContentObserver;
21import android.debug.IAdbManager;
Joshua Duong564f6ba2020-03-02 08:34:26 -080022import android.net.ConnectivityManager;
Jason Jeremy Iman620158b2020-12-14 18:19:52 +090023import android.net.Network;
24import android.net.NetworkCapabilities;
Joshua Duong85a65e22018-11-08 06:56:45 -080025import android.net.Uri;
26import android.os.Handler;
27import android.os.Looper;
28import android.os.RemoteException;
29import android.os.ServiceManager;
30import android.provider.Settings;
31import android.util.Log;
Joshua Duong564f6ba2020-03-02 08:34:26 -080032import android.widget.Toast;
Joshua Duong85a65e22018-11-08 06:56:45 -080033
34import androidx.preference.Preference;
35import androidx.preference.PreferenceScreen;
36
37import com.android.settings.core.PreferenceControllerMixin;
Wilson Wu9edf7972021-08-27 10:19:56 +080038import com.android.settingslib.PrimarySwitchPreference;
Joshua Duong85a65e22018-11-08 06:56:45 -080039import com.android.settingslib.core.lifecycle.Lifecycle;
40import com.android.settingslib.core.lifecycle.LifecycleObserver;
41import com.android.settingslib.core.lifecycle.events.OnPause;
42import com.android.settingslib.core.lifecycle.events.OnResume;
43import com.android.settingslib.development.DeveloperOptionsPreferenceController;
44
45/**
Edgar Wang4e02ceb2020-07-29 12:47:42 +080046 * This controls the primary switch controller in the developer options page for
Joshua Duong85a65e22018-11-08 06:56:45 -080047 * "Wireless debugging".
48 */
49public class WirelessDebuggingPreferenceController extends DeveloperOptionsPreferenceController
50 implements Preference.OnPreferenceChangeListener, PreferenceControllerMixin,
51 LifecycleObserver, OnResume, OnPause {
52 private static final String TAG = "WirelessDebugPrefCtrl";
53 private final IAdbManager mAdbManager;
54 private final ContentResolver mContentResolver;
55 private final ContentObserver mSettingsObserver;
56 private final Handler mHandler = new Handler(Looper.getMainLooper());
57
58 public static final String KEY_TOGGLE_ADB_WIRELESS = "toggle_adb_wireless";
59
60 public WirelessDebuggingPreferenceController(Context context, Lifecycle lifecycle) {
61 super(context);
62
63 if (lifecycle != null) {
64 lifecycle.addObserver(this);
65 }
66 mAdbManager = IAdbManager.Stub.asInterface(ServiceManager.getService(Context.ADB_SERVICE));
67 mSettingsObserver = new ContentObserver(mHandler) {
68 @Override
69 public void onChange(boolean selfChange, Uri uri) {
70 updateState(mPreference);
71 }
72 };
73 mContentResolver = context.getContentResolver();
74 }
75
76 @Override
77 public void displayPreference(PreferenceScreen screen) {
78 super.displayPreference(screen);
79 }
80
81 @Override
82 public boolean isAvailable() {
83 try {
84 return mAdbManager.isAdbWifiSupported();
85 } catch (RemoteException e) {
86 Log.e(TAG, "Unable to check if adb wifi is supported.", e);
87 }
88
89 return false;
90 }
91
92 @Override
93 public String getPreferenceKey() {
94 return KEY_TOGGLE_ADB_WIRELESS;
95 }
96
97 /**
98 * Called when developer options is enabled and the preference is available
99 */
100 @Override
101 protected void onDeveloperOptionsSwitchEnabled() {
102 super.onDeveloperOptionsSwitchEnabled();
103 mPreference.setEnabled(true);
104 }
105
106 /**
107 * Called when developer options is disabled and the preference is available
108 */
109 @Override
110 protected void onDeveloperOptionsSwitchDisabled() {
111 super.onDeveloperOptionsSwitchDisabled();
112 mPreference.setEnabled(false);
113 Settings.Global.putInt(mContext.getContentResolver(),
114 Settings.Global.ADB_WIFI_ENABLED,
115 AdbPreferenceController.ADB_SETTING_OFF);
116 }
117
118 @Override
119 public void onResume() {
120 mContentResolver.registerContentObserver(
121 Settings.Global.getUriFor(Settings.Global.ADB_WIFI_ENABLED), false,
122 mSettingsObserver);
123 }
124
125 @Override
126 public void onPause() {
127 mContentResolver.unregisterContentObserver(mSettingsObserver);
128 }
129
130 @Override
131 public void updateState(Preference preference) {
132 boolean enabled = Settings.Global.getInt(mContentResolver,
133 Settings.Global.ADB_WIFI_ENABLED, AdbPreferenceController.ADB_SETTING_OFF)
134 != AdbPreferenceController.ADB_SETTING_OFF;
govenliub70ddb92020-07-16 17:09:03 +0800135 ((PrimarySwitchPreference) preference).setChecked(enabled);
Joshua Duong85a65e22018-11-08 06:56:45 -0800136 }
137
Joshua Duong0c23d392020-04-07 00:17:17 -0700138 /**
139 * Returns true if connected to Wi-Fi network.
140 */
141 public static boolean isWifiConnected(Context context) {
Joshua Duong564f6ba2020-03-02 08:34:26 -0800142 ConnectivityManager cm = (ConnectivityManager) context.getSystemService(
143 Context.CONNECTIVITY_SERVICE);
Jason Jeremy Iman620158b2020-12-14 18:19:52 +0900144 if (cm == null) {
145 return false;
146 }
147 for (Network network : cm.getAllNetworks()) {
148 final NetworkCapabilities nc = cm.getNetworkCapabilities(network);
149 if (nc == null) {
150 continue;
151 }
152 if (nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
153 return true;
Joshua Duong564f6ba2020-03-02 08:34:26 -0800154 }
155 }
156 return false;
157 }
158
Joshua Duong85a65e22018-11-08 06:56:45 -0800159 @Override
160 public boolean onPreferenceChange(Preference preference, Object newValue) {
161 final boolean enabled = (Boolean) newValue;
Joshua Duong564f6ba2020-03-02 08:34:26 -0800162 if (enabled && !isWifiConnected(mContext)) {
163 // Cannot enable ADB over Wi-Fi if we're not connected to wifi.
164 Toast.makeText(
Chaohui Wang25413812023-07-31 15:56:42 +0800165 mContext, com.android.settingslib.R.string.adb_wireless_no_network_msg,
166 Toast.LENGTH_LONG)
Joshua Duong564f6ba2020-03-02 08:34:26 -0800167 .show();
168 return false;
169 }
170
Joshua Duong85a65e22018-11-08 06:56:45 -0800171 Settings.Global.putInt(mContext.getContentResolver(),
172 Settings.Global.ADB_WIFI_ENABLED,
173 enabled ? AdbPreferenceController.ADB_SETTING_ON
174 : AdbPreferenceController.ADB_SETTING_OFF);
175 return true;
176 }
177}