From bd882a9f164010da32751570c2e09647fbbba887 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Fri, 4 Aug 2017 12:24:18 -0500 Subject: ProfileList: Convert to a fragment This is required for a future two-fragment tablet layout, and simplifies the code a bit since the profile detail (view/edit) will be implemented as fragments anyway. --- .../com/wireguard/android/ProfileActivity.java | 96 ++++++++++++++++++++++ .../com/wireguard/android/ProfileListActivity.java | 87 -------------------- .../com/wireguard/android/ProfileListFragment.java | 76 +++++++++++++++++ .../android/ServiceConnectionListener.java | 11 +++ 4 files changed, 183 insertions(+), 87 deletions(-) create mode 100644 app/src/main/java/com/wireguard/android/ProfileActivity.java delete mode 100644 app/src/main/java/com/wireguard/android/ProfileListActivity.java create mode 100644 app/src/main/java/com/wireguard/android/ProfileListFragment.java create mode 100644 app/src/main/java/com/wireguard/android/ServiceConnectionListener.java (limited to 'app/src/main/java') diff --git a/app/src/main/java/com/wireguard/android/ProfileActivity.java b/app/src/main/java/com/wireguard/android/ProfileActivity.java new file mode 100644 index 00000000..5daaf54c --- /dev/null +++ b/app/src/main/java/com/wireguard/android/ProfileActivity.java @@ -0,0 +1,96 @@ +package com.wireguard.android; + +import android.app.Activity; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.ServiceConnection; +import android.os.Bundle; +import android.os.IBinder; +import android.view.Menu; +import android.view.MenuItem; + +import com.wireguard.config.Profile; + +import java.util.ArrayList; +import java.util.List; + +/** + * Activity that allows creating/viewing/editing/deleting WireGuard profiles. + */ + +public class ProfileActivity extends Activity { + private final ServiceConnection connection = new ProfileServiceConnection(); + private final List listeners = new ArrayList<>(); + private ProfileServiceInterface service; + + public void addServiceConnectionListener(ServiceConnectionListener listener) { + listeners.add(listener); + } + + public ProfileServiceInterface getService() { + return service; + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.profile_activity); + // Ensure the long-running service is started. This only needs to happen once. + Intent intent = new Intent(this, ProfileService.class); + startService(intent); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.main, menu); + return true; + } + + public void onMenuSettings(MenuItem item) { + + } + + public void onProfileSelected(Profile profile) { + + } + + @Override + public void onStart() { + super.onStart(); + Intent intent = new Intent(this, ProfileService.class); + bindService(intent, connection, Context.BIND_AUTO_CREATE); + } + + @Override + public void onStop() { + super.onStop(); + if (service != null) { + unbindService(connection); + for (ServiceConnectionListener listener : listeners) + listener.onServiceDisconnected(); + service = null; + } + } + + public void removeServiceConnectionListener(ServiceConnectionListener listener) { + listeners.remove(listener); + } + + private class ProfileServiceConnection implements ServiceConnection { + @Override + public void onServiceConnected(ComponentName component, IBinder binder) { + service = (ProfileServiceInterface) binder; + for (ServiceConnectionListener listener : listeners) + listener.onServiceConnected(service); + } + + @Override + public void onServiceDisconnected(ComponentName component) { + // This function is only called when the service crashes or goes away unexpectedly. + for (ServiceConnectionListener listener : listeners) + listener.onServiceDisconnected(); + service = null; + } + } +} diff --git a/app/src/main/java/com/wireguard/android/ProfileListActivity.java b/app/src/main/java/com/wireguard/android/ProfileListActivity.java deleted file mode 100644 index 6114cf1a..00000000 --- a/app/src/main/java/com/wireguard/android/ProfileListActivity.java +++ /dev/null @@ -1,87 +0,0 @@ -package com.wireguard.android; - -import android.app.Activity; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.ServiceConnection; -import android.databinding.DataBindingUtil; -import android.os.Bundle; -import android.os.IBinder; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.widget.AdapterView; -import android.widget.ListView; - -import com.wireguard.android.databinding.ProfileListActivityBinding; -import com.wireguard.config.Profile; - -public class ProfileListActivity extends Activity { - private final ServiceConnection connection = new ProfileServiceConnection(); - private ProfileListActivityBinding binding; - private ProfileServiceInterface service; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - binding = DataBindingUtil.setContentView(this, R.layout.profile_list_activity); - // Ensure the long-running service is started. This only needs to happen once. - Intent intent = new Intent(this, ProfileService.class); - startService(intent); - - ListView listView = findViewById(R.id.profile_list); - listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { - @Override - public void onItemClick(AdapterView parent, View view, int position, long id) { - Profile profile = (Profile) parent.getItemAtPosition(position); - if (profile == null || service == null) - return; - if (profile.getIsConnected()) - service.disconnectProfile(profile); - else - service.connectProfile(profile); - } - }); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.profile_list, menu); - return true; - } - - public void onMenuSettings(MenuItem item) { - - } - - @Override - public void onStart() { - super.onStart(); - Intent intent = new Intent(this, ProfileService.class); - bindService(intent, connection, Context.BIND_AUTO_CREATE); - } - - @Override - public void onStop() { - super.onStop(); - if (service != null) { - unbindService(connection); - service = null; - } - } - - private class ProfileServiceConnection implements ServiceConnection { - @Override - public void onServiceConnected(ComponentName component, IBinder binder) { - service = (ProfileServiceInterface) binder; - binding.setProfiles(service.getProfiles()); - } - - @Override - public void onServiceDisconnected(ComponentName component) { - // This function is only called when the service crashes or goes away unexpectedly. - service = null; - } - } -} diff --git a/app/src/main/java/com/wireguard/android/ProfileListFragment.java b/app/src/main/java/com/wireguard/android/ProfileListFragment.java new file mode 100644 index 00000000..1dfa9b77 --- /dev/null +++ b/app/src/main/java/com/wireguard/android/ProfileListFragment.java @@ -0,0 +1,76 @@ +package com.wireguard.android; + +import android.app.Fragment; +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.ListView; + +import com.wireguard.android.databinding.ProfileListFragmentBinding; +import com.wireguard.config.Profile; + +/** + * Fragment containing the list of available WireGuard profiles. Must be part of a ProfileActivity. + */ + +public class ProfileListFragment extends Fragment implements ServiceConnectionListener { + private ProfileActivity activity; + private ProfileListFragmentBinding binding; + private ProfileServiceInterface service; + + @Override + public void onAttach(Context context) { + super.onAttach(context); + activity = (ProfileActivity) context; + activity.addServiceConnectionListener(this); + service = activity.getService(); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) { + binding = ProfileListFragmentBinding.inflate(inflater, parent, false); + final ListView listView = (ListView) binding.getRoot(); + listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + final Profile profile = (Profile) parent.getItemAtPosition(position); + ((ProfileActivity) getActivity()).onProfileSelected(profile); + } + }); + listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { + @Override + public boolean onItemLongClick(AdapterView parent, View view, int position, + long id) { + final Profile profile = (Profile) parent.getItemAtPosition(position); + if (profile == null || service == null) + return false; + if (profile.getIsConnected()) + service.disconnectProfile(profile); + else + service.connectProfile(profile); + return true; + } + }); + return binding.getRoot(); + } + + @Override + public void onDetach() { + super.onDetach(); + activity.removeServiceConnectionListener(this); + } + + @Override + public void onServiceConnected(ProfileServiceInterface service) { + this.service = service; + binding.setProfiles(service.getProfiles()); + } + + @Override + public void onServiceDisconnected() { + service = null; + } +} diff --git a/app/src/main/java/com/wireguard/android/ServiceConnectionListener.java b/app/src/main/java/com/wireguard/android/ServiceConnectionListener.java new file mode 100644 index 00000000..5f3c8d0a --- /dev/null +++ b/app/src/main/java/com/wireguard/android/ServiceConnectionListener.java @@ -0,0 +1,11 @@ +package com.wireguard.android; + +/** + * Interface for fragments that need notification about connection changes to the ProfileService. + */ + +interface ServiceConnectionListener { + void onServiceConnected(ProfileServiceInterface service); + + void onServiceDisconnected(); +} -- cgit v1.2.3