• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.android.hotspot2.flow;
2 
3 import android.annotation.Nullable;
4 import android.app.IntentService;
5 import android.content.BroadcastReceiver;
6 import android.content.Context;
7 import android.content.Intent;
8 import android.content.IntentFilter;
9 import android.net.Network;
10 import android.net.wifi.WifiInfo;
11 import android.net.wifi.WifiManager;
12 import android.os.IBinder;
13 import android.util.Log;
14 
15 import com.android.hotspot2.osu.OSUFlowManager;
16 import com.android.hotspot2.osu.OSUManager;
17 import com.android.hotspot2.osu.OSUOperationStatus;
18 import com.android.hotspot2.pps.HomeSP;
19 
20 import java.io.IOException;
21 
22 /**
23  * This is the Hotspot 2.0 release 2 service that handles actual provisioning and remediation flows.
24  *
25  * The OSU App is made up of two services; FlowService and OSUService.
26  *
27  * OSUService is a long running light weight service, kept alive throughout the lifetime of the
28  * operating system by being bound from the framework (in WifiManager in stage
29  * PHASE_THIRD_PARTY_APPS_CAN_START), and is responsible for continuously caching OSU information
30  * and notifying the UI when OSUs are available.
31  *
32  * FlowService is only started on demand from OSUService and is responsible for handling actual
33  * provisioning and remediation flows, and requires a fairly significant memory footprint.
34  *
35  * FlowService is defined to run in its own process through the definition
36  *      <service android:name=".flow.FlowService" android:process=":osuflow">
37  * in the AndroidManifest.
38  * This is done as a means to keep total app memory footprint low (pss < 10M) and only start the
39  * FlowService on demand and make it available for "garbage collection" by the OS when not in use.
40  */
41 public class FlowService extends IntentService {
42     private static final String[] INTENTS = {
43             WifiManager.NETWORK_STATE_CHANGED_ACTION
44     };
45 
46     private OSUFlowManager mOSUFlowManager;
47     private PlatformAdapter mPlatformAdapter;
48     private final FlowServiceImpl mOSUAccessor = new FlowServiceImpl();
49 
50     /*
51     public FlowService(Context context) {
52         super("FlowService");
53         mOSUFlowManager = new OSUFlowManager();
54         mPlatformAdapter = new PlatformAdapter(context);
55         BroadcastReceiver receiver = new BroadcastReceiver() {
56             @Override
57             public void onReceive(Context context, Intent intent) {
58                 handleIntent(intent.getAction(), intent);
59             }
60         };
61         for (String intentString : INTENTS) {
62             context.registerReceiver(receiver, new IntentFilter(intentString));
63         }
64     }
65     */
66 
FlowService()67     public FlowService() {
68         super("FlowService");
69     }
70 
71     public final class FlowServiceImpl extends IFlowService.Stub {
provision(OSUInfo osuInfo)72         public void provision(OSUInfo osuInfo) {
73             FlowService.this.provision(osuInfo);
74         }
75 
remediate(String spFqdn, String url, boolean policy, Network network)76         public void remediate(String spFqdn, String url, boolean policy, Network network) {
77             FlowService.this.remediate(spFqdn, url, policy, network);
78         }
79 
spDeleted(String fqdn)80         public void spDeleted(String fqdn) {
81             FlowService.this.serviceProviderDeleted(fqdn);
82         }
83     }
84 
provision(OSUInfo osuInfo)85     public void provision(OSUInfo osuInfo) {
86         try {
87             mOSUFlowManager.appendFlow(new OSUFlowManager.OSUFlow(osuInfo, mPlatformAdapter,
88                     mPlatformAdapter.getKeyManager(null)));
89         } catch (IOException ioe) {
90             mPlatformAdapter.notifyUser(OSUOperationStatus.ProvisioningFailure, ioe.getMessage(),
91                     osuInfo.getName(PlatformAdapter.LOCALE));
92         }
93     }
94 
95     /**
96      * Initiate remediation
97      * @param spFqdn The FQDN of the current SP, not set for WNM based remediation
98      * @param url The URL of the remediation server
99      * @param policy Set if this is a policy update rather than a subscription update
100      * @param network The network to use for remediation
101      */
remediate(String spFqdn, String url, boolean policy, Network network)102     public void remediate(String spFqdn, String url, boolean policy, Network network) {
103         Log.d(OSUManager.TAG, "Starting remediation for " + spFqdn + " to " + url);
104         if (spFqdn != null) {
105             HomeSP homeSP = mPlatformAdapter.getHomeSP(spFqdn);
106             if (homeSP == null) {
107                 Log.e(OSUManager.TAG, "No HomeSP object matches '" + spFqdn + "'");
108                 return;
109             }
110 
111             try {
112                 mOSUFlowManager.appendFlow(new OSUFlowManager.OSUFlow(network, url,
113                         mPlatformAdapter, mPlatformAdapter.getKeyManager(homeSP),
114                         homeSP, policy
115                         ? OSUFlowManager.FlowType.Policy : OSUFlowManager.FlowType.Remediation));
116             } catch (IOException ioe) {
117                 Log.e(OSUManager.TAG, "Failed to remediate: " + ioe, ioe);
118             }
119         } else {
120             HomeSP homeSP = mPlatformAdapter.getCurrentSP();
121             if (homeSP == null) {
122                 Log.e(OSUManager.TAG, "Remediation request on unidentified Passpoint network ");
123                 return;
124             }
125 
126             try {
127                 mOSUFlowManager.appendFlow(new OSUFlowManager.OSUFlow(network, url,
128                         mPlatformAdapter, mPlatformAdapter.getKeyManager(homeSP), homeSP,
129                         OSUFlowManager.FlowType.Remediation));
130             } catch (IOException ioe) {
131                 Log.e(OSUManager.TAG, "Failed to start remediation: " + ioe, ioe);
132             }
133         }
134     }
135 
serviceProviderDeleted(String fqdn)136     public void serviceProviderDeleted(String fqdn) {
137         mPlatformAdapter.serviceProviderDeleted(fqdn);
138     }
139 
140     @Override
onBind(Intent intent)141     public IBinder onBind(Intent intent) {
142         mOSUFlowManager = new OSUFlowManager(this);
143         mPlatformAdapter = new PlatformAdapter(this);
144         BroadcastReceiver receiver = new BroadcastReceiver() {
145             @Override
146             public void onReceive(Context context, Intent intent) {
147                 handleIntent(intent.getAction(), intent);
148             }
149         };
150         for (String intentString : INTENTS) {
151             registerReceiver(receiver, new IntentFilter(intentString));
152         }
153         return mOSUAccessor;
154     }
155 
156     @Override
onHandleIntent(@ullable Intent intent)157     protected void onHandleIntent(@Nullable Intent intent) {
158     }
159 
handleIntent(String action, Intent intent)160     private void handleIntent(String action, Intent intent) {
161         if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) {
162             WifiInfo wifiInfo = intent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO);
163             if (wifiInfo != null) {
164                 mOSUFlowManager.networkChange();
165             }
166         }
167     }
168 }
169