android: Use a local broadcast to notify about profile changes
authorTobias Brunner <tobias@strongswan.org>
Thu, 29 Dec 2016 16:02:22 +0000 (17:02 +0100)
committerTobias Brunner <tobias@strongswan.org>
Fri, 20 Jan 2017 10:01:32 +0000 (11:01 +0100)
This allows other components to modify the profiles and notify about
changes.

src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileDetailActivity.java
src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileListFragment.java
src/frontends/android/app/src/main/java/org/strongswan/android/utils/Constants.java [new file with mode: 0644]

index 6405c0d..bf64370 100644 (file)
@@ -26,6 +26,7 @@ import android.os.Bundle;
 import android.security.KeyChain;
 import android.security.KeyChainAliasCallback;
 import android.security.KeyChainException;
+import android.support.v4.content.LocalBroadcastManager;
 import android.support.v7.app.AlertDialog;
 import android.support.v7.app.AppCompatActivity;
 import android.support.v7.app.AppCompatDialogFragment;
@@ -63,6 +64,7 @@ import org.strongswan.android.logic.TrustedCertificateManager;
 import org.strongswan.android.security.TrustedCertificateEntry;
 import org.strongswan.android.ui.adapter.CertificateIdentitiesAdapter;
 import org.strongswan.android.ui.widget.TextInputLayoutHelper;
+import org.strongswan.android.utils.Constants;
 
 import java.security.cert.X509Certificate;
 import java.util.UUID;
@@ -70,8 +72,6 @@ import java.util.UUID;
 public class VpnProfileDetailActivity extends AppCompatActivity
 {
        private static final int SELECT_TRUSTED_CERTIFICATE = 0;
-       private static final int MTU_MIN = 1280;
-       private static final int MTU_MAX = 1500;
 
        private VpnProfileDataSource mDataSource;
        private Long mId;
@@ -466,6 +466,10 @@ public class VpnProfileDetailActivity extends AppCompatActivity
                                updateProfileData();
                                mDataSource.insertProfile(mProfile);
                        }
+                       Intent intent = new Intent(Constants.VPN_PROFILES_CHANGED);
+                       intent.putExtra(Constants.VPN_PROFILES_SINGLE, mProfile.getId());
+                       LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
+
                        setResult(RESULT_OK, new Intent().putExtra(VpnProfileDataSource.KEY_ID, mProfile.getId()));
                        finish();
                }
@@ -501,9 +505,9 @@ public class VpnProfileDetailActivity extends AppCompatActivity
                        showCertificateAlert();
                        valid = false;
                }
-               if (!validateInteger(mMTU, MTU_MIN, MTU_MAX))
+               if (!validateInteger(mMTU, Constants.MTU_MIN, Constants.MTU_MAX))
                {
-                       mMTUWrap.setError(String.format(getString(R.string.alert_text_out_of_range), MTU_MIN, MTU_MAX));
+                       mMTUWrap.setError(String.format(getString(R.string.alert_text_out_of_range), Constants.MTU_MIN, Constants.MTU_MAX));
                        valid = false;
                }
                if (!validateInteger(mPort, 1, 65535))
@@ -572,8 +576,8 @@ public class VpnProfileDetailActivity extends AppCompatActivity
                                mRemoteId.setText(mProfile.getRemoteId());
                                mMTU.setText(mProfile.getMTU() != null ? mProfile.getMTU().toString() : null);
                                mPort.setText(mProfile.getPort() != null ? mProfile.getPort().toString() : null);
-                               mBlockIPv4.setChecked(mProfile.getSplitTunneling() != null ? (mProfile.getSplitTunneling() & VpnProfile.SPLIT_TUNNELING_BLOCK_IPV4) != 0 : false);
-                               mBlockIPv6.setChecked(mProfile.getSplitTunneling() != null ? (mProfile.getSplitTunneling() & VpnProfile.SPLIT_TUNNELING_BLOCK_IPV6) != 0 : false);
+                               mBlockIPv4.setChecked(mProfile.getSplitTunneling() != null && (mProfile.getSplitTunneling() & VpnProfile.SPLIT_TUNNELING_BLOCK_IPV4) != 0);
+                               mBlockIPv6.setChecked(mProfile.getSplitTunneling() != null && (mProfile.getSplitTunneling() & VpnProfile.SPLIT_TUNNELING_BLOCK_IPV6) != 0);
                                useralias = mProfile.getUserCertificateAlias();
                                local_id = mProfile.getLocalId();
                                alias = mProfile.getCertificateAlias();
@@ -691,11 +695,7 @@ public class VpnProfileDetailActivity extends AppCompatActivity
                                                }
                                        });
                                }
-                               catch (KeyChainException e)
-                               {
-                                       e.printStackTrace();
-                               }
-                               catch (InterruptedException e)
+                               catch (KeyChainException | InterruptedException e)
                                {
                                        e.printStackTrace();
                                }
@@ -727,11 +727,7 @@ public class VpnProfileDetailActivity extends AppCompatActivity
                        {
                                chain = KeyChain.getCertificateChain(mContext, mAlias);
                        }
-                       catch (KeyChainException e)
-                       {
-                               e.printStackTrace();
-                       }
-                       catch (InterruptedException e)
+                       catch (KeyChainException | InterruptedException e)
                        {
                                e.printStackTrace();
                        }
index d8d99ff..8210d59 100644 (file)
 
 package org.strongswan.android.ui;
 
-import android.app.Activity;
+import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.res.TypedArray;
 import android.os.Bundle;
 import android.support.v4.app.Fragment;
+import android.support.v4.content.LocalBroadcastManager;
 import android.util.AttributeSet;
 import android.view.ActionMode;
 import android.view.LayoutInflater;
@@ -41,9 +43,11 @@ import org.strongswan.android.R;
 import org.strongswan.android.data.VpnProfile;
 import org.strongswan.android.data.VpnProfileDataSource;
 import org.strongswan.android.ui.adapter.VpnProfileAdapter;
+import org.strongswan.android.utils.Constants;
 
 import java.util.ArrayList;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 
 public class VpnProfileListFragment extends Fragment
@@ -58,11 +62,47 @@ public class VpnProfileListFragment extends Fragment
        private OnVpnProfileSelectedListener mListener;
        private boolean mReadOnly;
 
+       private BroadcastReceiver mProfilesChanged = new BroadcastReceiver()
+       {
+               @Override
+               public void onReceive(Context context, Intent intent)
+               {
+                       long id, ids[];
+                       if ((id = intent.getLongExtra(Constants.VPN_PROFILES_SINGLE, 0)) > 0)
+                       {
+                               VpnProfile profile = mDataSource.getVpnProfile(id);
+                               if (profile != null)
+                               {       /* in case this was an edit, we remove it first */
+                                       mVpnProfiles.remove(profile);
+                                       mVpnProfiles.add(profile);
+                                       mListAdapter.notifyDataSetChanged();
+                               }
+                       }
+                       else if ((ids = intent.getLongArrayExtra(Constants.VPN_PROFILES_MULTIPLE)) != null)
+                       {
+                               for (long i : ids)
+                               {
+                                       Iterator<VpnProfile> profiles = mVpnProfiles.iterator();
+                                       while (profiles.hasNext())
+                                       {
+                                               VpnProfile profile = profiles.next();
+                                               if (profile.getId() == i)
+                                               {
+                                                       profiles.remove();
+                                                       break;
+                                               }
+                                       }
+                               }
+                               mListAdapter.notifyDataSetChanged();
+                       }
+               }
+       };
+
        /**
         * The activity containing this fragment should implement this interface
         */
        public interface OnVpnProfileSelectedListener {
-               public void onVpnProfileSelected(VpnProfile profile);
+               void onVpnProfileSelected(VpnProfile profile);
        }
 
        @Override
@@ -116,6 +156,9 @@ public class VpnProfileListFragment extends Fragment
                mVpnProfiles = mDataSource.getAllVpnProfiles();
 
                mListAdapter = new VpnProfileAdapter(getActivity(), R.layout.profile_list_item, mVpnProfiles);
+
+               IntentFilter profileChangesFilter = new IntentFilter(Constants.VPN_PROFILES_CHANGED);
+               LocalBroadcastManager.getInstance(getActivity()).registerReceiver(mProfilesChanged, profileChangesFilter);
        }
 
        @Override
@@ -123,6 +166,7 @@ public class VpnProfileListFragment extends Fragment
        {
                super.onDestroy();
                mDataSource.close();
+               LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(mProfilesChanged);
        }
 
        @Override
@@ -157,30 +201,6 @@ public class VpnProfileListFragment extends Fragment
                }
        }
 
-       @Override
-       public void onActivityResult(int requestCode, int resultCode, Intent data)
-       {
-               switch (requestCode)
-               {
-                       case ADD_REQUEST:
-                       case EDIT_REQUEST:
-                               if (resultCode != Activity.RESULT_OK)
-                               {
-                                       return;
-                               }
-                               long id = data.getLongExtra(VpnProfileDataSource.KEY_ID, 0);
-                               VpnProfile profile = mDataSource.getVpnProfile(id);
-                               if (profile != null)
-                               {       /* in case this was an edit, we remove it first */
-                                       mVpnProfiles.remove(profile);
-                                       mVpnProfiles.add(profile);
-                                       mListAdapter.notifyDataSetChanged();
-                               }
-                               return;
-               }
-               super.onActivityResult(requestCode, resultCode, data);
-       }
-
        private final OnItemClickListener mVpnProfileClicked = new OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> a, View v, int position, long id)
@@ -213,7 +233,7 @@ public class VpnProfileListFragment extends Fragment
                        MenuInflater inflater = mode.getMenuInflater();
                        inflater.inflate(R.menu.profile_list_context, menu);
                        mEditProfile = menu.findItem(R.id.edit_profile);
-                       mSelected = new HashSet<Integer>();
+                       mSelected = new HashSet<>();
                        mode.setTitle(R.string.select_profiles);
                        return true;
                }
@@ -234,17 +254,21 @@ public class VpnProfileListFragment extends Fragment
                                }
                                case R.id.delete_profile:
                                {
-                                       ArrayList<VpnProfile> profiles = new ArrayList<VpnProfile>();
+                                       ArrayList<VpnProfile> profiles = new ArrayList<>();
                                        for (int position : mSelected)
                                        {
                                                profiles.add((VpnProfile)mListView.getItemAtPosition(position));
                                        }
-                                       for (VpnProfile profile : profiles)
+                                       long ids[] = new long[profiles.size()];
+                                       for (int i = 0; i < profiles.size(); i++)
                                        {
+                                               VpnProfile profile = profiles.get(i);
+                                               ids[i] = profile.getId();
                                                mDataSource.deleteVpnProfile(profile);
-                                               mVpnProfiles.remove(profile);
                                        }
-                                       mListAdapter.notifyDataSetChanged();
+                                       Intent intent = new Intent(Constants.VPN_PROFILES_CHANGED);
+                                       intent.putExtra(Constants.VPN_PROFILES_MULTIPLE, ids);
+                                       LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(intent);
                                        Toast.makeText(VpnProfileListFragment.this.getActivity(),
                                                                   R.string.profiles_deleted, Toast.LENGTH_SHORT).show();
                                        break;
diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/utils/Constants.java b/src/frontends/android/app/src/main/java/org/strongswan/android/utils/Constants.java
new file mode 100644 (file)
index 0000000..413ecae
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2016 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+package org.strongswan.android.utils;
+
+public final class Constants
+{
+       /**
+        * Intent action used to notify about changes to the VPN profiles
+        */
+       public static final String VPN_PROFILES_CHANGED = "org.strongswan.android.VPN_PROFILES_CHANGED";
+
+       /**
+        * Used in the intent above to notify about edits or inserts of a VPN profile (long)
+        */
+       public static final String VPN_PROFILES_SINGLE = "org.strongswan.android.VPN_PROFILES_SINGLE";
+
+       /**
+        * Used in the intent above to notify about the deletion of multiple VPN profiles (array of longs)
+        */
+       public static final String VPN_PROFILES_MULTIPLE = "org.strongswan.android.VPN_PROFILES_MULTIPLE";
+
+       /**
+        * Limits for MTU
+        */
+       public static final int MTU_MAX = 1500;
+       public static final int MTU_MIN = 1280;
+}