diff options
author | cyberta <cyberta@riseup.net> | 2020-01-31 22:46:24 -0800 |
---|---|---|
committer | cyberta <cyberta@riseup.net> | 2020-01-31 22:46:24 -0800 |
commit | 0e8f40e75eb1a5fe2d3c212b5939fdbf427ec0f5 (patch) | |
tree | f6b0adef18755cc8c107897e625595614e5dce36 /app/src/main/java/se/leap/bitmaskclient/fragments/TetheringDialog.java | |
parent | 721d222a457ec0dfec28bc4ee4908b50f04904fc (diff) | |
parent | b8ba423d997f5dbb2541b4f4542a2b6b30400485 (diff) |
Merge branch 'implement_tethering_for_rooted_devices' into 'master'
Implement tethering for rooted devices
See merge request leap/bitmask_android!98
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.java | 239 |
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(); + } + } + +} |