android: Use a local broadcast to notify about profile changes

This allows other components to modify the profiles and notify about
changes.
This commit is contained in:
Tobias Brunner 2016-12-29 17:02:22 +01:00
parent c4ab9af74e
commit cf6110f152
3 changed files with 107 additions and 47 deletions

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

View File

@ -17,12 +17,14 @@
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;

View File

@ -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;
}