• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.android.hotspot2.app;
2 
3 import android.app.IntentService;
4 import android.content.BroadcastReceiver;
5 import android.content.Context;
6 import android.content.Intent;
7 import android.content.IntentFilter;
8 import android.net.wifi.WifiConfiguration;
9 import android.net.wifi.WifiInfo;
10 import android.net.wifi.WifiManager;
11 import android.os.Bundle;
12 import android.os.IBinder;
13 import android.util.Log;
14 
15 import com.android.anqp.OSUProvider;
16 import com.android.hotspot2.PasspointMatch;
17 import com.android.hotspot2.osu.OSUManager;
18 
19 import java.io.IOException;
20 import java.util.List;
21 
22 /**
23  * This is the Hotspot 2.0 release 2 OSU background service that is continuously running and caches
24  * OSU information.
25  *
26  * The OSU App is made up of two services; FlowService and OSUService.
27  *
28  * OSUService is a long running light weight service, kept alive throughout the lifetime of the
29  * operating system by being bound from the framework (in WifiManager in stage
30  * PHASE_THIRD_PARTY_APPS_CAN_START), and is responsible for continuously caching OSU information
31  * and notifying the UI when OSUs are available.
32  *
33  * FlowService is only started on demand from OSUService and is responsible for handling actual
34  * provisioning and remediation flows, and requires a fairly significant memory footprint.
35  *
36  * FlowService is defined to run in its own process through the definition
37  *      <service android:name=".flow.FlowService" android:process=":osuflow">
38  * in the AndroidManifest.
39  * This is done as a means to keep total app memory footprint low (pss < 10M) and only start the
40  * FlowService on demand and make it available for "garbage collection" by the OS when not in use.
41  */
42 public class OSUService extends IntentService {
43     public static final String REMEDIATION_DONE_ACTION = "com.android.hotspot2.REMEDIATION_DONE";
44     public static final String REMEDIATION_FQDN_EXTRA = "com.android.hotspot2.REMEDIATION_FQDN";
45     public static final String REMEDIATION_POLICY_EXTRA = "com.android.hotspot2.REMEDIATION_POLICY";
46 
47     private static final String[] INTENTS = {
48             WifiManager.SCAN_RESULTS_AVAILABLE_ACTION,
49             // TODO(b/32883320): use updated intent definitions.
50             //WifiManager.PASSPOINT_WNM_FRAME_RECEIVED_ACTION,
51             //WifiManager.PASSPOINT_ICON_RECEIVED_ACTION,
52             WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION,
53             WifiManager.WIFI_STATE_CHANGED_ACTION,
54             WifiManager.NETWORK_STATE_CHANGED_ACTION,
55             REMEDIATION_DONE_ACTION
56     };
57 
58     private OSUManager mOsuManager;
59     private final LocalServiceBinder mLocalServiceBinder;
60 
OSUService()61     public OSUService() {
62         super("OSUService");
63         mLocalServiceBinder = new LocalServiceBinder(this);
64     }
65 
66     /*
67     public final class OSUAccessorImpl extends IOSUAccessor.Stub {
68         public List<OSUData> getOsuData() {
69             List<OSUInfo> infos = getOsuInfos();
70             List<OSUData> data = new ArrayList<>(infos.size());
71             for (OSUInfo osuInfo : infos) {
72                 data.add(new OSUData(osuInfo));
73             }
74             return data;
75         }
76 
77         public void selectOsu(int id) {
78             OSUService.this.selectOsu(id);
79         }
80     }
81     */
82 
83     @Override
onStartCommand(Intent intent, int flags, int startId)84     public int onStartCommand(Intent intent, int flags, int startId) {
85         onHandleIntent(intent);
86         return START_STICKY;
87     }
88 
89     @Override
onBind(Intent intent)90     public IBinder onBind(Intent intent) {
91         BroadcastReceiver receiver = new BroadcastReceiver() {
92             @Override
93             public void onReceive(Context context, Intent intent) {
94                 handleIntent(intent.getAction(), intent);
95             }
96         };
97         for (String intentString : INTENTS) {
98             registerReceiver(receiver, new IntentFilter(intentString));
99         }
100         return mLocalServiceBinder;
101     }
102 
103     @Override
onHandleIntent(Intent intent)104     protected void onHandleIntent(Intent intent) {
105         if (intent == null) {
106             Log.d(OSUManager.TAG, "Null intent!");
107             return;
108         }
109         //handleIntent(intent.getStringExtra(MainActivity.ACTION_KEY), intent);
110     }
111 
handleIntent(String action, Intent intent)112     private void handleIntent(String action, Intent intent) {
113         WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
114         Bundle bundle = intent.getExtras();
115         if (mOsuManager == null) {
116             mOsuManager = new OSUManager(this);
117         }
118         Log.d(OSUManager.TAG, "Got intent " + intent.getAction());
119 
120         switch (action) {
121             case WifiManager.SCAN_RESULTS_AVAILABLE_ACTION:
122                 mOsuManager.pushScanResults(wifiManager.getScanResults());
123                 break;
124             // TODO(b/32883320): use updated intent definitions.
125             /*
126             case WifiManager.PASSPOINT_WNM_FRAME_RECEIVED_ACTION:
127                 long bssid = bundle.getLong(WifiManager.EXTRA_PASSPOINT_WNM_BSSID);
128                 String url = bundle.getString(WifiManager.EXTRA_PASSPOINT_WNM_URL);
129 
130                 try {
131                     if (bundle.containsKey(WifiManager.EXTRA_PASSPOINT_WNM_METHOD)) {
132                         int method = bundle.getInt(WifiManager.EXTRA_PASSPOINT_WNM_METHOD);
133                         if (method != OSUProvider.OSUMethod.SoapXml.ordinal()) {
134                             Log.w(OSUManager.TAG, "Unsupported remediation method: " + method);
135                             return;
136                         }
137                         PasspointMatch match = null;
138                         if (bundle.containsKey(WifiManager.EXTRA_PASSPOINT_WNM_PPOINT_MATCH)) {
139                             int ordinal =
140                                     bundle.getInt(WifiManager.EXTRA_PASSPOINT_WNM_PPOINT_MATCH);
141                             if (ordinal >= 0 && ordinal < PasspointMatch.values().length) {
142                                 match = PasspointMatch.values()[ordinal];
143                             }
144                         }
145                         mOsuManager.wnmRemediate(bssid, url, match);
146                     } else if (bundle.containsKey(WifiManager.EXTRA_PASSPOINT_WNM_ESS)) {
147                         boolean ess = bundle.getBoolean(WifiManager.EXTRA_PASSPOINT_WNM_ESS);
148                         int delay = bundle.getInt(WifiManager.EXTRA_PASSPOINT_WNM_DELAY);
149                         mOsuManager.deauth(bssid, ess, delay, url);
150                     } else {
151                         Log.w(OSUManager.TAG, "Unknown WNM event");
152                     }
153                 } catch (IOException e) {
154                     Log.w(OSUManager.TAG, "Remediation event failed to parse: " + e);
155                 }
156                 break;
157             case WifiManager.PASSPOINT_ICON_RECEIVED_ACTION:
158                 mOsuManager.notifyIconReceived(
159                         bundle.getLong(WifiManager.EXTRA_PASSPOINT_ICON_BSSID),
160                         bundle.getString(WifiManager.EXTRA_PASSPOINT_ICON_FILE),
161                         bundle.getByteArray(WifiManager.EXTRA_PASSPOINT_ICON_DATA));
162                 break;
163             */
164             case WifiManager.NETWORK_STATE_CHANGED_ACTION:
165                 mOsuManager.networkConnectChange(
166                         (WifiInfo) intent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO));
167                 break;
168             case WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION:
169                 boolean multiNetwork =
170                         bundle.getBoolean(WifiManager.EXTRA_MULTIPLE_NETWORKS_CHANGED, false);
171                 if (multiNetwork) {
172                     mOsuManager.networkConfigChanged();
173                 } else if (bundle.getInt(WifiManager.EXTRA_CHANGE_REASON,
174                         WifiManager.CHANGE_REASON_CONFIG_CHANGE)
175                         == WifiManager.CHANGE_REASON_REMOVED) {
176                     WifiConfiguration configuration =
177                             intent.getParcelableExtra(WifiManager.EXTRA_WIFI_CONFIGURATION);
178                     mOsuManager.networkDeleted(configuration);
179                 } else {
180                     mOsuManager.networkConfigChanged();
181                 }
182                 break;
183             case WifiManager.WIFI_STATE_CHANGED_ACTION:
184                 int state = bundle.getInt(WifiManager.EXTRA_WIFI_STATE);
185                 if (state == WifiManager.WIFI_STATE_DISABLED) {
186                     mOsuManager.wifiStateChange(false);
187                 } else if (state == WifiManager.WIFI_STATE_ENABLED) {
188                     mOsuManager.wifiStateChange(true);
189                 }
190                 break;
191             case REMEDIATION_DONE_ACTION:
192                 String fqdn = bundle.getString(REMEDIATION_FQDN_EXTRA);
193                 boolean policy = bundle.getBoolean(REMEDIATION_POLICY_EXTRA);
194                 mOsuManager.remediationDone(fqdn, policy);
195                 break;
196             }
197     }
198 
getOsuData()199     public List<OSUData> getOsuData() {
200         return mOsuManager.getAvailableOSUs();
201     }
202 
selectOsu(int id)203     public void selectOsu(int id) {
204         mOsuManager.setOSUSelection(id);
205     }
206 }
207