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();
}
}
}