When other network types with higher priority than wifi is connected alongside wifi, turning on ADB over wifi is not possible. This is happening due to `isWifiConnected()` only checks if wifi is the default network and not if wifi is connected. Often times multiple networks such as ethernet is used in conjuction with wifi, making ADB over wifi not working with the setup. Fix by returning if any available network is a WiFi network. Bug: 173466085 Test: Tested on eve Chrome OS ARCVM, ADB WiFi can be toggled when WiFi is not the default network. Change-Id: I8474a4e8b37a4af0031e1462645509f1e634e9a8
178 lines
6.1 KiB
Java
178 lines
6.1 KiB
Java
/*
|
|
* 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.settings.development;
|
|
|
|
import android.content.ContentResolver;
|
|
import android.content.Context;
|
|
import android.database.ContentObserver;
|
|
import android.debug.IAdbManager;
|
|
import android.net.ConnectivityManager;
|
|
import android.net.Network;
|
|
import android.net.NetworkCapabilities;
|
|
import android.net.Uri;
|
|
import android.os.Handler;
|
|
import android.os.Looper;
|
|
import android.os.RemoteException;
|
|
import android.os.ServiceManager;
|
|
import android.provider.Settings;
|
|
import android.util.Log;
|
|
import android.widget.Toast;
|
|
|
|
import androidx.preference.Preference;
|
|
import androidx.preference.PreferenceScreen;
|
|
|
|
import com.android.settings.R;
|
|
import com.android.settings.core.PreferenceControllerMixin;
|
|
import com.android.settings.widget.MasterSwitchPreference;
|
|
import com.android.settingslib.core.lifecycle.Lifecycle;
|
|
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
|
import com.android.settingslib.core.lifecycle.events.OnPause;
|
|
import com.android.settingslib.core.lifecycle.events.OnResume;
|
|
import com.android.settingslib.development.DeveloperOptionsPreferenceController;
|
|
|
|
/**
|
|
* This controls the master switch controller in the developer options page for
|
|
* "Wireless debugging".
|
|
*/
|
|
public class WirelessDebuggingPreferenceController extends DeveloperOptionsPreferenceController
|
|
implements Preference.OnPreferenceChangeListener, PreferenceControllerMixin,
|
|
LifecycleObserver, OnResume, OnPause {
|
|
private static final String TAG = "WirelessDebugPrefCtrl";
|
|
private final IAdbManager mAdbManager;
|
|
private final ContentResolver mContentResolver;
|
|
private final ContentObserver mSettingsObserver;
|
|
private final Handler mHandler = new Handler(Looper.getMainLooper());
|
|
|
|
public static final String KEY_TOGGLE_ADB_WIRELESS = "toggle_adb_wireless";
|
|
|
|
public WirelessDebuggingPreferenceController(Context context, Lifecycle lifecycle) {
|
|
super(context);
|
|
|
|
if (lifecycle != null) {
|
|
lifecycle.addObserver(this);
|
|
}
|
|
mAdbManager = IAdbManager.Stub.asInterface(ServiceManager.getService(Context.ADB_SERVICE));
|
|
mSettingsObserver = new ContentObserver(mHandler) {
|
|
@Override
|
|
public void onChange(boolean selfChange, Uri uri) {
|
|
updateState(mPreference);
|
|
}
|
|
};
|
|
mContentResolver = context.getContentResolver();
|
|
}
|
|
|
|
@Override
|
|
public void displayPreference(PreferenceScreen screen) {
|
|
super.displayPreference(screen);
|
|
}
|
|
|
|
@Override
|
|
public boolean isAvailable() {
|
|
try {
|
|
return mAdbManager.isAdbWifiSupported();
|
|
} catch (RemoteException e) {
|
|
Log.e(TAG, "Unable to check if adb wifi is supported.", e);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public String getPreferenceKey() {
|
|
return KEY_TOGGLE_ADB_WIRELESS;
|
|
}
|
|
|
|
/**
|
|
* Called when developer options is enabled and the preference is available
|
|
*/
|
|
@Override
|
|
protected void onDeveloperOptionsSwitchEnabled() {
|
|
super.onDeveloperOptionsSwitchEnabled();
|
|
mPreference.setEnabled(true);
|
|
}
|
|
|
|
/**
|
|
* Called when developer options is disabled and the preference is available
|
|
*/
|
|
@Override
|
|
protected void onDeveloperOptionsSwitchDisabled() {
|
|
super.onDeveloperOptionsSwitchDisabled();
|
|
mPreference.setEnabled(false);
|
|
Settings.Global.putInt(mContext.getContentResolver(),
|
|
Settings.Global.ADB_WIFI_ENABLED,
|
|
AdbPreferenceController.ADB_SETTING_OFF);
|
|
}
|
|
|
|
@Override
|
|
public void onResume() {
|
|
mContentResolver.registerContentObserver(
|
|
Settings.Global.getUriFor(Settings.Global.ADB_WIFI_ENABLED), false,
|
|
mSettingsObserver);
|
|
}
|
|
|
|
@Override
|
|
public void onPause() {
|
|
mContentResolver.unregisterContentObserver(mSettingsObserver);
|
|
}
|
|
|
|
@Override
|
|
public void updateState(Preference preference) {
|
|
boolean enabled = Settings.Global.getInt(mContentResolver,
|
|
Settings.Global.ADB_WIFI_ENABLED, AdbPreferenceController.ADB_SETTING_OFF)
|
|
!= AdbPreferenceController.ADB_SETTING_OFF;
|
|
((MasterSwitchPreference) preference).setChecked(enabled);
|
|
}
|
|
|
|
/**
|
|
* Returns true if connected to Wi-Fi network.
|
|
*/
|
|
public static boolean isWifiConnected(Context context) {
|
|
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(
|
|
Context.CONNECTIVITY_SERVICE);
|
|
if (cm == null) {
|
|
return false;
|
|
}
|
|
for (Network network : cm.getAllNetworks()) {
|
|
final NetworkCapabilities nc = cm.getNetworkCapabilities(network);
|
|
if (nc == null) {
|
|
continue;
|
|
}
|
|
if (nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
|
final boolean enabled = (Boolean) newValue;
|
|
if (enabled && !isWifiConnected(mContext)) {
|
|
// Cannot enable ADB over Wi-Fi if we're not connected to wifi.
|
|
Toast.makeText(
|
|
mContext, R.string.adb_wireless_no_network_msg, Toast.LENGTH_LONG)
|
|
.show();
|
|
return false;
|
|
}
|
|
|
|
Settings.Global.putInt(mContext.getContentResolver(),
|
|
Settings.Global.ADB_WIFI_ENABLED,
|
|
enabled ? AdbPreferenceController.ADB_SETTING_ON
|
|
: AdbPreferenceController.ADB_SETTING_OFF);
|
|
return true;
|
|
}
|
|
}
|