• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.settings.development;
18 
19 import android.content.Context;
20 import android.debug.IAdbManager;
21 import android.net.ConnectivityManager;
22 import android.net.LinkAddress;
23 import android.net.LinkProperties;
24 import android.net.wifi.WifiManager;
25 import android.os.Build;
26 import android.os.RemoteException;
27 import android.os.ServiceManager;
28 import android.os.SystemProperties;
29 import android.util.Log;
30 
31 import androidx.preference.Preference;
32 import androidx.preference.PreferenceScreen;
33 
34 import com.android.settingslib.core.lifecycle.Lifecycle;
35 import com.android.settingslib.deviceinfo.AbstractConnectivityPreferenceController;
36 
37 import java.net.Inet4Address;
38 import java.net.InetAddress;
39 import java.util.Iterator;
40 
41 /**
42  * Controller for the ip address preference in the Wireless debugging
43  * fragment.
44  */
45 public class AdbIpAddressPreferenceController extends AbstractConnectivityPreferenceController {
46     private static final String TAG = "AdbIpAddrPrefCtrl";
47 
48     private static final String[] CONNECTIVITY_INTENTS = {
49             ConnectivityManager.CONNECTIVITY_ACTION,
50             WifiManager.ACTION_LINK_CONFIGURATION_CHANGED,
51             WifiManager.NETWORK_STATE_CHANGED_ACTION,
52     };
53 
54     private static final String PREF_KEY = "adb_ip_addr_pref";
55     private Preference mAdbIpAddrPref;
56     private int mPort;
57     private final ConnectivityManager mCM;
58     private IAdbManager mAdbManager;
59 
AdbIpAddressPreferenceController(Context context, Lifecycle lifecycle)60     public AdbIpAddressPreferenceController(Context context, Lifecycle lifecycle) {
61         super(context, lifecycle);
62         mCM = context.getSystemService(ConnectivityManager.class);
63         mAdbManager = IAdbManager.Stub.asInterface(ServiceManager.getService(
64                 Context.ADB_SERVICE));
65     }
66 
67     @Override
isAvailable()68     public boolean isAvailable() {
69         return true;
70     }
71 
72     @Override
getPreferenceKey()73     public String getPreferenceKey() {
74         return PREF_KEY;
75     }
76 
77     @Override
displayPreference(PreferenceScreen screen)78     public void displayPreference(PreferenceScreen screen) {
79         super.displayPreference(screen);
80         mAdbIpAddrPref = screen.findPreference(PREF_KEY);
81         updateConnectivity();
82     }
83 
84     @Override
updateState(Preference preference)85     public void updateState(Preference preference) {
86         super.updateState(preference);
87         updateConnectivity();
88     }
89 
90     @Override
getConnectivityIntents()91     protected String[] getConnectivityIntents() {
92         return CONNECTIVITY_INTENTS;
93     }
94 
getPort()95     protected int getPort() {
96         try {
97             return mAdbManager.getAdbWirelessPort();
98         } catch (RemoteException e) {
99             Log.e(TAG, "Unable to get the adbwifi port");
100         }
101         return 0;
102     }
103 
getIpv4Address()104     public String getIpv4Address() {
105         // ARC specific - from here
106         // Get the host's Wi-Fi IP address instead of guest's IP.
107         if (Build.IS_ARC) {
108             final String[] addrs =
109                     SystemProperties.get("vendor.arc.net.ipv4.host_wifi_address").split(",");
110             // ADB over Wi-Fi uses the first available available network configuration.
111             if (addrs.length > 0) {
112                 return addrs[0];
113             }
114         }
115         // ARC specific - till here.
116         return getDefaultIpAddresses(mCM);
117     }
118 
119     @Override
updateConnectivity()120     protected void updateConnectivity() {
121         String ipAddress = getIpv4Address();
122         if (ipAddress != null) {
123             int port = getPort();
124             if (port <= 0) {
125                 mAdbIpAddrPref.setSummary(com.android.settingslib.R.string.status_unavailable);
126             } else {
127                 ipAddress += ":" + port;
128             }
129             mAdbIpAddrPref.setSummary(ipAddress);
130         } else {
131             mAdbIpAddrPref.setSummary(com.android.settingslib.R.string.status_unavailable);
132         }
133     }
134 
135     /**
136      * Returns the default link's IP addresses, if any, taking into account IPv4 and IPv6 style
137      * addresses.
138      * @param cm ConnectivityManager
139      * @return the formatted and newline-separated IP addresses, or null if none.
140      */
getDefaultIpAddresses(ConnectivityManager cm)141     private static String getDefaultIpAddresses(ConnectivityManager cm) {
142         LinkProperties prop = cm.getLinkProperties(cm.getActiveNetwork());
143         return formatIpAddresses(prop);
144     }
145 
formatIpAddresses(LinkProperties prop)146     private static String formatIpAddresses(LinkProperties prop) {
147         if (prop == null) {
148             return null;
149         }
150 
151         Iterator<LinkAddress> iter = prop.getAllLinkAddresses().iterator();
152         // If there are no entries, return null
153         if (!iter.hasNext()) {
154             return null;
155         }
156 
157         // Concatenate all available addresses, newline separated
158         StringBuilder addresses = new StringBuilder();
159         while (iter.hasNext()) {
160             InetAddress addr = iter.next().getAddress();
161             if (addr instanceof Inet4Address) {
162                 // adb only supports ipv4 at the moment
163                 addresses.append(addr.getHostAddress());
164                 break;
165             }
166         }
167         return addresses.toString();
168     }
169 }
170