1 /*
2  * Copyright (C) 2017 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.settingslib.deviceinfo;
18 
19 import android.content.Context;
20 import android.net.ConnectivityManager;
21 import android.net.LinkAddress;
22 import android.net.LinkProperties;
23 import android.net.wifi.WifiManager;
24 
25 import androidx.annotation.VisibleForTesting;
26 import androidx.preference.Preference;
27 import androidx.preference.PreferenceScreen;
28 
29 import com.android.settingslib.R;
30 import com.android.settingslib.core.lifecycle.Lifecycle;
31 
32 import java.util.Iterator;
33 
34 /**
35  * Preference controller for IP address
36  */
37 public abstract class AbstractIpAddressPreferenceController
38         extends AbstractConnectivityPreferenceController {
39 
40     @VisibleForTesting
41     static final String KEY_IP_ADDRESS = "wifi_ip_address";
42 
43     private static final String[] CONNECTIVITY_INTENTS = {
44             ConnectivityManager.CONNECTIVITY_ACTION,
45             WifiManager.ACTION_LINK_CONFIGURATION_CHANGED,
46             WifiManager.NETWORK_STATE_CHANGED_ACTION,
47     };
48 
49     private Preference mIpAddress;
50     private final ConnectivityManager mCM;
51 
AbstractIpAddressPreferenceController(Context context, Lifecycle lifecycle)52     public AbstractIpAddressPreferenceController(Context context, Lifecycle lifecycle) {
53         super(context, lifecycle);
54         mCM = context.getSystemService(ConnectivityManager.class);
55     }
56 
57     @Override
isAvailable()58     public boolean isAvailable() {
59         return true;
60     }
61 
62     @Override
getPreferenceKey()63     public String getPreferenceKey() {
64         return KEY_IP_ADDRESS;
65     }
66 
67     @Override
displayPreference(PreferenceScreen screen)68     public void displayPreference(PreferenceScreen screen) {
69         super.displayPreference(screen);
70         mIpAddress = screen.findPreference(KEY_IP_ADDRESS);
71         updateConnectivity();
72     }
73 
74     @Override
getConnectivityIntents()75     protected String[] getConnectivityIntents() {
76         return CONNECTIVITY_INTENTS;
77     }
78 
79     @Override
updateConnectivity()80     protected void updateConnectivity() {
81         String ipAddress = getDefaultIpAddresses(mCM);
82         if (ipAddress != null) {
83             mIpAddress.setSummary(ipAddress);
84         } else {
85             mIpAddress.setSummary(R.string.status_unavailable);
86         }
87     }
88 
89     /**
90      * Returns the default link's IP addresses, if any, taking into account IPv4 and IPv6 style
91      * addresses.
92      * @param cm ConnectivityManager
93      * @return the formatted and newline-separated IP addresses, or null if none.
94      */
getDefaultIpAddresses(ConnectivityManager cm)95     private static String getDefaultIpAddresses(ConnectivityManager cm) {
96         LinkProperties prop = cm.getLinkProperties(cm.getActiveNetwork());
97         return formatIpAddresses(prop);
98     }
99 
formatIpAddresses(LinkProperties prop)100     private static String formatIpAddresses(LinkProperties prop) {
101         if (prop == null) return null;
102         Iterator<LinkAddress> iter = prop.getAllLinkAddresses().iterator();
103         // If there are no entries, return null
104         if (!iter.hasNext()) return null;
105         // Concatenate all available addresses, newline separated
106         StringBuilder addresses = new StringBuilder();
107         while (iter.hasNext()) {
108             addresses.append(iter.next().getAddress().getHostAddress());
109             if (iter.hasNext()) addresses.append("\n");
110         }
111         return addresses.toString();
112     }
113 }
114