• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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.wifi;
18 
19 import static android.app.slice.Slice.EXTRA_TOGGLE_STATE;
20 import static android.provider.SettingsSlicesContract.KEY_WIFI;
21 
22 import static androidx.slice.builders.ListBuilder.ICON_IMAGE;
23 
24 import android.annotation.ColorInt;
25 import android.app.PendingIntent;
26 import android.content.ContentResolver;
27 import android.content.Context;
28 import android.content.Intent;
29 import android.content.IntentFilter;
30 import android.net.Uri;
31 import android.net.wifi.WifiInfo;
32 import android.net.wifi.WifiManager;
33 import android.net.wifi.WifiSsid;
34 import android.provider.SettingsSlicesContract;
35 
36 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
37 import com.android.settings.R;
38 import com.android.settings.SubSettings;
39 import com.android.settings.Utils;
40 import com.android.settings.search.DatabaseIndexingUtils;
41 import com.android.settings.slices.SliceBroadcastReceiver;
42 import com.android.settings.slices.SliceBuilderUtils;
43 
44 import androidx.slice.Slice;
45 import androidx.slice.builders.ListBuilder;
46 import androidx.slice.builders.SliceAction;
47 
48 import android.support.v4.graphics.drawable.IconCompat;
49 import android.text.TextUtils;
50 
51 /**
52  * Utility class to build a Wifi Slice, and handle all associated actions.
53  */
54 public class WifiSliceBuilder {
55 
56     /**
57      * Backing Uri for the Wifi Slice.
58      */
59     public static final Uri WIFI_URI = new Uri.Builder()
60             .scheme(ContentResolver.SCHEME_CONTENT)
61             .authority(SettingsSlicesContract.AUTHORITY)
62             .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
63             .appendPath(KEY_WIFI)
64             .build();
65 
66     /**
67      * Action notifying a change on the Wifi Slice.
68      */
69     public static final String ACTION_WIFI_SLICE_CHANGED =
70             "com.android.settings.wifi.action.WIFI_CHANGED";
71 
72     public static final IntentFilter INTENT_FILTER = new IntentFilter();
73 
74     static {
75         INTENT_FILTER.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
76         INTENT_FILTER.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
77     }
78 
WifiSliceBuilder()79     private WifiSliceBuilder() {
80     }
81 
82     /**
83      * Return a Wifi Slice bound to {@link #WIFI_URI}.
84      * <p>
85      * Note that you should register a listener for {@link #INTENT_FILTER} to get changes for Wifi.
86      */
getSlice(Context context)87     public static Slice getSlice(Context context) {
88         final boolean isWifiEnabled = isWifiEnabled(context);
89         final IconCompat icon = IconCompat.createWithResource(context,
90                 R.drawable.ic_settings_wireless);
91         final String title = context.getString(R.string.wifi_settings);
92         final CharSequence summary = getSummary(context);
93         @ColorInt final int color = Utils.getColorAccent(context);
94         final PendingIntent toggleAction = getBroadcastIntent(context);
95         final PendingIntent primaryAction = getPrimaryAction(context);
96         final SliceAction primarySliceAction = new SliceAction(primaryAction, icon, title);
97         final SliceAction toggleSliceAction = new SliceAction(toggleAction, null /* actionTitle */,
98                 isWifiEnabled);
99 
100         return new ListBuilder(context, WIFI_URI, ListBuilder.INFINITY)
101                 .setAccentColor(color)
102                 .addRow(b -> b
103                         .setTitle(title)
104                         .setSubtitle(summary)
105                         .addEndItem(toggleSliceAction)
106                         .setPrimaryAction(primarySliceAction))
107                 .build();
108     }
109 
110     /**
111      * Update the current wifi status to the boolean value keyed by
112      * {@link android.app.slice.Slice#EXTRA_TOGGLE_STATE} on {@param intent}.
113      */
handleUriChange(Context context, Intent intent)114     public static void handleUriChange(Context context, Intent intent) {
115         final WifiManager wifiManager = context.getSystemService(WifiManager.class);
116         final boolean newState = intent.getBooleanExtra(EXTRA_TOGGLE_STATE,
117                 wifiManager.isWifiEnabled());
118         wifiManager.setWifiEnabled(newState);
119         // Do not notifyChange on Uri. The service takes longer to update the current value than it
120         // does for the Slice to check the current value again. Let {@link SliceBroadcastRelay}
121         // handle it.
122     }
123 
getIntent(Context context)124     public static Intent getIntent(Context context) {
125         final String screenTitle = context.getText(R.string.wifi_settings).toString();
126         final Uri contentUri = new Uri.Builder().appendPath(KEY_WIFI).build();
127         final Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(context,
128                 WifiSettings.class.getName(), KEY_WIFI, screenTitle,
129                 MetricsEvent.DIALOG_WIFI_AP_EDIT)
130                 .setClassName(context.getPackageName(), SubSettings.class.getName())
131                 .setData(contentUri);
132 
133         return intent;
134     }
135 
isWifiEnabled(Context context)136     private static boolean isWifiEnabled(Context context) {
137         final WifiManager wifiManager = context.getSystemService(WifiManager.class);
138 
139         switch (wifiManager.getWifiState()) {
140             case WifiManager.WIFI_STATE_ENABLED:
141             case WifiManager.WIFI_STATE_ENABLING:
142                 return true;
143             case WifiManager.WIFI_STATE_DISABLED:
144             case WifiManager.WIFI_STATE_DISABLING:
145             case WifiManager.WIFI_STATE_UNKNOWN:
146             default:
147                 return false;
148         }
149     }
150 
getSummary(Context context)151     private static CharSequence getSummary(Context context) {
152         final WifiManager wifiManager = context.getSystemService(WifiManager.class);
153 
154         switch (wifiManager.getWifiState()) {
155             case WifiManager.WIFI_STATE_ENABLED:
156                 final String ssid = WifiInfo.removeDoubleQuotes(wifiManager.getConnectionInfo()
157                         .getSSID());
158                 if (TextUtils.equals(ssid, WifiSsid.NONE)) {
159                     return context.getText(R.string.disconnected);
160                 }
161                 return ssid;
162             case WifiManager.WIFI_STATE_ENABLING:
163                 return context.getText(R.string.disconnected);
164             case WifiManager.WIFI_STATE_DISABLED:
165             case WifiManager.WIFI_STATE_DISABLING:
166                 return context.getText(R.string.switch_off_text);
167             case WifiManager.WIFI_STATE_UNKNOWN:
168             default:
169                 return "";
170         }
171     }
172 
getPrimaryAction(Context context)173     private static PendingIntent getPrimaryAction(Context context) {
174         final Intent intent = getIntent(context);
175         return PendingIntent.getActivity(context, 0 /* requestCode */,
176                 intent, 0 /* flags */);
177     }
178 
getBroadcastIntent(Context context)179     private static PendingIntent getBroadcastIntent(Context context) {
180         final Intent intent = new Intent(ACTION_WIFI_SLICE_CHANGED);
181         intent.setClass(context, SliceBroadcastReceiver.class);
182         return PendingIntent.getBroadcast(context, 0 /* requestCode */, intent,
183                 PendingIntent.FLAG_CANCEL_CURRENT);
184     }
185 }
186