Home | History | Annotate | Download | only in app
      1 package com.android.hotspot2.app;
      2 
      3 import android.app.Activity;
      4 import android.app.AlertDialog;
      5 import android.app.Notification;
      6 import android.app.NotificationManager;
      7 import android.app.PendingIntent;
      8 import android.app.TaskStackBuilder;
      9 import android.content.ComponentName;
     10 import android.content.DialogInterface;
     11 import android.content.Intent;
     12 import android.content.ServiceConnection;
     13 import android.graphics.BitmapFactory;
     14 import android.graphics.drawable.BitmapDrawable;
     15 import android.os.Bundle;
     16 import android.os.IBinder;
     17 import android.util.Log;
     18 import android.view.LayoutInflater;
     19 import android.view.View;
     20 import android.view.ViewGroup;
     21 import android.widget.AdapterView;
     22 import android.widget.ArrayAdapter;
     23 import android.widget.ImageView;
     24 import android.widget.ListView;
     25 import android.widget.TextView;
     26 
     27 import com.android.hotspot2.AppBridge;
     28 import com.android.hotspot2.R;
     29 import com.android.hotspot2.osu.OSUManager;
     30 
     31 import java.util.Collections;
     32 import java.util.List;
     33 import java.util.concurrent.TimeUnit;
     34 
     35 /**
     36  * Main activity.
     37  */
     38 public class MainActivity extends Activity {
     39     private static final int NOTIFICATION_ID = 0; // Used for OSU count
     40     private static final int NOTIFICATION_MESSAGE_ID = 1; // Used for other messages
     41     private static final String ACTION_SVC_BOUND = "SVC_BOUND";
     42 
     43     private volatile OSUService mLocalService;
     44 
     45     private final ServiceConnection mConnection = new ServiceConnection() {
     46         @Override
     47         public void onServiceConnected(ComponentName name, IBinder service) {
     48             LocalServiceBinder binder = (LocalServiceBinder) service;
     49             mLocalService = binder.getService();
     50             showOsuSelection(mLocalService);
     51         }
     52 
     53         @Override
     54         public void onServiceDisconnected(ComponentName name) {
     55             mLocalService = null;
     56         }
     57     };
     58 
     59     private ListView osuListView;
     60     private OsuListAdapter osuListAdapter;
     61     private String message;
     62 
     63     public MainActivity() {
     64 
     65     }
     66 
     67     @Override
     68     protected void onStop() {
     69         super.onStop();
     70         if (mLocalService != null) {
     71             unbindService(mConnection);
     72             mLocalService = null;
     73         }
     74     }
     75 
     76     @Override
     77     protected void onResume() {
     78         super.onResume();
     79         if (message != null) {
     80             showDialog(message);
     81             message = null;
     82         }
     83     }
     84 
     85     @Override
     86     public void onCreate(Bundle savedInstanceState) {
     87         super.onCreate(savedInstanceState);
     88 
     89         final Intent intent = getIntent();
     90         Bundle bundle = intent.getExtras();
     91 
     92         if (intent.getAction() == null) {
     93             if (mLocalService == null) {
     94                 bindService(new Intent(this, OSUService.class), mConnection, 0);
     95             }
     96         } else if (intent.getAction().equals(AppBridge.ACTION_OSU_NOTIFICATION)) {
     97             if (bundle == null) {
     98                 Log.d(OSUManager.TAG, "No parameters for OSU notification");
     99                 return;
    100             }
    101             if (bundle.containsKey(AppBridge.OSU_COUNT)) {
    102                 showOsuCount(bundle.getInt("osu-count", 0), Collections.<OSUData>emptyList());
    103             } else if (bundle.containsKey(AppBridge.PROV_SUCCESS)) {
    104                 showStatus(bundle.getBoolean(AppBridge.PROV_SUCCESS),
    105                         bundle.getString(AppBridge.SP_NAME),
    106                         bundle.getString(AppBridge.PROV_MESSAGE),
    107                         null);
    108             } else if (bundle.containsKey(AppBridge.DEAUTH)) {
    109                 showDeauth(bundle.getString(AppBridge.SP_NAME),
    110                         bundle.getBoolean(AppBridge.DEAUTH),
    111                         bundle.getInt(AppBridge.DEAUTH_DELAY),
    112                         bundle.getString(AppBridge.DEAUTH_URL));
    113             }
    114         }
    115     }
    116 
    117     private void showOsuSelection(final OSUService osuService) {
    118         List<OSUData> osuData = osuService.getOsuData();
    119 
    120         setContentView(R.layout.activity_main);
    121         Log.d("osu", "osu count:" + osuData.size());
    122         View noOsuView = findViewById(R.id.no_osu);
    123         if (osuData.size() > 0) {
    124             noOsuView.setVisibility(View.GONE);
    125             osuListAdapter = new OsuListAdapter(this, osuData);
    126             osuListView = findViewById(R.id.profile_list);
    127             osuListView.setAdapter(osuListAdapter);
    128             osuListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    129                 @Override
    130                 public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
    131                     OSUData osuData = (OSUData) adapterView.getAdapter().getItem(position);
    132                     Log.d("osu", "launch osu:" + osuData.getName()
    133                             + " id:" + osuData.getId());
    134                     osuService.selectOsu(osuData.getId());
    135                     finish();
    136                 }
    137             });
    138         } else {
    139             noOsuView.setVisibility(View.VISIBLE);
    140         }
    141     }
    142 
    143     private void showOsuCount(int osuCount, List<OSUData> osus) {
    144         if (osuCount > 0) {
    145             printOsuDataList(osus);
    146             sendNotification(osuCount);
    147         } else {
    148             cancelNotification();
    149         }
    150         finish();
    151     }
    152 
    153     private void showStatus(boolean provSuccess, String spName, String provMessage,
    154                             String remoteStatus) {
    155         if (provSuccess) {
    156             sendDialogMessage(
    157                     String.format("Credentials for %s was successfully installed", spName));
    158         } else {
    159             if (spName != null) {
    160                 if (remoteStatus != null) {
    161                     sendDialogMessage(
    162                             String.format("Failed to install credentials for %s: %s: %s",
    163                                     spName, provMessage, remoteStatus));
    164                 } else {
    165                     sendDialogMessage(
    166                             String.format("Failed to install credentials for %s: %s",
    167                                     spName, provMessage));
    168                 }
    169             } else {
    170                 sendDialogMessage(
    171                         String.format("Failed to contact OSU: %s", provMessage));
    172             }
    173         }
    174     }
    175 
    176     private void showDeauth(String spName, boolean ess, int delay, String url) {
    177         String delayReadable = getReadableTimeInSeconds(delay);
    178         if (ess) {
    179             if (delay > 60) {
    180                 sendDialogMessage(
    181                         String.format("There is an issue connecting to %s [for the next %s]. " +
    182                                 "Please visit %s for details", spName, delayReadable, url));
    183             } else {
    184                 sendDialogMessage(
    185                         String.format("There is an issue connecting to %s. " +
    186                                 "Please visit %s for details", spName, url));
    187             }
    188         } else {
    189             sendDialogMessage(
    190                     String.format("There is an issue with the closest Access Point for %s. " +
    191                                     "You may wait %s or move to another Access Point to " +
    192                                     "regain access. Please visit %s for details.",
    193                             spName, delayReadable, url));
    194         }
    195     }
    196 
    197     private String getReadableTimeInSeconds(int timeSeconds) {
    198         long hours = TimeUnit.SECONDS.toHours(timeSeconds);
    199         long minutes = TimeUnit.SECONDS.toMinutes(timeSeconds) - TimeUnit.HOURS.toMinutes(hours);
    200         long seconds =
    201                 timeSeconds - TimeUnit.HOURS.toSeconds(hours) - TimeUnit.MINUTES.toSeconds(minutes);
    202         if (hours > 0) {
    203             return String.format("%02d:%02d:%02d", hours, minutes, seconds);
    204         } else {
    205             return String.format("%ds", seconds);
    206         }
    207     }
    208 
    209     private void sendNotification(int count) {
    210         Notification.Builder builder =
    211                 new Notification.Builder(this)
    212                         .setContentTitle(String.format("%s OSU available", count))
    213                         .setContentText("Choose one to connect")
    214                         .setSmallIcon(android.R.drawable.ic_dialog_info)
    215                         .setAutoCancel(false);
    216         Intent resultIntent = new Intent(this, MainActivity.class);
    217 
    218         TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
    219         stackBuilder.addParentStack(MainActivity.class);
    220         stackBuilder.addNextIntent(resultIntent);
    221         PendingIntent resultPendingIntent =
    222                 stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
    223         builder.setContentIntent(resultPendingIntent);
    224         NotificationManager notificationManager =
    225                 (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    226         notificationManager.notify(NOTIFICATION_ID, builder.build());
    227     }
    228 
    229     private void cancelNotification() {
    230         NotificationManager notificationManager =
    231                 (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    232         notificationManager.cancel(NOTIFICATION_ID);
    233     }
    234 
    235     private void sendDialogMessage(String message) {
    236 //        sendNotificationMessage(message);
    237         this.message = message;
    238     }
    239 
    240     private void showDialog(String message) {
    241         AlertDialog.Builder builder = new AlertDialog.Builder(this);
    242         builder.setMessage(message)
    243                 .setTitle("OSU");
    244         builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
    245             @Override
    246             public void onCancel(DialogInterface dialogInterface) {
    247                 dialogInterface.cancel();
    248                 finish();
    249             }
    250         });
    251         AlertDialog dialog = builder.create();
    252         dialog.show();
    253     }
    254 
    255     private void sendNotificationMessage(String title) {
    256         Notification.Builder builder =
    257                 new Notification.Builder(this)
    258                         .setContentTitle(title)
    259                         .setContentText("Click to dismiss.")
    260                         .setSmallIcon(android.R.drawable.ic_dialog_info)
    261                         .setAutoCancel(true);
    262         NotificationManager notificationManager =
    263                 (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    264         notificationManager.notify(NOTIFICATION_MESSAGE_ID, builder.build());
    265     }
    266 
    267     private static class OsuListAdapter extends ArrayAdapter<OSUData> {
    268         private Activity activity;
    269 
    270         public OsuListAdapter(Activity activity, List<OSUData> osuDataList) {
    271             super(activity, R.layout.list_item, osuDataList);
    272             this.activity = activity;
    273         }
    274 
    275         @Override
    276         public View getView(int position, View convertView, ViewGroup parent) {
    277             View view = convertView;
    278             if (view == null) {
    279                 view = LayoutInflater.from(getContext()).inflate(R.layout.list_item, parent, false);
    280             }
    281             OSUData osuData = getItem(position);
    282             TextView osuName = (TextView) view.findViewById(R.id.profile_name);
    283             osuName.setText(osuData.getName());
    284             TextView osuDetail = (TextView) view.findViewById(R.id.profile_detail);
    285             osuDetail.setText(osuData.getServiceDescription());
    286             ImageView osuIcon = (ImageView) view.findViewById(R.id.profile_logo);
    287             byte[] iconData = osuData.getIconData();
    288             osuIcon.setImageDrawable(
    289                     new BitmapDrawable(activity.getResources(),
    290                             BitmapFactory.decodeByteArray(iconData, 0, iconData.length)));
    291             return view;
    292         }
    293     }
    294 
    295     private void printOsuDataList(List<OSUData> osuDataList) {
    296         for (OSUData osuData : osuDataList) {
    297             Log.d("osu", String.format("OSUData:[%s][%s][%d]",
    298                     osuData.getName(), osuData.getServiceDescription(),
    299                     osuData.getId()));
    300         }
    301     }
    302 
    303 }
    304