From f9a200a7004b74cb2d64e37129e6234427c84c7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Thu, 4 Dec 2014 16:38:21 +0100 Subject: Renderers and dagger, refactoring CW. --- .../main/java/se/leap/bitmaskclient/Dashboard.java | 15 +-- .../main/java/se/leap/bitmaskclient/Provider.java | 116 ++++++++++---------- .../se/leap/bitmaskclient/ProviderManager.java | 120 +++++++++++++++++++++ .../se/leap/bitmaskclient/ProviderRenderer.java | 55 ++++++++++ .../bitmaskclient/ProviderRendererBuilder.java | 25 +++++ 5 files changed, 264 insertions(+), 67 deletions(-) create mode 100644 app/src/main/java/se/leap/bitmaskclient/ProviderManager.java create mode 100644 app/src/main/java/se/leap/bitmaskclient/ProviderRenderer.java create mode 100644 app/src/main/java/se/leap/bitmaskclient/ProviderRendererBuilder.java (limited to 'app/src/main/java') diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index c4f845b8..e1d08d08 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -71,9 +71,10 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf private TextView status_message; public ProviderAPIResultReceiver providerAPI_result_receiver; + private Provider provider; private static boolean authed_eip; - - @Override + + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -137,9 +138,12 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf updateEipService(); buildDashboard(false); invalidateOptionsMenu(); - if(data != null && data.hasExtra(LogInDialog.TAG)) { + if(data != null) + if(data.hasExtra(LogInDialog.TAG)) { logInDialog(Bundle.EMPTY); } + if(data.hasExtra(Provider.KEY)) + provider = data.getParcelableExtra(Provider.KEY); } else if(resultCode == RESULT_CANCELED && (data == null || data.hasExtra(ACTION_QUIT))) { finish(); } else @@ -180,9 +184,6 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf * service dependent UI elements to include. */ private void buildDashboard(boolean hide_and_turn_on_eip) { - Provider provider = Provider.getInstance(); - provider.init( this ); - setContentView(R.layout.client_dashboard); TextView providerNameTV = (TextView) findViewById(R.id.providerName); @@ -262,7 +263,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf startActivity(startLW); return true; case R.id.switch_provider: - if (Provider.getInstance().hasEIP()){ + if (provider.hasEIP()){ if (preferences.getBoolean(Constants.AUTHED_EIP, false)){ logOut(); } diff --git a/app/src/main/java/se/leap/bitmaskclient/Provider.java b/app/src/main/java/se/leap/bitmaskclient/Provider.java index bb30905c..5dd54175 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Provider.java +++ b/app/src/main/java/se/leap/bitmaskclient/Provider.java @@ -19,12 +19,16 @@ package se.leap.bitmaskclient; import android.app.Activity; import android.content.Context; import android.content.SharedPreferences; +import android.os.Parcel; +import android.os.Parcelable; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.Serializable; +import java.net.MalformedURLException; +import java.net.URL; import java.util.Arrays; import java.util.Locale; @@ -32,16 +36,11 @@ import java.util.Locale; * @author Sean Leonard * */ -public final class Provider implements Serializable { +public final class Provider implements Parcelable { - private static final long serialVersionUID = 6003835972151761353L; - - private static Provider instance = null; - - // We'll access our preferences here - private static SharedPreferences preferences = null; - // Represents our Provider's provider.json - private static JSONObject definition = null; + private JSONObject definition; // Represents our Provider's provider.json + private URL main_url; + private boolean is_custom = false; final public static String API_URL = "api_uri", @@ -69,54 +68,39 @@ public final class Provider implements Serializable { private static final String API_TERM_DEFAULT_LANGUAGE = "default_language"; protected static final String[] API_EIP_TYPES = {"openvpn"}; - private static final String PREFS_EIP_NAME = null; + public Provider(URL main_url) { + this.main_url = main_url; + } + public static final Parcelable.Creator CREATOR + = new Parcelable.Creator() { + public Provider createFromParcel(Parcel in) { + return new Provider(in); + } - - // What, no individual fields?! We're going to gamble on org.json.JSONObject and JSONArray - // Supporting multiple API versions will probably break this paradigm, - // Forcing me to write a real constructor and rewrite getters/setters - // Also will refactor if i'm instantiating the same local variables all the time - - /** - * - */ - private Provider() {} - - protected static Provider getInstance(){ - if(instance==null){ - instance = new Provider(); - } - return instance; - } + public Provider[] newArray(int size) { + return new Provider[size]; + } + }; - protected void init(Activity activity) { - - // Load our preferences from SharedPreferences - // If there's nothing there, we will end up returning a rather empty object - // to whoever called getInstance() and they can run the First Run Wizard - //preferences = context.getgetPreferences(0); // 0 == MODE_PRIVATE, but we don't extend Android's classes... - - // Load SharedPreferences - preferences = activity.getSharedPreferences(Dashboard.SHARED_PREFERENCES,Context.MODE_PRIVATE); - // Inflate our provider.json data - try { - definition = new JSONObject( preferences.getString(Provider.KEY, "") ); - } catch (JSONException e) { - // TODO: handle exception - - // FIXME!! We want "real" data!! - } - } + private Provider(Parcel in) { + try { + main_url = new URL(in.readString()); + definition = new JSONObject((in.readString())); + } catch (MalformedURLException e) { + e.printStackTrace(); + } catch (JSONException e) { + e.printStackTrace(); + } + } + + + protected void define(JSONObject provider_json) { + definition = provider_json; + } protected String getDomain(){ - String domain = ""; - try { - domain = definition.getString(API_TERM_DOMAIN); - } catch (JSONException e) { - e.printStackTrace(); - } - return domain; + return main_url.getHost(); } protected String getName(){ @@ -124,15 +108,12 @@ public final class Provider implements Serializable { String lang = Locale.getDefault().getLanguage(); String name = "Null"; // Should it actually /be/ null, for error conditions? try { - name = definition.getJSONObject(API_TERM_NAME).getString(lang); + if(definition != null) + name = definition.getJSONObject(API_TERM_NAME).getString(lang); + else throw new JSONException("Provider not defined"); } catch (JSONException e) { - // TODO: Nesting try/catch blocks? Crazy - // Maybe you should actually handle exception? - try { - name = definition.getJSONObject(API_TERM_NAME).getString( definition.getString(API_TERM_DEFAULT_LANGUAGE) ); - } catch (JSONException e2) { - // TODO: Will you handle the exception already? - } + String host = main_url.getHost(); + name = host.substring(0, host.indexOf(".")); } return name; @@ -177,4 +158,19 @@ public final class Provider implements Serializable { } return false; } + + protected boolean isCustom() { + return is_custom; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel parcel, int i) { + parcel.writeString(main_url.toString()); + parcel.writeString(definition.toString()); + } } diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderManager.java b/app/src/main/java/se/leap/bitmaskclient/ProviderManager.java new file mode 100644 index 00000000..59507d9c --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/ProviderManager.java @@ -0,0 +1,120 @@ +package se.leap.bitmaskclient; + +import android.content.res.AssetManager; + +import com.pedrogomez.renderers.AdapteeCollection; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +/** + * Created by parmegv on 4/12/14. + */ +public class ProviderManager implements AdapteeCollection { + + private AssetManager assets_manager; + private Set default_providers; + private Set custom_providers; + + final protected static String URLS = "urls"; + + public ProviderManager(AssetManager assets_manager) { + this.assets_manager = assets_manager; + default_providers = default_providers(); + custom_providers = new HashSet(); + } + + /** + * Loads providers data from url files contained in the assets folder + * @return true if the files were correctly read + */ + private Set default_providers() { + Set providers = new HashSet(); + try { + for(String file : assets_manager.list(URLS)) { + String main_url = extractProviderMainUrlFromAssetsFile(URLS + "/" + file); + providers.add(new Provider(new URL(main_url))); + } + } catch (MalformedURLException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + return providers; + } + + private String extractProviderMainUrlFromAssetsFile(String file_path) { + String provider_main_url = ""; + try { + InputStream input_stream_file_contents = assets_manager.open(file_path); + byte[] urls_file_bytes = new byte[input_stream_file_contents.available()]; + if(input_stream_file_contents.read(urls_file_bytes) > 0) { + String urls_file_content = new String(urls_file_bytes); + JSONObject file_contents = new JSONObject(urls_file_content); + provider_main_url = file_contents.getString(Provider.MAIN_URL); + } + } catch (JSONException e) { + } catch (IOException e) { + } + return provider_main_url; + } + + public Set providers() { + Set all_providers = new HashSet(); + all_providers.addAll(default_providers); + all_providers.addAll(custom_providers); + return all_providers; + } + + @Override + public int size() { + return providers().size(); + } + + @Override + public Provider get(int index) { + Iterator iterator = providers().iterator(); + while(iterator.hasNext() && index > 0) { + iterator.next(); + index--; + } + return iterator.next(); + } + + @Override + public void add(Provider element) { + custom_providers.add(element); + } + + @Override + public void remove(Provider element) { + custom_providers.remove(element); + } + + @Override + public void addAll(Collection elements) { + custom_providers.addAll(elements); + } + + @Override + public void removeAll(Collection elements) { + custom_providers.removeAll(elements); + default_providers.removeAll(elements); + } + + @Override + public void clear() { + default_providers.clear(); + custom_providers.clear(); + } +} diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderRenderer.java b/app/src/main/java/se/leap/bitmaskclient/ProviderRenderer.java new file mode 100644 index 00000000..2e376dee --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/ProviderRenderer.java @@ -0,0 +1,55 @@ +package se.leap.bitmaskclient; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import com.pedrogomez.renderers.Renderer; + +import butterknife.ButterKnife; +import butterknife.InjectView; + +/** + * Created by parmegv on 4/12/14. + */ +public class ProviderRenderer extends Renderer { + private final Context context; + + @InjectView(R.id.provider_name) + TextView name; + @InjectView(R.id.provider_domain) + TextView domain; + + public ProviderRenderer(Context context) { + this.context = context; + } + + @Override + protected View inflate(LayoutInflater inflater, ViewGroup parent) { + View view = inflater.inflate(R.layout.provider_list_item, parent, false); + ButterKnife.inject(this, view); + return view; + } + + @Override + protected void setUpView(View rootView) { + /* + * Empty implementation substituted with the usage of ButterKnife library by Jake Wharton. + */ + } + + @Override + protected void hookListeners(View rootView) { + //Empty + } + + @Override + public void render() { + Provider provider = getContent(); + name.setText(provider.getName()); + domain.setText(provider.getDomain()); + } +} diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderRendererBuilder.java b/app/src/main/java/se/leap/bitmaskclient/ProviderRendererBuilder.java new file mode 100644 index 00000000..7366e68e --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/ProviderRendererBuilder.java @@ -0,0 +1,25 @@ +package se.leap.bitmaskclient; + +import android.content.Context; + +import com.pedrogomez.renderers.Renderer; +import com.pedrogomez.renderers.RendererBuilder; + +import java.util.Collection; +import java.util.LinkedList; +import java.util.List; + +import javax.inject.Inject; + +/** + * Created by parmegv on 4/12/14. + */ + public class ProviderRendererBuilder extends RendererBuilder { + public ProviderRendererBuilder(Collection> prototypes) { + super(prototypes); + } + @Override + protected Class getPrototypeClass(Provider content) { + return ProviderRenderer.class; + } +} -- cgit v1.2.3