package se.leap.leapclient; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URL; import java.util.Iterator; import java.util.Scanner; import org.json.JSONException; import org.json.JSONObject; import se.leap.leapclient.ProviderAPIResultReceiver.Receiver; import se.leap.leapclient.ProviderListContent.ProviderItem; import android.app.Activity; import android.app.DialogFragment; import android.app.Fragment; import android.app.FragmentManager; import android.app.FragmentTransaction; import android.content.Intent; import android.content.res.AssetManager; import android.os.Bundle; import android.os.Handler; import android.view.View; import android.widget.Toast; /** * An activity representing a list of Providers. This activity * has different presentations for handset and tablet-size devices. On * handsets, the activity presents a list of items, which when touched, * lead to a {@link DashboardActivity} representing * item details. On tablets, the activity presents the list of items and * item details side-by-side using two vertical panes. *

* The activity makes heavy use of fragments. The list of items is a * {@link ProviderListFragment} and the item details * (if present) is a {@link DashboardFragment}. *

* This activity also implements the required * {@link ProviderListFragment.Callbacks} interface * to listen for item selections. */ public class ConfigurationWizard extends Activity implements ProviderListFragment.Callbacks, NewProviderDialog.NewProviderDialogInterface, Receiver { /** * Whether or not the activity is in two-pane mode, i.e. running on a tablet * device. */ private boolean mTwoPane; public ProviderAPIResultReceiver providerAPI_result_receiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_configuration_wizard); ConfigHelper.setSharedPreferences(getSharedPreferences(ConfigHelper.PREFERENCES_KEY, MODE_PRIVATE)); loadPreseededProviders(); if(ConfigHelper.getKeystore() == null) { InputStream keystore_input_stream = getResources().openRawResource(R.raw.leapkeystore); ConfigHelper.getNewKeystore(keystore_input_stream); } // Only create our fragments if we're not restoring a saved instance if ( savedInstanceState == null ){ // TODO Some welcome screen? // We will need better flow control when we have more Fragments (e.g. user auth) ProviderListFragment providerList = new ProviderListFragment(); FragmentManager fragmentManager = getFragmentManager(); fragmentManager.beginTransaction() .add(R.id.configuration_wizard_layout, providerList, "providerlist") .commit(); } // TODO: If exposing deep links into your app, handle intents here. } private void loadPreseededProviders() { AssetManager asset_manager = getAssets(); String[] urls_filepaths = null; try { String url_files_folder = "urls"; //TODO Put that folder in a better place (also inside the "for") urls_filepaths = asset_manager.list(url_files_folder); String provider_name = ""; for(String url_filepath : urls_filepaths) { boolean custom = false; provider_name = url_filepath.subSequence(0, url_filepath.indexOf(".")).toString(); if(ProviderListContent.ITEMS.isEmpty()) //TODO I have to implement a way of checking if a provider new or is already present in that ITEMS list ProviderListContent.addItem(new ProviderItem(provider_name, asset_manager.open(url_files_folder + "/" + url_filepath), custom, true)); // By default, it trusts the provider } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * Callback method from {@link ProviderListFragment.Callbacks} * indicating that the item with the given ID was selected. */ @Override public void onItemSelected(String id) { if (mTwoPane) { // TODO Hmmm...is this how we should do this? What if it /is/ two pane? } else { // In single-pane mode, simply start the detail activity // for the selected item ID. Iterator preseeded_providers_iterator = ProviderListContent.ITEMS.iterator(); while(preseeded_providers_iterator.hasNext()) { ProviderItem current_provider_item = preseeded_providers_iterator.next(); if(current_provider_item.id.equalsIgnoreCase(id)) { try { saveProviderJson(current_provider_item); downloadJSONFiles(current_provider_item); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } } private void saveProviderJson(ProviderItem current_provider_item) { JSONObject provider_json = new JSONObject(); try { String provider_contents = ""; if(!current_provider_item.custom) { //provider_contents = new Scanner(new InputStreamReader(assets_manager.open(current_provider_item.provider_json_filename))).useDelimiter("\\A").next(); updateProviderDotJson(current_provider_item.name, current_provider_item.provider_json_url, current_provider_item.danger_on); } else { provider_contents = new Scanner(ConfigHelper.openFileInputStream(current_provider_item.provider_json_filename)).useDelimiter("\\A").next(); provider_json = new JSONObject(provider_contents); ConfigHelper.saveSharedPref(ConfigHelper.provider_key, provider_json); try { ConfigHelper.saveSharedPref(ConfigHelper.danger_on, new JSONObject().put(ConfigHelper.danger_on, current_provider_item.danger_on)); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } catch (JSONException e) { ConfigHelper.rescueJSONException(e); } } private void downloadJSONFiles(ProviderItem current_provider_item) throws IOException { providerAPI_result_receiver = new ProviderAPIResultReceiver(new Handler()); providerAPI_result_receiver.setReceiver(this); Intent provider_API_command = new Intent(this, ProviderAPI.class); Bundle method_and_parameters = new Bundle(); method_and_parameters.putString(ConfigHelper.provider_key, current_provider_item.name); method_and_parameters.putString(ConfigHelper.main_cert_key, current_provider_item.cert_json_url); method_and_parameters.putString(ConfigHelper.eip_service_key, current_provider_item.eip_service_json_url); method_and_parameters.putBoolean(ConfigHelper.danger_on, current_provider_item.danger_on); provider_API_command.putExtra(ConfigHelper.downloadJsonFilesBundleExtra, method_and_parameters); provider_API_command.putExtra("receiver", providerAPI_result_receiver); startService(provider_API_command); } public void addNewProvider(View view) { FragmentTransaction fragment_transaction = getFragmentManager().beginTransaction(); Fragment previous_new_provider_dialog = getFragmentManager().findFragmentByTag(ConfigHelper.newProviderDialog); if (previous_new_provider_dialog != null) { fragment_transaction.remove(previous_new_provider_dialog); } fragment_transaction.addToBackStack(null); DialogFragment newFragment = NewProviderDialog.newInstance(); newFragment.show(fragment_transaction, ConfigHelper.newProviderDialog); } @Override public void saveProvider(String provider_main_url, boolean danger_on) { providerAPI_result_receiver = new ProviderAPIResultReceiver(new Handler()); providerAPI_result_receiver.setReceiver(this); Intent provider_API_command = new Intent(this, ProviderAPI.class); Bundle method_and_parameters = new Bundle(); method_and_parameters.putString(ConfigHelper.provider_main_url, provider_main_url); method_and_parameters.putBoolean(ConfigHelper.danger_on, danger_on); provider_API_command.putExtra(ConfigHelper.downloadNewProviderDotJSON, method_and_parameters); provider_API_command.putExtra("receiver", providerAPI_result_receiver); startService(provider_API_command); } public void updateProviderDotJson(String provider_name, String provider_json_url, boolean danger_on) { providerAPI_result_receiver = new ProviderAPIResultReceiver(new Handler()); providerAPI_result_receiver.setReceiver(this); Intent provider_API_command = new Intent(this, ProviderAPI.class); Bundle method_and_parameters = new Bundle(); method_and_parameters.putString(ConfigHelper.provider_name, provider_name); method_and_parameters.putString(ConfigHelper.provider_json_url, provider_json_url); method_and_parameters.putBoolean(ConfigHelper.danger_on, danger_on); provider_API_command.putExtra(ConfigHelper.updateProviderDotJSON, method_and_parameters); provider_API_command.putExtra("receiver", providerAPI_result_receiver); startService(provider_API_command); } @Override public void onReceiveResult(int resultCode, Bundle resultData) { if(resultCode == ConfigHelper.CUSTOM_PROVIDER_ADDED){ ProviderListFragment providerList = new ProviderListFragment(); FragmentManager fragmentManager = getFragmentManager(); fragmentManager.beginTransaction() .replace(R.id.configuration_wizard_layout, providerList, "providerlist") .commit(); } else if(resultCode == ConfigHelper.CORRECTLY_DOWNLOADED_JSON_FILES) { setResult(RESULT_OK); finish(); } else if(resultCode == ConfigHelper.INCORRECTLY_DOWNLOADED_JSON_FILES) { setResult(RESULT_CANCELED); Toast.makeText(getApplicationContext(), "You have not entered a LEAP provider URL", Toast.LENGTH_LONG).show(); } else if(resultCode == ConfigHelper.CORRECTLY_UPDATED_PROVIDER_DOT_JSON) { JSONObject provider_json; try { provider_json = new JSONObject(resultData.getString(ConfigHelper.provider_key)); boolean danger_on = resultData.getBoolean(ConfigHelper.danger_on); ConfigHelper.saveSharedPref(ConfigHelper.provider_key, provider_json); ConfigHelper.saveSharedPref(ConfigHelper.danger_on, new JSONObject().put(ConfigHelper.danger_on, danger_on)); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } } else if(resultCode == ConfigHelper.INCORRECTLY_UPDATED_PROVIDER_DOT_JSON) { Toast.makeText(getApplicationContext(), "Install a new version of this app.", Toast.LENGTH_LONG).show(); } } }