summaryrefslogtreecommitdiff
path: root/app/src/main/java/se/leap/bitmaskclient/fragments/TetheringDialog.java
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/java/se/leap/bitmaskclient/fragments/TetheringDialog.java')
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/fragments/TetheringDialog.java239
1 files changed, 239 insertions, 0 deletions
diff --git a/app/src/main/java/se/leap/bitmaskclient/fragments/TetheringDialog.java b/app/src/main/java/se/leap/bitmaskclient/fragments/TetheringDialog.java
new file mode 100644
index 00000000..c53d2a6c
--- /dev/null
+++ b/app/src/main/java/se/leap/bitmaskclient/fragments/TetheringDialog.java
@@ -0,0 +1,239 @@
+package se.leap.bitmaskclient.fragments;
+
+import android.app.Dialog;
+import android.content.Intent;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.support.annotation.NonNull;
+import android.support.v7.app.AlertDialog;
+import android.support.v7.app.AppCompatDialogFragment;
+import android.support.v7.widget.AppCompatTextView;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.text.Spannable;
+import android.text.SpannableString;
+import android.text.method.LinkMovementMethod;
+import android.text.style.ClickableSpan;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+/**
+ * Copyright (c) 2020 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/>.
+ */
+
+import java.util.Observable;
+import java.util.Observer;
+
+import butterknife.ButterKnife;
+import butterknife.InjectView;
+import de.blinkt.openvpn.core.VpnStatus;
+import se.leap.bitmaskclient.R;
+import se.leap.bitmaskclient.firewall.FirewallManager;
+import se.leap.bitmaskclient.tethering.TetheringObservable;
+import se.leap.bitmaskclient.utils.PreferenceHelper;
+import se.leap.bitmaskclient.views.IconCheckboxEntry;
+
+public class TetheringDialog extends AppCompatDialogFragment implements Observer {
+
+ public final static String TAG = TetheringDialog.class.getName();
+
+ @InjectView(R.id.tvTitle)
+ AppCompatTextView title;
+
+ @InjectView(R.id.user_message)
+ AppCompatTextView userMessage;
+
+ @InjectView(R.id.selection_list_view)
+ RecyclerView selectionListView;
+ DialogListAdapter adapter;
+ private DialogListAdapter.ViewModel[] dataset;
+
+ public static class DialogListAdapter extends RecyclerView.Adapter<DialogListAdapter.ViewHolder> {
+
+ interface OnItemClickListener {
+ void onItemClick(ViewModel item);
+ }
+
+ private ViewModel[] dataSet;
+ private OnItemClickListener clickListener;
+
+ DialogListAdapter(ViewModel[] dataSet, OnItemClickListener clickListener) {
+ this.dataSet = dataSet;
+ this.clickListener = clickListener;
+ }
+
+ @NonNull
+ @Override
+ public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
+ IconCheckboxEntry v = new IconCheckboxEntry(viewGroup.getContext());
+ return new ViewHolder(v);
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull ViewHolder viewHolder, int i) {
+ viewHolder.bind(dataSet[i], clickListener);
+ }
+
+ @Override
+ public int getItemCount() {
+ return dataSet.length;
+ }
+
+ public static class ViewModel {
+
+ public Drawable image;
+ public String text;
+ public boolean checked;
+ public boolean enabled;
+
+ ViewModel(Drawable image, String text, boolean checked, boolean enabled) {
+ this.image = image;
+ this.text = text;
+ this.checked = checked;
+ this.enabled = enabled;
+ }
+ }
+
+ public static class ViewHolder extends RecyclerView.ViewHolder {
+
+ ViewHolder(IconCheckboxEntry v) {
+ super(v);
+ }
+
+ public void bind(ViewModel model, OnItemClickListener onClickListener) {
+ ((IconCheckboxEntry) this.itemView).bind(model);
+ this.itemView.setOnClickListener(v -> {
+ model.checked = !model.checked;
+ ((IconCheckboxEntry) itemView).setChecked(model.checked);
+ onClickListener.onItemClick(model);
+ });
+ }
+ }
+ }
+
+ @NonNull
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ LayoutInflater inflater = getActivity().getLayoutInflater();
+ View view = inflater.inflate(R.layout.d_list_selection, null);
+ ButterKnife.inject(this, view);
+
+ title.setText(R.string.tethering);
+ userMessage.setMovementMethod(LinkMovementMethod.getInstance());
+ userMessage.setLinkTextColor(getContext().getResources().getColor(R.color.colorPrimary));
+ userMessage.setText(createUserMessage());
+
+ initDataset();
+ adapter = new DialogListAdapter(dataset, this::onItemClick);
+ selectionListView.setAdapter(adapter);
+ selectionListView.setLayoutManager(new LinearLayoutManager(getActivity()));
+
+
+ builder.setView(view)
+ .setPositiveButton(android.R.string.ok, (dialog, id) -> {
+ PreferenceHelper.allowWifiTethering(getContext(), dataset[0].checked);
+ PreferenceHelper.allowUsbTethering(getContext(), dataset[1].checked);
+// PreferenceHelper.allowBluetoothTethering(getContext(), dataset[2].checked);
+ TetheringObservable.allowVpnWifiTethering(dataset[0].checked);
+ TetheringObservable.allowVpnUsbTethering(dataset[1].checked);
+// TetheringObservable.allowVpnBluetoothTethering(dataset[2].checked);
+ FirewallManager firewallManager = new FirewallManager(getContext().getApplicationContext(), false);
+ if (VpnStatus.isVPNActive()) {
+ if (TetheringObservable.getInstance().getTetheringState().hasAnyDeviceTetheringEnabled() &&
+ TetheringObservable.getInstance().getTetheringState().hasAnyVpnTetheringAllowed()) {
+ firewallManager.startTethering();
+ } else {
+ firewallManager.stopTethering();
+ }
+ }
+ }).setNegativeButton(R.string.cancel, (dialog, id) -> dialog.cancel());
+ return builder.create();
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ dataset[0].enabled = TetheringObservable.getInstance().isWifiTetheringEnabled();
+ dataset[1].enabled = TetheringObservable.getInstance().isUsbTetheringEnabled();
+// dataset[2].enabled = TetheringObservable.getInstance().isBluetoothTetheringEnabled();
+ adapter.notifyDataSetChanged();
+ TetheringObservable.getInstance().addObserver(this);
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ TetheringObservable.getInstance().deleteObserver(this);
+ }
+
+ public void onItemClick(DialogListAdapter.ViewModel item) {
+
+ }
+
+ private CharSequence createUserMessage() {
+ String tetheringMessage = getString(R.string.tethering_message);
+ String systemSettings = getString(R.string.tethering_system_settings);
+ String systemSettingsMessage = getString(R.string.tethering_enabled_message, systemSettings);
+ String wholeMessage = systemSettingsMessage + "\n\n" + tetheringMessage;
+ int startIndex = wholeMessage.indexOf(systemSettings, 0);
+ int endIndex = startIndex + systemSettings.length();
+
+ Spannable spannable = new SpannableString(wholeMessage);
+ spannable.setSpan(new ClickableSpan() {
+ @Override
+ public void onClick(@NonNull View widget) {
+ Intent intent = new Intent(Settings.ACTION_WIRELESS_SETTINGS);
+ startActivity(intent);
+ }
+ }, startIndex, endIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+
+ return spannable;
+ }
+
+ private void initDataset() {
+ dataset = new DialogListAdapter.ViewModel[] {
+ new DialogListAdapter.ViewModel(getContext().getResources().getDrawable(R.drawable.ic_wifi),
+ getContext().getString(R.string.tethering_wifi),
+ PreferenceHelper.isWifiTetheringAllowed(getContext()),
+ TetheringObservable.getInstance().isWifiTetheringEnabled()),
+ new DialogListAdapter.ViewModel(getContext().getResources().getDrawable(R.drawable.ic_usb),
+ getContext().getString(R.string.tethering_usb),
+ PreferenceHelper.isUsbTetheringAllowed(getContext()),
+ TetheringObservable.getInstance().isUsbTetheringEnabled()),
+/* new DialogListAdapter.ViewModel(getContext().getResources().getDrawable(R.drawable.ic_bluetooth),
+ getContext().getString(R.string.tethering_bluetooth),
+ PreferenceHelper.isBluetoothTetheringAllowed(getContext()),
+ TetheringObservable.getInstance().isUsbTetheringEnabled())*/
+ };
+ }
+
+ @Override
+ public void update(Observable o, Object arg) {
+ if (o instanceof TetheringObservable) {
+ TetheringObservable observable = (TetheringObservable) o;
+ Log.d(TAG, "TetheringObservable is updated");
+ dataset[0].enabled = observable.isWifiTetheringEnabled();
+ dataset[1].enabled = observable.isUsbTetheringEnabled();
+// dataset[2].enabled = observable.isBluetoothTetheringEnabled();
+ adapter.notifyDataSetChanged();
+ }
+ }
+
+}