diff options
author | Fup Duck <fupduck@sacknagel.com> | 2018-02-16 10:38:41 +0100 |
---|---|---|
committer | Fup Duck <fupduck@sacknagel.com> | 2018-02-16 10:38:41 +0100 |
commit | 9108878992e9825a00c44f0596818d0ab245b183 (patch) | |
tree | 088b116ca4b1236827337a3d5ae204abc0f907bb /app | |
parent | 6c1434addf1ee25a8c7ce30c240e2033d5075f35 (diff) | |
parent | 0365f243fc56112b2f43b35e1b4884d2d1ad2aa4 (diff) |
Merge branch 'leap_0.9.8' into #8797_certificate_expiration
Diffstat (limited to 'app')
29 files changed, 18 insertions, 1831 deletions
diff --git a/app/build.gradle b/app/build.gradle index 3e4862ca..5422b5e4 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -109,8 +109,6 @@ dependencies { implementation 'com.intellij:annotations:12.0' implementation 'com.google.code.gson:gson:2.8.2' implementation 'com.squareup.okhttp3:okhttp:3.9.0' - //TODO: remove that library - implementation 'mbanje.kurt:fabbutton:1.1.4' implementation "com.android.support:support-core-utils:27.0.2" implementation 'com.android.support:support-annotations:27.0.2' implementation 'com.android.support:support-v4:27.0.2' @@ -151,8 +149,6 @@ task copyIcsOpenVPNClasses( type: Copy ) { include '**/VpnProfile.java' include '**/DisconnectVPN.java' include '**/VpnProfile.java' - include '**/LogWindow.java' - include '**/LogFragment.java' include '**/SeekBarTicks.java' include '**/core/**.java' include '**/activities/BaseActivity.java' @@ -177,16 +173,10 @@ task copyIcsOpenVPNClasses( type: Copy ) { task copyIcsOpenVPNXml( type: Copy ) { println "copyIcsOpenVPNXml" from ('../ics-openvpn/main/') { - include '**/log_window.xml' - include '**/log_fragment.xml' - include '**/log_silders.xml' include '**/vpnstatus.xml' - include '**/logmenu.xml' include '**/strings.xml' - include '**/log_*.xml' include '**/vpnstatus.xml' include '**/refs.xml' - include '**/logmenu.xml' include '**/white_rect.xml' include '**/plurals.xml' includeEmptyDirs = false diff --git a/app/src/androidTest/legacy/BaseTestDashboardFragment.java b/app/src/androidTest/legacy/BaseTestDashboardFragment.java index e187d424..4730cecc 100644 --- a/app/src/androidTest/legacy/BaseTestDashboardFragment.java +++ b/app/src/androidTest/legacy/BaseTestDashboardFragment.java @@ -8,7 +8,6 @@ import android.view.View; import com.robotium.solo.Solo; import se.leap.bitmaskclient.ProviderListActivity; -import se.leap.bitmaskclient.Dashboard; import se.leap.bitmaskclient.R; public abstract class BaseTestDashboardFragment extends ActivityInstrumentationTestCase2<Dashboard> { diff --git a/app/src/androidTest/legacy/VpnTestController.java b/app/src/androidTest/legacy/VpnTestController.java index 4c6a6370..e39ebae3 100644 --- a/app/src/androidTest/legacy/VpnTestController.java +++ b/app/src/androidTest/legacy/VpnTestController.java @@ -8,9 +8,7 @@ import com.robotium.solo.Solo; import de.blinkt.openvpn.activities.DisconnectVPN; import mbanje.kurt.fabbutton.ProgressRingView; -import se.leap.bitmaskclient.Dashboard; import se.leap.bitmaskclient.R; -import se.leap.bitmaskclient.userstatus.FabButton; import static junit.framework.Assert.assertTrue; diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index f60a2db6..4e7f8348 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -70,11 +70,6 @@ android:name="de.blinkt.openvpn.LaunchVPN" android:label="@string/vpn_launch_title" /> <activity - android:name=".Dashboard" - android:label="@string/app_name" - android:launchMode="singleTop" - android:uiOptions="splitActionBarWhenNarrow" /> - <activity android:name=".StartActivity" android:label="@string/app_name" android:launchMode="singleTop" diff --git a/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java b/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java index b2bf6b46..e83cffa0 100644 --- a/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java +++ b/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java @@ -21,13 +21,12 @@ import android.os.Bundle; import java.io.IOException; -import de.blinkt.openvpn.activities.LogWindow; import de.blinkt.openvpn.core.ConnectionStatus; import de.blinkt.openvpn.core.Preferences; import de.blinkt.openvpn.core.ProfileManager; import de.blinkt.openvpn.core.VPNLaunchHelper; import de.blinkt.openvpn.core.VpnStatus; -import se.leap.bitmaskclient.R; +import se.leap.bitmaskclient.MainActivity; /** * This Activity actually handles two stages of a launcher shortcut's life cycle. @@ -143,7 +142,8 @@ public class LaunchVPN extends Activity { void showLogWindow() { - Intent startLW = new Intent(getBaseContext(), LogWindow.class); + Intent startLW = new Intent(getBaseContext(), MainActivity.class); + startLW.putExtra(MainActivity.ACTION_SHOW_LOG_FRAGMENT, true); startLW.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); startActivity(startLW); diff --git a/app/src/main/java/de/blinkt/openvpn/activities/LogWindow.java b/app/src/main/java/de/blinkt/openvpn/activities/LogWindow.java deleted file mode 100644 index 130084f5..00000000 --- a/app/src/main/java/de/blinkt/openvpn/activities/LogWindow.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2012-2016 Arne Schwabe - * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - */ - -package de.blinkt.openvpn.activities; - -import android.app.Activity; -import android.os.Bundle; -import android.view.MenuItem; - -import se.leap.bitmaskclient.R; -import de.blinkt.openvpn.fragments.LogFragment; - -/** - * Created by arne on 13.10.13. - */ -public class LogWindow extends BaseActivity { - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.log_window); - getActionBar().setDisplayHomeAsUpEnabled(true); - - if (savedInstanceState == null) { - getFragmentManager().beginTransaction() - .add(R.id.container, new LogFragment()) - .commit(); - } - - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - return super.onOptionsItemSelected(item); - } -} diff --git a/app/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java b/app/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java deleted file mode 100644 index 1a207a25..00000000 --- a/app/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java +++ /dev/null @@ -1,694 +0,0 @@ -/* - * Copyright (c) 2012-2016 Arne Schwabe - * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - */ - -package de.blinkt.openvpn.fragments; - -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.animation.ObjectAnimator; -import android.app.Activity; -import android.app.AlertDialog; -import android.app.ListFragment; -import android.content.ClipData; -import android.content.ClipboardManager; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.res.Resources; -import android.database.DataSetObserver; -import android.graphics.drawable.Drawable; -import android.os.Bundle; -import android.os.Handler; -import android.os.Handler.Callback; -import android.os.Message; -import android.preference.PreferenceManager; -import android.support.annotation.Nullable; -import android.text.SpannableString; -import android.text.format.DateFormat; -import android.text.style.ImageSpan; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AdapterView; -import android.widget.AdapterView.OnItemLongClickListener; -import android.widget.CheckBox; -import android.widget.CompoundButton; -import android.widget.LinearLayout; -import android.widget.ListAdapter; -import android.widget.ListView; -import android.widget.RadioGroup; -import android.widget.SeekBar; -import android.widget.TextView; -import android.widget.Toast; - -import java.text.SimpleDateFormat; -import java.util.Collections; -import java.util.Date; -import java.util.Locale; -import java.util.Vector; - -import de.blinkt.openvpn.LaunchVPN; -import se.leap.bitmaskclient.R; -import de.blinkt.openvpn.VpnProfile; -import de.blinkt.openvpn.activities.DisconnectVPN; -import de.blinkt.openvpn.core.ConnectionStatus; -import de.blinkt.openvpn.core.OpenVPNManagement; -import de.blinkt.openvpn.core.OpenVPNService; -import de.blinkt.openvpn.core.Preferences; -import de.blinkt.openvpn.core.ProfileManager; -import de.blinkt.openvpn.core.VpnStatus; -import de.blinkt.openvpn.core.LogItem; -import de.blinkt.openvpn.core.VpnStatus.LogListener; -import de.blinkt.openvpn.core.VpnStatus.StateListener; - -import static de.blinkt.openvpn.core.OpenVPNService.humanReadableByteCount; - -import se.leap.bitmaskclient.Dashboard; - -public class LogFragment extends ListFragment implements StateListener, SeekBar.OnSeekBarChangeListener, RadioGroup.OnCheckedChangeListener, VpnStatus.ByteCountListener { - private static final String LOGTIMEFORMAT = "logtimeformat"; - private static final int START_VPN_CONFIG = 0; - private static final String VERBOSITYLEVEL = "verbositylevel"; - - - - private SeekBar mLogLevelSlider; - private LinearLayout mOptionsLayout; - private RadioGroup mTimeRadioGroup; - private TextView mUpStatus; - private TextView mDownStatus; - private TextView mConnectStatus; - private boolean mShowOptionsLayout; - private CheckBox mClearLogCheckBox; - - @Override - public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - ladapter.setLogLevel(progress + 1); - } - - @Override - public void onStartTrackingTouch(SeekBar seekBar) { - } - - @Override - public void onStopTrackingTouch(SeekBar seekBar) { - } - - @Override - public void onCheckedChanged(RadioGroup group, int checkedId) { - switch (checkedId) { - case R.id.radioISO: - ladapter.setTimeFormat(LogWindowListAdapter.TIME_FORMAT_ISO); - break; - case R.id.radioNone: - ladapter.setTimeFormat(LogWindowListAdapter.TIME_FORMAT_NONE); - break; - case R.id.radioShort: - ladapter.setTimeFormat(LogWindowListAdapter.TIME_FORMAT_SHORT); - break; - - } - } - - @Override - public void updateByteCount(long in, long out, long diffIn, long diffOut) { - //%2$s/s %1$s - ↑%4$s/s %3$s - Resources res = getActivity().getResources(); - final String down = String.format("%2$s %1$s", humanReadableByteCount(in, false, res), humanReadableByteCount(diffIn / OpenVPNManagement.mBytecountInterval, true, res)); - final String up = String.format("%2$s %1$s", humanReadableByteCount(out, false, res), humanReadableByteCount(diffOut / OpenVPNManagement.mBytecountInterval, true, res)); - - if (mUpStatus != null && mDownStatus != null) { - if (getActivity() != null) { - getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - mUpStatus.setText(up); - mDownStatus.setText(down); - } - }); - } - } - - } - - - class LogWindowListAdapter implements ListAdapter, LogListener, Callback { - - private static final int MESSAGE_NEWLOG = 0; - - private static final int MESSAGE_CLEARLOG = 1; - - private static final int MESSAGE_NEWTS = 2; - private static final int MESSAGE_NEWLOGLEVEL = 3; - - public static final int TIME_FORMAT_NONE = 0; - public static final int TIME_FORMAT_SHORT = 1; - public static final int TIME_FORMAT_ISO = 2; - private static final int MAX_STORED_LOG_ENTRIES = 1000; - - private Vector<LogItem> allEntries = new Vector<>(); - - private Vector<LogItem> currentLevelEntries = new Vector<LogItem>(); - - private Handler mHandler; - - private Vector<DataSetObserver> observers = new Vector<DataSetObserver>(); - - private int mTimeFormat = 0; - private int mLogLevel = 3; - - - public LogWindowListAdapter() { - initLogBuffer(); - if (mHandler == null) { - mHandler = new Handler(this); - } - - VpnStatus.addLogListener(this); - } - - - private void initLogBuffer() { - allEntries.clear(); - Collections.addAll(allEntries, VpnStatus.getlogbuffer()); - initCurrentMessages(); - } - - String getLogStr() { - String str = ""; - for (LogItem entry : allEntries) { - str += getTime(entry, TIME_FORMAT_ISO) + entry.getString(getActivity()) + '\n'; - } - return str; - } - - - private void shareLog() { - Intent shareIntent = new Intent(Intent.ACTION_SEND); - shareIntent.putExtra(Intent.EXTRA_TEXT, getLogStr()); - shareIntent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.ics_openvpn_log_file)); - shareIntent.setType("text/plain"); - startActivity(Intent.createChooser(shareIntent, "Send Logfile")); - } - - @Override - public void registerDataSetObserver(DataSetObserver observer) { - observers.add(observer); - - } - - @Override - public void unregisterDataSetObserver(DataSetObserver observer) { - observers.remove(observer); - } - - @Override - public int getCount() { - return currentLevelEntries.size(); - } - - @Override - public Object getItem(int position) { - return currentLevelEntries.get(position); - } - - @Override - public long getItemId(int position) { - return ((Object) currentLevelEntries.get(position)).hashCode(); - } - - @Override - public boolean hasStableIds() { - return true; - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - TextView v; - if (convertView == null) - v = new TextView(getActivity()); - else - v = (TextView) convertView; - - LogItem le = currentLevelEntries.get(position); - String msg = le.getString(getActivity()); - String time = getTime(le, mTimeFormat); - msg = time + msg; - - int spanStart = time.length(); - - SpannableString t = new SpannableString(msg); - - //t.setSpan(getSpanImage(le,(int)v.getTextSize()),spanStart,spanStart+1, Spanned.SPAN_INCLUSIVE_INCLUSIVE); - v.setText(t); - return v; - } - - private String getTime(LogItem le, int time) { - if (time != TIME_FORMAT_NONE) { - Date d = new Date(le.getLogtime()); - java.text.DateFormat timeformat; - if (time == TIME_FORMAT_ISO) - timeformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()); - else - timeformat = DateFormat.getTimeFormat(getActivity()); - - return timeformat.format(d) + " "; - - } else { - return ""; - } - - } - - private ImageSpan getSpanImage(LogItem li, int imageSize) { - int imageRes = android.R.drawable.ic_menu_call; - - switch (li.getLogLevel()) { - case ERROR: - imageRes = android.R.drawable.ic_notification_clear_all; - break; - case INFO: - imageRes = android.R.drawable.ic_menu_compass; - break; - case VERBOSE: - imageRes = android.R.drawable.ic_menu_info_details; - break; - case WARNING: - imageRes = android.R.drawable.ic_menu_camera; - break; - } - - Drawable d = getResources().getDrawable(imageRes); - - - //d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight()); - d.setBounds(0, 0, imageSize, imageSize); - ImageSpan span = new ImageSpan(d, ImageSpan.ALIGN_BOTTOM); - - return span; - } - - @Override - public int getItemViewType(int position) { - return 0; - } - - @Override - public int getViewTypeCount() { - return 1; - } - - @Override - public boolean isEmpty() { - return currentLevelEntries.isEmpty(); - - } - - @Override - public boolean areAllItemsEnabled() { - return true; - } - - @Override - public boolean isEnabled(int position) { - return true; - } - - @Override - public void newLog(LogItem logMessage) { - Message msg = Message.obtain(); - assert (msg != null); - msg.what = MESSAGE_NEWLOG; - Bundle bundle = new Bundle(); - bundle.putParcelable("logmessage", logMessage); - msg.setData(bundle); - mHandler.sendMessage(msg); - } - - @Override - public boolean handleMessage(Message msg) { - // We have been called - if (msg.what == MESSAGE_NEWLOG) { - - LogItem logMessage = msg.getData().getParcelable("logmessage"); - if (addLogMessage(logMessage)) - for (DataSetObserver observer : observers) { - observer.onChanged(); - } - } else if (msg.what == MESSAGE_CLEARLOG) { - for (DataSetObserver observer : observers) { - observer.onInvalidated(); - } - initLogBuffer(); - } else if (msg.what == MESSAGE_NEWTS) { - for (DataSetObserver observer : observers) { - observer.onInvalidated(); - } - } else if (msg.what == MESSAGE_NEWLOGLEVEL) { - initCurrentMessages(); - - for (DataSetObserver observer : observers) { - observer.onChanged(); - } - - } - - return true; - } - - private void initCurrentMessages() { - currentLevelEntries.clear(); - for (LogItem li : allEntries) { - if (li.getVerbosityLevel() <= mLogLevel || - mLogLevel == VpnProfile.MAXLOGLEVEL) - currentLevelEntries.add(li); - } - } - - /** - * @param logmessage - * @return True if the current entries have changed - */ - private boolean addLogMessage(LogItem logmessage) { - allEntries.add(logmessage); - - if (allEntries.size() > MAX_STORED_LOG_ENTRIES) { - Vector<LogItem> oldAllEntries = allEntries; - allEntries = new Vector<LogItem>(allEntries.size()); - for (int i = 50; i < oldAllEntries.size(); i++) { - allEntries.add(oldAllEntries.elementAt(i)); - } - initCurrentMessages(); - return true; - } else { - if (logmessage.getVerbosityLevel() <= mLogLevel) { - currentLevelEntries.add(logmessage); - return true; - } else { - return false; - } - } - } - - void clearLog() { - // Actually is probably called from GUI Thread as result of the user - // pressing a button. But better safe than sorry - VpnStatus.clearLog(); - VpnStatus.logInfo(R.string.logCleared); - mHandler.sendEmptyMessage(MESSAGE_CLEARLOG); - } - - - public void setTimeFormat(int newTimeFormat) { - mTimeFormat = newTimeFormat; - mHandler.sendEmptyMessage(MESSAGE_NEWTS); - } - - public void setLogLevel(int logLevel) { - mLogLevel = logLevel; - mHandler.sendEmptyMessage(MESSAGE_NEWLOGLEVEL); - } - - } - - - private LogWindowListAdapter ladapter; - private TextView mSpeedView; - - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if (item.getItemId() == R.id.clearlog) { - ladapter.clearLog(); - return true; - } else if (item.getItemId() == R.id.cancel) { - Intent intent = new Intent(getActivity(), DisconnectVPN.class); - startActivity(intent); - return true; - } else if (item.getItemId() == R.id.send) { - ladapter.shareLog(); - } else if (item.getItemId() == R.id.edit_vpn) { - VpnProfile lastConnectedprofile = ProfileManager.get(getActivity(), VpnStatus.getLastConnectedVPNProfile()); - - if (lastConnectedprofile != null) { - Intent vprefintent = new Intent(getActivity(), Dashboard.class) - .putExtra(VpnProfile.EXTRA_PROFILEUUID, lastConnectedprofile.getUUIDString()); - startActivityForResult(vprefintent, START_VPN_CONFIG); - } else { - Toast.makeText(getActivity(), R.string.log_no_last_vpn, Toast.LENGTH_LONG).show(); - } - } else if (item.getItemId() == R.id.toggle_time) { - showHideOptionsPanel(); - } else if (item.getItemId() == android.R.id.home) { - // This is called when the Home (Up) button is pressed - // in the Action Bar. - Intent parentActivityIntent = new Intent(getActivity(), Dashboard.class); - parentActivityIntent.addFlags( - Intent.FLAG_ACTIVITY_CLEAR_TOP | - Intent.FLAG_ACTIVITY_NEW_TASK); - startActivity(parentActivityIntent); - getActivity().finish(); - return true; - - } - return super.onOptionsItemSelected(item); - - } - - private void showHideOptionsPanel() { - boolean optionsVisible = (mOptionsLayout.getVisibility() != View.GONE); - - ObjectAnimator anim; - if (optionsVisible) { - anim = ObjectAnimator.ofFloat(mOptionsLayout, "alpha", 1.0f, 0f); - anim.addListener(collapseListener); - - } else { - mOptionsLayout.setVisibility(View.VISIBLE); - anim = ObjectAnimator.ofFloat(mOptionsLayout, "alpha", 0f, 1.0f); - //anim = new TranslateAnimation(0.0f, 0.0f, mOptionsLayout.getHeight(), 0.0f); - - } - - //anim.setInterpolator(new AccelerateInterpolator(1.0f)); - //anim.setDuration(300); - //mOptionsLayout.startAnimation(anim); - anim.start(); - - } - - AnimatorListenerAdapter collapseListener = new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animator) { - mOptionsLayout.setVisibility(View.GONE); - } - - }; - - - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - inflater.inflate(R.menu.logmenu, menu); - if (getResources().getBoolean(R.bool.logSildersAlwaysVisible)) - menu.removeItem(R.id.toggle_time); - } - - - @Override - public void onResume() { - super.onResume(); - Intent intent = new Intent(getActivity(), OpenVPNService.class); - intent.setAction(OpenVPNService.START_SERVICE); - } - - @Override - public void onStart() { - super.onStart(); - VpnStatus.addStateListener(this); - VpnStatus.addByteCountListener(this); - } - - @Override - public void onActivityResult(int requestCode, int resultCode, Intent data) { - if (requestCode == START_VPN_CONFIG && resultCode == Activity.RESULT_OK) { - String configuredVPN = data.getStringExtra(VpnProfile.EXTRA_PROFILEUUID); - - final VpnProfile profile = ProfileManager.get(getActivity(), configuredVPN); - ProfileManager.getInstance(getActivity()).saveProfile(getActivity(), profile); - // Name could be modified, reset List adapter - - AlertDialog.Builder dialog = new AlertDialog.Builder(getActivity()); - dialog.setTitle(R.string.configuration_changed); - dialog.setMessage(R.string.restart_vpn_after_change); - - - dialog.setPositiveButton(R.string.restart, - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - Intent intent = new Intent(getActivity(), LaunchVPN.class); - intent.putExtra(LaunchVPN.EXTRA_KEY, profile.getUUIDString()); - intent.setAction(Intent.ACTION_MAIN); - startActivity(intent); - } - - - }); - dialog.setNegativeButton(R.string.ignore, null); - dialog.create().show(); - } - super.onActivityResult(requestCode, resultCode, data); - } - - - @Override - public void onStop() { - super.onStop(); - VpnStatus.removeStateListener(this); - VpnStatus.removeByteCountListener(this); - - getActivity().getPreferences(0).edit().putInt(LOGTIMEFORMAT, ladapter.mTimeFormat) - .putInt(VERBOSITYLEVEL, ladapter.mLogLevel).apply(); - - } - - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - ListView lv = getListView(); - - lv.setOnItemLongClickListener(new OnItemLongClickListener() { - - @Override - public boolean onItemLongClick(AdapterView<?> parent, View view, - int position, long id) { - ClipboardManager clipboard = (ClipboardManager) - getActivity().getSystemService(Context.CLIPBOARD_SERVICE); - ClipData clip = ClipData.newPlainText("Log Entry", ((TextView) view).getText()); - clipboard.setPrimaryClip(clip); - Toast.makeText(getActivity(), R.string.copied_entry, Toast.LENGTH_SHORT).show(); - return true; - } - }); - } - - @Nullable - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View v = inflater.inflate(R.layout.log_fragment, container, false); - - setHasOptionsMenu(true); - - ladapter = new LogWindowListAdapter(); - ladapter.mTimeFormat = getActivity().getPreferences(0).getInt(LOGTIMEFORMAT, 1); - int logLevel = getActivity().getPreferences(0).getInt(VERBOSITYLEVEL, 1); - ladapter.setLogLevel(logLevel); - - setListAdapter(ladapter); - - mTimeRadioGroup = (RadioGroup) v.findViewById(R.id.timeFormatRadioGroup); - mTimeRadioGroup.setOnCheckedChangeListener(this); - - if (ladapter.mTimeFormat == LogWindowListAdapter.TIME_FORMAT_ISO) { - mTimeRadioGroup.check(R.id.radioISO); - } else if (ladapter.mTimeFormat == LogWindowListAdapter.TIME_FORMAT_NONE) { - mTimeRadioGroup.check(R.id.radioNone); - } else if (ladapter.mTimeFormat == LogWindowListAdapter.TIME_FORMAT_SHORT) { - mTimeRadioGroup.check(R.id.radioShort); - } - - mClearLogCheckBox = (CheckBox) v.findViewById(R.id.clearlogconnect); - mClearLogCheckBox.setChecked(PreferenceManager.getDefaultSharedPreferences(getActivity()).getBoolean(LaunchVPN.CLEARLOG, true)); - mClearLogCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - Preferences.getDefaultSharedPreferences(getActivity()).edit().putBoolean(LaunchVPN.CLEARLOG, isChecked).apply(); - } - }); - - mSpeedView = (TextView) v.findViewById(R.id.speed); - - mOptionsLayout = (LinearLayout) v.findViewById(R.id.logOptionsLayout); - mLogLevelSlider = (SeekBar) v.findViewById(R.id.LogLevelSlider); - mLogLevelSlider.setMax(VpnProfile.MAXLOGLEVEL - 1); - mLogLevelSlider.setProgress(logLevel - 1); - - mLogLevelSlider.setOnSeekBarChangeListener(this); - - if (getResources().getBoolean(R.bool.logSildersAlwaysVisible)) - mOptionsLayout.setVisibility(View.VISIBLE); - - mUpStatus = (TextView) v.findViewById(R.id.speedUp); - mDownStatus = (TextView) v.findViewById(R.id.speedDown); - mConnectStatus = (TextView) v.findViewById(R.id.speedStatus); - if (mShowOptionsLayout) - mOptionsLayout.setVisibility(View.VISIBLE); - return v; - } - - @Override - public void onViewCreated(View view, Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - // Scroll to the end of the list end - //getListView().setSelection(getListView().getAdapter().getCount()-1); - } - - @Override - public void onAttach(Context activity) { - super.onAttach(activity); - if (getResources().getBoolean(R.bool.logSildersAlwaysVisible)) { - mShowOptionsLayout = true; - if (mOptionsLayout != null) - mOptionsLayout.setVisibility(View.VISIBLE); - } - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - //getActionBar().setDisplayHomeAsUpEnabled(true); - - } - - - @Override - public void updateState(final String status, final String logMessage, final int resId, final ConnectionStatus level) { - if (isAdded()) { - final String cleanLogMessage = VpnStatus.getLastCleanLogMessage(getActivity()); - - getActivity().runOnUiThread(new Runnable() { - - @Override - public void run() { - if (isAdded()) { - if (mSpeedView != null) { - mSpeedView.setText(cleanLogMessage); - } - if (mConnectStatus != null) - mConnectStatus.setText(cleanLogMessage); - } - } - }); - } - } - - @Override - public void setConnectedVPN(String uuid) { - } - - - @Override - public void onDestroy() { - VpnStatus.removeLogListener(ladapter); - super.onDestroy(); - } - -} diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index 41c308a2..e69de29b 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -1,401 +0,0 @@ -/* - * Copyright (c) 2013 LEAP Encryption Access Project and contributers - * - * 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 3 of the License, or - * (at your option) any later version. - * - * 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. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ -package se.leap.bitmaskclient; - -import android.annotation.SuppressLint; -import android.app.AlertDialog; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.pm.PackageManager.NameNotFoundException; -import android.os.Bundle; -import android.util.Log; -import android.view.Menu; -import android.view.MenuItem; -import android.widget.TextView; - -import org.jetbrains.annotations.NotNull; -import org.json.JSONException; -import org.json.JSONObject; - -import java.net.MalformedURLException; -import java.net.URL; - -import butterknife.InjectView; -import de.blinkt.openvpn.core.VpnStatus; -import se.leap.bitmaskclient.eip.EipCommand; -import se.leap.bitmaskclient.fragments.AboutFragment; -import se.leap.bitmaskclient.userstatus.User; -import se.leap.bitmaskclient.userstatus.UserStatusFragment; - -import static se.leap.bitmaskclient.Constants.APP_ACTION_CONFIGURE_ALWAYS_ON_PROFILE; -import static se.leap.bitmaskclient.Constants.APP_ACTION_QUIT; -import static se.leap.bitmaskclient.Constants.EIP_IS_ALWAYS_ON; -import static se.leap.bitmaskclient.Constants.EIP_RESTART_ON_BOOT; -import static se.leap.bitmaskclient.Constants.PROVIDER_CONFIGURED; -import static se.leap.bitmaskclient.Constants.PROVIDER_EIP_DEFINITION; -import static se.leap.bitmaskclient.Constants.REQUEST_CODE_CONFIGURE_LEAP; -import static se.leap.bitmaskclient.Constants.REQUEST_CODE_KEY; -import static se.leap.bitmaskclient.Constants.REQUEST_CODE_SWITCH_PROVIDER; -import static se.leap.bitmaskclient.Constants.SHARED_PREFERENCES; - -/** - * The main user facing Activity of Bitmask Android, consisting of status, controls, - * and access to preferences. - * - * @author Sean Leonard <meanderingcode@aetherislands.net> - * @author parmegv - */ -public class Dashboard extends ButterKnifeActivity { - - public static final String TAG = Dashboard.class.getSimpleName(); - - /** - * When "Disconnect" is clicked from the notification this extra gets added to the calling intent. - */ - public static final String ACTION_ASK_TO_CANCEL_VPN = "ask to cancel vpn"; - /** - * if always-on feature is enabled, but there's no provider configured the EIP Service - * adds this intent extra. Constants.APP_ACTION_CONFIGURE_ALWAYS_ON_PROFILE - * serves to start the Configuration Wizard on top of the Dashboard Activity. - */ - - protected static SharedPreferences preferences; - private static FragmentManagerEnhanced fragment_manager; - - @InjectView(R.id.providerName) - TextView provider_name; - - private EipFragment eip_fragment; - private UserStatusFragment user_status_fragment; - - private static Provider provider = new Provider(); - private boolean handledVersion; - - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - preferences = getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE); - fragment_manager = new FragmentManagerEnhanced(getSupportFragmentManager()); - - - if (!handledVersion) { - handleVersion(); - handledVersion = true; - } - - // initialize app necessities - VpnStatus.initLogCache(getApplicationContext().getCacheDir()); - User.init(getString(R.string.default_username)); - - prepareEIP(savedInstanceState); - } - - @Override - protected void onResume() { - super.onResume(); - handleVpnCancellation(getIntent()); - } - - private boolean previousProviderExists(Bundle savedInstanceState) { - return providerInSavedInstance(savedInstanceState) || providerInSharedPreferences(); - } - - private Provider getProvider(Bundle savedInstanceState) { - if(providerInSavedInstance(savedInstanceState)) - provider = savedInstanceState.getParcelable(Provider.KEY); - else if (providerInSharedPreferences()) - provider = getSavedProviderFromSharedPreferences(); - return provider; - } - - private boolean providerInSavedInstance(Bundle savedInstanceState) { - return savedInstanceState != null && - savedInstanceState.containsKey(Provider.KEY); - } - - private boolean providerInSharedPreferences() { - return preferences != null && - preferences.getBoolean(PROVIDER_CONFIGURED, false); - - } - - @Override - protected void onSaveInstanceState(@NotNull Bundle outState) { - outState.putParcelable(Provider.KEY, provider); - super.onSaveInstanceState(outState); - } - - private Provider getSavedProviderFromSharedPreferences() { - Provider provider = new Provider(); - try { - provider.setMainUrl(new URL(preferences.getString(Provider.MAIN_URL, ""))); - provider.define(new JSONObject(preferences.getString(Provider.KEY, ""))); - provider.setCaCert(preferences.getString(Provider.CA_CERT, "")); - } catch (MalformedURLException | JSONException e) { - e.printStackTrace(); - } - - return provider; - } - - private void handleVersion() { - try { - int versionCode = getPackageManager().getPackageInfo(getPackageName(), 0).versionCode; - - switch (versionCode) { - case 91: // 0.6.0 without Bug #5999 - case 101: // 0.8.0 - if (!preferences.getString(PROVIDER_EIP_DEFINITION, "").isEmpty()) - break; - } - } catch (NameNotFoundException e) { - Log.d(TAG, "Handle version didn't find any " + getPackageName() + " package"); - } - } - - @Override - protected void onNewIntent(Intent intent) { - super.onNewIntent(intent); - setIntent(intent); - handleIntentExtras(intent); - } - - private void handleIntentExtras(Intent intent) { - if (intent.hasExtra(ACTION_ASK_TO_CANCEL_VPN)) { - handleVpnCancellation(intent); - } else if (intent.hasExtra(EIP_RESTART_ON_BOOT)) { - Log.d(TAG, "Dashboard: EIP_RESTART_ON_BOOT"); - prepareEIP(null); - } else if (intent.hasExtra(APP_ACTION_CONFIGURE_ALWAYS_ON_PROFILE)) { - Log.d(TAG, "Dashboard: Constants.APP_ACTION_CONFIGURE_ALWAYS_ON_PROFILE"); - handleConfigureAlwaysOn(getIntent()); - } - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - if (requestCode == REQUEST_CODE_CONFIGURE_LEAP || requestCode == REQUEST_CODE_SWITCH_PROVIDER) { - if (resultCode == RESULT_OK && data.hasExtra(Provider.KEY)) { - provider = data.getParcelableExtra(Provider.KEY); - providerToPreferences(provider); - - buildDashboard(false); - invalidateOptionsMenuOnUiThread(); - //if (data.hasExtra(SessionDialog.TAG)) { - // sessionDialog(Bundle.EMPTY); - //} - - } else if (resultCode == RESULT_CANCELED && data != null && data.hasExtra(APP_ACTION_QUIT)) { - finish(); - } else - configErrorDialog(); - } - } - - private void handleVpnCancellation(Intent intent) { - if (intent.hasExtra(Dashboard.ACTION_ASK_TO_CANCEL_VPN)) { - eip_fragment.askToStopEIP(); - intent.removeExtra(ACTION_ASK_TO_CANCEL_VPN); - } - } - - private void handleConfigureAlwaysOn(Intent intent) { - intent.removeExtra(APP_ACTION_CONFIGURE_ALWAYS_ON_PROFILE); - Log.d(TAG, "start Configuration wizard!"); - startActivityForResult(new Intent(this, ProviderListActivity.class), REQUEST_CODE_CONFIGURE_LEAP); - } - - private void prepareEIP(Bundle savedInstanceState) { - boolean provider_exists = previousProviderExists(savedInstanceState); - if (provider_exists) { - provider = getProvider(savedInstanceState); - if(!provider.isConfigured()) { - configureLeapProvider(); - } else { - Log.d(TAG, "vpn provider is configured"); - buildDashboard(getIntent().getBooleanExtra(EIP_RESTART_ON_BOOT, false)); - user_status_fragment.restoreSessionStatus(savedInstanceState); - } - } else { - configureLeapProvider(); - } - } - - private void configureLeapProvider() { - if (getIntent().hasExtra(APP_ACTION_CONFIGURE_ALWAYS_ON_PROFILE)) { - getIntent().removeExtra(APP_ACTION_CONFIGURE_ALWAYS_ON_PROFILE); - } - startActivityForResult(new Intent(this, ProviderListActivity.class), REQUEST_CODE_CONFIGURE_LEAP); - } - @SuppressLint("CommitPrefEdits") - private void providerToPreferences(Provider provider) { - preferences.edit().putBoolean(PROVIDER_CONFIGURED, true). - putString(Provider.MAIN_URL, provider.getMainUrl().toString()). - putString(Provider.KEY, provider.getDefinition().toString()).apply(); - } - - private void configErrorDialog() { - AlertDialog.Builder alertBuilder = new AlertDialog.Builder(this); - alertBuilder.setTitle(getResources().getString(R.string.setup_error_title)); - alertBuilder - .setMessage(getResources().getString(R.string.setup_error_text)) - .setCancelable(false) - .setPositiveButton(getResources().getString(R.string.setup_error_configure_button), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - startActivityForResult(new Intent(Dashboard.this, ProviderListActivity.class), REQUEST_CODE_CONFIGURE_LEAP); - } - }) - .setNegativeButton(getResources().getString(R.string.setup_error_close_button), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - preferences.edit().remove(Provider.KEY).remove(PROVIDER_CONFIGURED).apply(); - finish(); - } - }) - .show(); - } - - /** - * Inflates permanent UI elements of the View and contains logic for what - * service dependent UI elements to include. - */ - //TODO: REFACTOR ME! Consider implementing a manager that handles most of EipFragment's logic about handling EIP commands. - //This way, we could avoid to create UI elements (like fragmentManager.replace(R.id.servicesCollection, eip_fragment, EipFragment.TAG); ) - // just to start services and destroy them afterwards - private void buildDashboard(boolean hideAndTurnOnEipOnBoot) { - setContentView(R.layout.dashboard); - - provider_name.setText(provider.getDomain()); - - user_status_fragment = new UserStatusFragment(); - Bundle bundle = new Bundle(); - bundle.putBoolean(Provider.ALLOW_REGISTRATION, provider.allowsRegistration()); - user_status_fragment.setArguments(bundle); - fragment_manager.replace(R.id.user_status_fragment, user_status_fragment, UserStatusFragment.TAG); - -// if (provider.hasEIP()) { -// fragment_manager.removePreviousFragment(EipFragment.TAG); -// eip_fragment = prepareEipFragment(hideAndTurnOnEipOnBoot); -// fragment_manager.replace(R.id.servicesCollection, eip_fragment, EipFragment.TAG); -// if (hideAndTurnOnEipOnBoot) { -// onBackPressed(); -// } -// } - } - - /** - * - * @param hideAndTurnOnEipOnBoot Flag that indicates if system intent android.intent.action.BOOT_COMPLETED - * has caused to start Dashboard - * @return the created VPNFragment - */ - public EipFragment prepareEipFragment(boolean hideAndTurnOnEipOnBoot) { - EipFragment eip_fragment = new EipFragment(); - - if (hideAndTurnOnEipOnBoot && !isAlwaysOn()) { - preferences.edit().remove(EIP_RESTART_ON_BOOT).apply(); - Bundle arguments = new Bundle(); - arguments.putBoolean(EipFragment.START_EIP_ON_BOOT, true); - Log.d(TAG, "set START_EIP_ON_BOOT argument for eip_fragment"); - eip_fragment.setArguments(arguments); - - } - return eip_fragment; - } - - /** - * checks if Android's VPN feature 'always-on' is enabled for Bitmask - * @return true if 'always-on' is enabled false if not - */ - private boolean isAlwaysOn() { - return preferences.getBoolean(EIP_IS_ALWAYS_ON, false); - } - - - @Override - public boolean onPrepareOptionsMenu(Menu menu) { - if (provider.allowsRegistration()) { - menu.findItem(R.id.signup_button).setVisible(true); - } - return true; - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.client_dashboard, menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case R.id.about_leap: - showAbout(); - return true; - case R.id.log_window: - showLog(); - return true; - case R.id.switch_provider: - if (User.loggedIn()) user_status_fragment.logOut(); - else switchProvider(); - return true; - case R.id.signup_button: - //sessionDialog(Bundle.EMPTY); - return true; - default: - return super.onOptionsItemSelected(item); - } - } - - public void showAbout() { - Intent intent = new Intent(this, AboutFragment.class); - startActivity(intent); - } - - public void showLog() { - LogWindowWrapper log_window_wrapper = LogWindowWrapper.getInstance(this); - log_window_wrapper.showLog(); - } - - private void switchProvider() { -// if (provider.hasEIP()) eip_fragment.stopEipIfPossible(); - - ConfigHelper.clearDataOfLastProvider(preferences); - - startActivityForResult(new Intent(this, ProviderListActivity.class), REQUEST_CODE_SWITCH_PROVIDER); - } - - public static Provider getProvider() { return provider; } - - @Override - public void startActivityForResult(Intent intent, int requestCode) { - intent.putExtra(REQUEST_CODE_KEY, requestCode); - super.startActivityForResult(intent, requestCode); - } - - public void invalidateOptionsMenuOnUiThread() { - runOnUiThread(new Runnable() { - @Override - public void run() { - invalidateOptionsMenu(); - } - }); - } -} diff --git a/app/src/main/java/se/leap/bitmaskclient/LogWindowWrapper.java b/app/src/main/java/se/leap/bitmaskclient/LogWindowWrapper.java deleted file mode 100644 index 2476f6a4..00000000 --- a/app/src/main/java/se/leap/bitmaskclient/LogWindowWrapper.java +++ /dev/null @@ -1,28 +0,0 @@ -package se.leap.bitmaskclient; - -import android.content.*; - -import de.blinkt.openvpn.activities.*; - -public class LogWindowWrapper { - private static LogWindowWrapper instance; - - private static String TAG = LogWindowWrapper.class.getName(); - private Context context; - - public LogWindowWrapper(Context context) { - this.context = context; - } - - public void showLog() { - Intent startLW = new Intent(context, LogWindow.class); - startLW.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - context.startActivity(startLW); - } - - public static LogWindowWrapper getInstance(Context context) { - if(instance == null) - instance = new LogWindowWrapper(context); - return instance; - } -} diff --git a/app/src/main/java/se/leap/bitmaskclient/MainActivity.java b/app/src/main/java/se/leap/bitmaskclient/MainActivity.java index 6d9d32b5..2a2a68a7 100644 --- a/app/src/main/java/se/leap/bitmaskclient/MainActivity.java +++ b/app/src/main/java/se/leap/bitmaskclient/MainActivity.java @@ -35,6 +35,7 @@ import se.leap.bitmaskclient.drawer.NavigationDrawerFragment; import se.leap.bitmaskclient.eip.EipCommand; import se.leap.bitmaskclient.eip.EipStatus; import se.leap.bitmaskclient.eip.VoidVpnService; +import se.leap.bitmaskclient.fragments.LogFragment; import static android.content.Intent.CATEGORY_DEFAULT; import static se.leap.bitmaskclient.Constants.BROADCAST_EIP_EVENT; @@ -97,6 +98,7 @@ public class MainActivity extends AppCompatActivity implements Observer, MainAct }; public final static String ACTION_SHOW_VPN_FRAGMENT = "action_show_vpn_fragment"; + public final static String ACTION_SHOW_LOG_FRAGMENT = "action_show_log_fragment"; /** * Fragment managing the behaviors, interactions and presentation of the navigation drawer. @@ -189,6 +191,9 @@ public class MainActivity extends AppCompatActivity implements Observer, MainAct bundle.putParcelable(PROVIDER_KEY, provider); fragment.setArguments(bundle); break; + case ACTION_SHOW_LOG_FRAGMENT: + fragment = new LogFragment(); + break; default: break; } diff --git a/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java b/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java index 9d5d4341..772140b0 100644 --- a/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java @@ -26,6 +26,7 @@ import android.widget.ListView; import android.widget.Toast; import se.leap.bitmaskclient.ConfigHelper; +import se.leap.bitmaskclient.Provider; import se.leap.bitmaskclient.ProviderListActivity; import se.leap.bitmaskclient.EipFragment; import se.leap.bitmaskclient.R; @@ -34,6 +35,7 @@ import se.leap.bitmaskclient.fragments.LogFragment; import static android.content.Context.MODE_PRIVATE; import static se.leap.bitmaskclient.BitmaskApp.getRefWatcher; +import static se.leap.bitmaskclient.Constants.PROVIDER_KEY; import static se.leap.bitmaskclient.Constants.REQUEST_CODE_SWITCH_PROVIDER; import static se.leap.bitmaskclient.Constants.SHARED_PREFERENCES; @@ -278,6 +280,10 @@ public class NavigationDrawerFragment extends Fragment { if (parent == mDrawerAccountsListView) { mTitle = getString(R.string.vpn_fragment_title); fragment = new EipFragment(); + Bundle arguments = new Bundle(); + Provider currentProvider = ConfigHelper.getSavedProviderFromSharedPreferences(preferences); + arguments.putParcelable(PROVIDER_KEY, currentProvider); + fragment.setArguments(arguments); } else { Log.d("Drawer", String.format("Selected position %d", position)); switch (position) { diff --git a/app/src/main/java/se/leap/bitmaskclient/fragments/LogFragment.java b/app/src/main/java/se/leap/bitmaskclient/fragments/LogFragment.java index 3d85b4ad..03e0669a 100644 --- a/app/src/main/java/se/leap/bitmaskclient/fragments/LogFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/fragments/LogFragment.java @@ -63,7 +63,6 @@ import de.blinkt.openvpn.core.ProfileManager; import de.blinkt.openvpn.core.VpnStatus; import de.blinkt.openvpn.core.VpnStatus.LogListener; import de.blinkt.openvpn.core.VpnStatus.StateListener; -import se.leap.bitmaskclient.Dashboard; import se.leap.bitmaskclient.R; import static de.blinkt.openvpn.core.OpenVPNService.humanReadableByteCount; @@ -427,29 +426,8 @@ public class LogFragment extends ListFragment implements StateListener, SeekBar. return true; } else if (item.getItemId() == R.id.send) { ladapter.shareLog(); - } else if (item.getItemId() == R.id.edit_vpn) { - VpnProfile lastConnectedprofile = ProfileManager.get(getActivity(), VpnStatus.getLastConnectedVPNProfile()); - - if (lastConnectedprofile != null) { - Intent vprefintent = new Intent(getActivity(), Dashboard.class) - .putExtra(VpnProfile.EXTRA_PROFILEUUID, lastConnectedprofile.getUUIDString()); - startActivityForResult(vprefintent, START_VPN_CONFIG); - } else { - Toast.makeText(getActivity(), R.string.log_no_last_vpn, Toast.LENGTH_LONG).show(); - } } else if (item.getItemId() == R.id.toggle_time) { showHideOptionsPanel(); - } else if (item.getItemId() == android.R.id.home) { - // This is called when the Home (Up) button is pressed - // in the Action Bar. - Intent parentActivityIntent = new Intent(getActivity(), Dashboard.class); - parentActivityIntent.addFlags( - Intent.FLAG_ACTIVITY_CLEAR_TOP | - Intent.FLAG_ACTIVITY_NEW_TASK); - startActivity(parentActivityIntent); - getActivity().finish(); - return true; - } return super.onOptionsItemSelected(item); diff --git a/app/src/main/java/se/leap/bitmaskclient/userstatus/FabButton.java b/app/src/main/java/se/leap/bitmaskclient/userstatus/FabButton.java deleted file mode 100644 index d1c56dee..00000000 --- a/app/src/main/java/se/leap/bitmaskclient/userstatus/FabButton.java +++ /dev/null @@ -1,28 +0,0 @@ -package se.leap.bitmaskclient.userstatus; - - -import android.content.Context; -import android.util.AttributeSet; - -import mbanje.kurt.fabbutton.CircleImageView; -import se.leap.bitmaskclient.R; - -public class FabButton extends mbanje.kurt.fabbutton.FabButton { - - - public FabButton(Context context) { - super(context); - } - - public FabButton(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public FabButton(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - } - - private CircleImageView getImage() { - return (CircleImageView) findViewById(R.id.fabbutton_circle); - } -} diff --git a/app/src/main/java/se/leap/bitmaskclient/userstatus/UserStatusFragment.java b/app/src/main/java/se/leap/bitmaskclient/userstatus/UserStatusFragment.java deleted file mode 100644 index 2d8b5c6f..00000000 --- a/app/src/main/java/se/leap/bitmaskclient/userstatus/UserStatusFragment.java +++ /dev/null @@ -1,158 +0,0 @@ -package se.leap.bitmaskclient.userstatus; - -import android.content.Context; -import android.os.Bundle; -import android.support.v4.app.Fragment; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.TextView; - -import org.jetbrains.annotations.NotNull; - -import java.util.Observable; -import java.util.Observer; - -import butterknife.ButterKnife; -import butterknife.InjectView; -import butterknife.OnClick; -import se.leap.bitmaskclient.Provider; -import se.leap.bitmaskclient.ProviderAPI; -import se.leap.bitmaskclient.ProviderAPICommand; -import se.leap.bitmaskclient.ProviderAPIResultReceiver; -import se.leap.bitmaskclient.R; - -public class UserStatusFragment extends Fragment implements Observer { - - public final static String TAG = UserStatusFragment.class.getSimpleName(); - private ProviderAPIResultReceiver providerAPI_result_receiver; - - private Provider provider; - - @InjectView(R.id.user_status_username) - TextView username; - @InjectView(R.id.user_status_icon) - FabButton icon; - @InjectView(R.id.user_status_button) - Button button; - - private UserStatus status; - private boolean allowsRegistration = false; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - status = UserStatus.getInstance(getResources()); - status.addObserver(this); - } - - @Override - public void onSaveInstanceState(@NotNull Bundle outState) { - if (username != null && username.getVisibility() == TextView.VISIBLE) - outState.putSerializable(UserStatus.TAG, status.sessionStatus()); - - super.onSaveInstanceState(outState); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - - View view = inflater.inflate(R.layout.user_session_fragment, container, false); - ButterKnife.inject(this, view); - - Bundle arguments = getArguments(); - allowsRegistration = arguments.getBoolean(Provider.ALLOW_REGISTRATION); - handleNewStatus(status); - - return view; - } - - @Override - public void onAttach(Context context) { - super.onAttach(context); - } - - public void restoreSessionStatus(Bundle savedInstanceState) { - if (savedInstanceState != null) - if (savedInstanceState.containsKey(UserStatus.TAG)) { - UserStatus.SessionStatus status = (UserStatus.SessionStatus) savedInstanceState.getSerializable(UserStatus.TAG); - UserStatus.updateStatus(status, getResources()); - } - } - - @OnClick(R.id.user_status_button) - public void handleButton() { - android.util.Log.d(TAG, status.toString()); - if(status.isLoggedIn()) - logOut(); - else if(status.isLoggedOut()) - Log.w(TAG, "implement login from here?"); - //MainActivity.sessionDialog(Bundle.EMPTY); - else if(status.inProgress()) - cancelLoginOrSignup(); - } - - @Override - public void update(Observable observable, Object data) { - if (observable instanceof UserStatus) { - final UserStatus status = (UserStatus) observable; - getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - handleNewStatus(status); - } - }); - } - } - - private void handleNewStatus(UserStatus status) { - this.status = status; - if (allowsRegistration) { - if (this.status.inProgress()) - showUserSessionProgressBar(); - else - hideUserSessionProgressBar(); - changeMessage(); - updateButton(); - } - } - - private void showUserSessionProgressBar() { - icon.showProgress(true); - } - - private void hideUserSessionProgressBar() { - icon.showProgress(false); - } - - private void changeMessage() { - final String message = User.userName(); - username.setText(message); - } - - private void updateButton() { - if(status.isLoggedIn() || status.didntLogOut()) - button.setText(getActivity().getString(R.string.logout_button)); - else if(allowsRegistration) { - if (status.isLoggedOut() || status.notLoggedIn()) - button.setText(getActivity().getString(R.string.login_button)); - else if (status.inProgress()) - button.setText(getActivity().getString(android.R.string.cancel)); - } - } - - - public void logOut() { - android.util.Log.d(TAG, "Log out"); - ProviderAPICommand.execute(getActivity(), ProviderAPI.LOG_OUT, provider, providerAPI_result_receiver); - } - - public void cancelLoginOrSignup() { - //EipStatus.getInstance().setConnectedOrDisconnected(); - } - -} diff --git a/app/src/main/res/layout-sw600dp-port/f_log.xml b/app/src/main/res/layout-sw600dp-port/f_log.xml index 4ee64811..78dc4c62 100644 --- a/app/src/main/res/layout-sw600dp-port/f_log.xml +++ b/app/src/main/res/layout-sw600dp-port/f_log.xml @@ -20,7 +20,7 @@ android:layout_width="wrap_content" android:layout_height="match_parent"> - <include layout="@layout/log_silders"/> + <include layout="@layout/f_log_sliders"/> <include layout="@layout/vpnstatus"/> </LinearLayout> diff --git a/app/src/main/res/layout-sw600dp-port/log_fragment.xml b/app/src/main/res/layout-sw600dp-port/log_fragment.xml deleted file mode 100644 index 7a4b60fe..00000000 --- a/app/src/main/res/layout-sw600dp-port/log_fragment.xml +++ /dev/null @@ -1,45 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - ~ Copyright (c) 2012-2016 Arne Schwabe - ~ Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - --> - -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:orientation="vertical" - tools:context=".LogWindow"> - - <LinearLayout - android:background="@drawable/white_rect" - android:elevation="1dp" - android:layout_height="wrap_content" - android:layout_width="match_parent"> - - <include layout="@layout/log_silders"/> - - <Space - android:layout_weight="5" - android:layout_height="wrap_content" - android:layout_width="wrap_content"/> - <LinearLayout - android:layout_height="wrap_content" - android:layout_width="wrap_content" - android:orientation="vertical"> - <include layout="@layout/vpnstatus"/> - </LinearLayout> - <Space - android:layout_height="wrap_content" - android:layout_width="wrap_content" - android:layout_weight="1"/> - </LinearLayout> - - - <ListView - android:id="@android:id/list" - android:transcriptMode="normal" - android:layout_width="fill_parent" - android:layout_height="fill_parent"/> - -</LinearLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout-sw600dp/f_log.xml b/app/src/main/res/layout-sw600dp/f_log.xml index ec66af07..34daf8be 100644 --- a/app/src/main/res/layout-sw600dp/f_log.xml +++ b/app/src/main/res/layout-sw600dp/f_log.xml @@ -20,7 +20,7 @@ android:layout_width="wrap_content" android:layout_height="match_parent"> - <include layout="@layout/log_silders"/> + <include layout="@layout/f_log_sliders"/> <include layout="@layout/vpnstatus"/> </LinearLayout> diff --git a/app/src/main/res/layout-sw600dp/log_fragment.xml b/app/src/main/res/layout-sw600dp/log_fragment.xml deleted file mode 100644 index 089bfb9d..00000000 --- a/app/src/main/res/layout-sw600dp/log_fragment.xml +++ /dev/null @@ -1,37 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - ~ Copyright (c) 2012-2016 Arne Schwabe - ~ Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - --> - -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:orientation="horizontal" - android:padding="20dp" - tools:context=".LogWindow"> - - - <LinearLayout - android:background="@drawable/white_rect" - android:elevation="1dp" - android:minWidth="300dp" - - android:orientation="vertical" - android:layout_width="400dp" - android:layout_height="match_parent"> - - <include layout="@layout/log_silders"/> - - <include layout="@layout/vpnstatus"/> - </LinearLayout> - - <ListView - android:minWidth="400dp" - android:layout_weight="4" - android:id="@android:id/list" - android:transcriptMode="normal" - android:layout_width="fill_parent" - android:layout_height="match_parent"/> -</LinearLayout> diff --git a/app/src/main/res/layout-xlarge/about.xml b/app/src/main/res/layout-xlarge/about.xml index fdf823a9..ea2251cf 100644 --- a/app/src/main/res/layout-xlarge/about.xml +++ b/app/src/main/res/layout-xlarge/about.xml @@ -5,7 +5,7 @@ android:layout_height="match_parent" android:orientation="vertical" android:layout_marginLeft="12sp" - tools:context=".Dashboard" > + tools:context=".MainActivity" > <LinearLayout android:layout_width="match_parent" diff --git a/app/src/main/res/layout-xlarge/dashboard.xml b/app/src/main/res/layout-xlarge/dashboard.xml deleted file mode 100644 index b9c78b68..00000000 --- a/app/src/main/res/layout-xlarge/dashboard.xml +++ /dev/null @@ -1,38 +0,0 @@ -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" - android:id="@+id/dashboardLayout" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:orientation="vertical" - android:layout_marginLeft="10sp" - android:layout_marginStart="10sp" - android:layout_marginTop="10sp" - tools:context=".Dashboard" > - - <TextView - android:id="@+id/providerName" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginLeft="32dp" - android:layout_marginStart="32dp" - android:textSize="48sp" - android:ellipsize="marquee" - android:gravity="center_vertical" - android:text="@string/provider_label_none" - android:textAppearance="?android:attr/textAppearanceMedium" /> - - <LinearLayout - android:id="@+id/user.status.fragment" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="horizontal"/> - - <LinearLayout - android:id="@+id/servicesCollection" - android:layout_width="match_parent" - android:layout_height="0dp" - android:layout_weight="0.11" - android:orientation="vertical" > - </LinearLayout> - -</LinearLayout> diff --git a/app/src/main/res/layout-xlarge/user_session_fragment.xml b/app/src/main/res/layout-xlarge/user_session_fragment.xml deleted file mode 100644 index df72f615..00000000 --- a/app/src/main/res/layout-xlarge/user_session_fragment.xml +++ /dev/null @@ -1,54 +0,0 @@ -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" - xmlns:app="http://schemas.android.com/apk/res-auto" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginTop="30dp" - android:layout_marginLeft="60dp" - android:layout_marginStart="60dp" - android:orientation="vertical" - tools:context="se.leap.bitmaskclient.userstatus.UserStatusFragment"> - - <TextView - android:id="@+id/user.status.username" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginBottom="30dp" - android:layout_gravity="center" - android:textSize="46sp" - android:text="@string/default_username" - android:textAppearance="?android:attr/textAppearanceMedium"/> - - <LinearLayout - android:id="@+id/user.status.buttonAndIcon" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center"> - - <Button - android:id="@+id/user.status.button" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:textSize="32sp" - /> - - <se.leap.bitmaskclient.userstatus.FabButton - android:id="@+id/user.status.icon" - android:layout_width="56dp" - android:layout_height="56dp" - android:layout_marginStart="24dp" - android:layout_marginLeft="24dp" - android:shadowRadius="0" - android:src="@drawable/icon_user" - android:color="@android:color/holo_blue_dark" - android:layout_gravity="center" - android:visibility="visible" - android:indeterminate="true" - android:max="100" - fbb_autoStart="true" - app:fbb_progressColor="@android:color/holo_green_dark" - app:fbb_progressWidthRatio="0.2" - /> - - </LinearLayout> -</LinearLayout> diff --git a/app/src/main/res/layout/about.xml b/app/src/main/res/layout/about.xml index e26629ab..abc12566 100644 --- a/app/src/main/res/layout/about.xml +++ b/app/src/main/res/layout/about.xml @@ -5,7 +5,7 @@ android:layout_height="match_parent" android:orientation="vertical" android:layout_marginLeft="8sp" - tools:context=".Dashboard" > + tools:context=".MainActivity" > <LinearLayout android:layout_width="match_parent" diff --git a/app/src/main/res/layout/dashboard.xml b/app/src/main/res/layout/dashboard.xml deleted file mode 100644 index 1b294fb1..00000000 --- a/app/src/main/res/layout/dashboard.xml +++ /dev/null @@ -1,34 +0,0 @@ -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" - android:id="@+id/dashboardLayout" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:orientation="vertical" - tools:context=".Dashboard" > - - <TextView - android:id="@+id/providerName" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginLeft="10dp" - android:layout_marginStart="10dp" - android:textSize="26sp" - android:ellipsize="marquee" - android:gravity="center_vertical" - android:maxLines="1" - android:text="@string/provider_label_none" - android:textAppearance="?android:attr/textAppearanceMedium" /> - - <LinearLayout - android:id="@+id/user.status.fragment" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="horizontal"/> - - <LinearLayout - android:id="@+id/servicesCollection" - android:layout_width="match_parent" - android:layout_height="0dp" - android:layout_weight="0.11" - android:orientation="vertical" /> -</LinearLayout> diff --git a/app/src/main/res/layout/log_fragment.xml b/app/src/main/res/layout/log_fragment.xml deleted file mode 100644 index ab070117..00000000 --- a/app/src/main/res/layout/log_fragment.xml +++ /dev/null @@ -1,37 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - ~ Copyright (c) 2012-2016 Arne Schwabe - ~ Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - --> - -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:orientation="vertical"> - - <LinearLayout - android:background="@drawable/white_rect" - android:elevation="1dp" - android:orientation="vertical" - android:layout_height="wrap_content" - android:layout_width="match_parent"> - - <include layout="@layout/log_silders"/> - - <TextView - android:text="@string/speed_waiting" - android:singleLine="true" - android:id="@+id/speed" - tools:ignore="InconsistentLayout" - android:layout_width="match_parent" - android:layout_height="wrap_content"/> - </LinearLayout> - - <ListView - android:id="@android:id/list" - android:transcriptMode="normal" - android:layout_width="fill_parent" - android:layout_height="fill_parent"/> - -</LinearLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/log_silders.xml b/app/src/main/res/layout/log_silders.xml deleted file mode 100644 index 4196e243..00000000 --- a/app/src/main/res/layout/log_silders.xml +++ /dev/null @@ -1,73 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> - - -<!-- - ~ Copyright (c) 2012-2016 Arne Schwabe - ~ Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - --> - -<LinearLayout - xmlns:tools="http://schemas.android.com/tools" - xmlns:android="http://schemas.android.com/apk/res/android" - android:orientation="vertical" - android:id="@+id/logOptionsLayout" - android:visibility="gone" - tools:visibility="visible" - android:layout_width="wrap_content" - android:layout_height="wrap_content"> - - <TextView - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:text="@string/log_verbosity_level"/> - - - <de.blinkt.openvpn.views.SeekBarTicks - android:id="@+id/LogLevelSlider" - android:layout_width="300dp" - android:layout_height="wrap_content" - tools:max="5" - android:indeterminate="false"/> - - <TextView - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:text="@string/timestamps"/> - - <RadioGroup - android:id="@+id/timeFormatRadioGroup" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="horizontal"> - - <RadioButton - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/timestamps_none" - android:id="@+id/radioNone" - /> - - <RadioButton - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/timestamp_short" - android:id="@+id/radioShort" - /> - - <RadioButton - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/timestamp_iso" - android:id="@+id/radioISO" - /> - - - </RadioGroup> - - <CheckBox - tools:checked="true" - android:id="@+id/clearlogconnect" - android:text="@string/clear_log_on_connect" - android:layout_width="wrap_content" - android:layout_height="wrap_content" /> -</LinearLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/log_window.xml b/app/src/main/res/layout/log_window.xml deleted file mode 100644 index 7c25dcfa..00000000 --- a/app/src/main/res/layout/log_window.xml +++ /dev/null @@ -1,12 +0,0 @@ -<!-- - ~ Copyright (c) 2012-2016 Arne Schwabe - ~ Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - --> - -<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" - android:id="@+id/container" - android:layout_width="match_parent" - android:layout_height="match_parent" - tools:context=".LogWindow" - tools:ignore="MergeRootFrame" />
\ No newline at end of file diff --git a/app/src/main/res/layout/user_session_fragment.xml b/app/src/main/res/layout/user_session_fragment.xml deleted file mode 100644 index 2d38d140..00000000 --- a/app/src/main/res/layout/user_session_fragment.xml +++ /dev/null @@ -1,45 +0,0 @@ -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" - xmlns:app="http://schemas.android.com/apk/res-auto" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginTop="10dp" - android:layout_marginLeft="20dp" - android:layout_marginStart="20dp" - tools:context="se.leap.bitmaskclient.userstatus.UserStatusFragment"> - - <TextView - android:id="@+id/user.status.username" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginBottom="10dp" - android:layout_marginRight="15dp" - android:layout_marginEnd="20dp" - android:textSize="20sp" - android:text="@string/default_username" - android:textAppearance="?android:attr/textAppearanceMedium"/> - - <Button - android:id="@+id/user.status.button" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:textSize="14sp" - /> - - <se.leap.bitmaskclient.userstatus.FabButton - android:id="@+id/user.status.icon" - android:layout_width="32dp" - android:layout_height="32dp" - android:layout_marginLeft="9dp" - android:layout_marginStart="9dp" - android:shadowRadius="0" - android:src="@drawable/icon_user" - android:color="@android:color/holo_blue_dark" - android:layout_gravity="center" - android:indeterminate="true" - app:fbb_progressColor="@android:color/holo_green_dark" - app:fbb_progressWidthRatio="0.2" - app:fbb_showShadow="false" - /> - -</LinearLayout> diff --git a/app/src/main/res/menu/client_dashboard.xml b/app/src/main/res/menu/client_dashboard.xml deleted file mode 100644 index e0336cc0..00000000 --- a/app/src/main/res/menu/client_dashboard.xml +++ /dev/null @@ -1,19 +0,0 @@ -<menu xmlns:android="http://schemas.android.com/apk/res/android" > - <item - android:id="@+id/about_leap" - android:orderInCategory="110" - android:title="@string/about"/> - <item - android:id="@+id/log_window" - android:title="@string/show_log_window" - android:visible="true"/> - <item - android:id="@+id/switch_provider" - android:orderInCategory="501" - android:title="@string/switch_provider_menu_option"/> - <item - android:id="@+id/signup_button" - android:title="@string/signup_button" - android:visible="false"/> - -</menu> diff --git a/app/src/main/res/menu/logmenu.xml b/app/src/main/res/menu/logmenu.xml deleted file mode 100644 index 4c8daf35..00000000 --- a/app/src/main/res/menu/logmenu.xml +++ /dev/null @@ -1,44 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - ~ Copyright (c) 2012-2016 Arne Schwabe - ~ Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt - --> - -<menu xmlns:android="http://schemas.android.com/apk/res/android"> - - - <item - android:id="@+id/toggle_time" - android:alphabeticShortcut="t" - android:icon="@drawable/ic_menu_view" - android:showAsAction="ifRoom" - android:title="@string/logview_options" /> - - <item - android:id="@+id/clearlog" - android:icon="@drawable/ic_menu_delete" - android:showAsAction="ifRoom" - android:title="@string/clear_log" - android:titleCondensed="@string/clear"/> - <item - android:id="@+id/send" - android:icon="@drawable/ic_menu_share" - android:showAsAction="ifRoom" - android:title="@string/send_logfile" - android:titleCondensed="@string/send"/> - - <item - android:id="@+id/cancel" - android:icon="@drawable/ic_menu_close_clear_cancel" - android:showAsAction="ifRoom" - android:title="@string/cancel_connection_long" - android:titleCondensed="@string/cancel_connection"/> - <item - android:id="@+id/edit_vpn" - android:alphabeticShortcut="e" - android:icon="@drawable/ic_menu_edit" - android:showAsAction="withText|ifRoom" - android:title="@string/edit_vpn" - android:visible="false"/> - -</menu> |