Home | History | Annotate | Download | only in flow
      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 
     67     public FlowService() {
     68         super("FlowService");
     69     }
     70 
     71     public final class FlowServiceImpl extends IFlowService.Stub {
     72         public void provision(OSUInfo osuInfo) {
     73             FlowService.this.provision(osuInfo);
     74         }
     75 
     76         public void remediate(String spFqdn, String url, boolean policy, Network network) {
     77             FlowService.this.remediate(spFqdn, url, policy, network);
     78         }
     79 
     80         public void spDeleted(String fqdn) {
     81             FlowService.this.serviceProviderDeleted(fqdn);
     82         }
     83     }
     84 
     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      */
    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 
    136     public void serviceProviderDeleted(String fqdn) {
    137         mPlatformAdapter.serviceProviderDeleted(fqdn);
    138     }
    139 
    140     @Override
    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
    157     protected void onHandleIntent(@Nullable Intent intent) {
    158     }
    159 
    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