Compare commits

..

44 Commits

Author SHA1 Message Date
Jason A. Donenfeld 164ec1e31d Bump version so that we have correct submodule hashes
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-11-01 03:41:56 +01:00
Jason A. Donenfeld 373a5f18d6 tools: update submodules
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-10-30 01:01:49 +01:00
Jason A. Donenfeld 36058ead7d Never use system go
Telling people to patch their system go is bonkers.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-10-11 00:23:17 +02:00
Jason A. Donenfeld 33fd5b4634 Update to go modules
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-10-09 19:46:48 +02:00
Jason A. Donenfeld 91647978e6 Fix small error
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-10-01 17:54:47 +02:00
Jason A. Donenfeld d0b64f4bd5 Version bump
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-10-01 17:47:24 +02:00
Jason A. Donenfeld c23d58bc27 Peer: prefer v4 endpoints to v6
This works around DNS64 XLAT changeovers.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-10-01 17:13:14 +02:00
Jason A. Donenfeld 49a9475c4a strings: properly mark positionals
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-10-01 16:33:37 +02:00
Jason A. Donenfeld 364032fe84 Update gradle and external deps
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-10-01 16:30:07 +02:00
Jason A. Donenfeld 5658584803 global: update copyright headers
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-09-06 21:32:46 -06:00
Jason A. Donenfeld d580200989 Version bump
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-08-26 11:15:23 -06:00
Jason A. Donenfeld c2cdde73d1 tools: bump submodules
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-08-26 11:09:36 -06:00
Jason A. Donenfeld bc74d4d7f8 libwg-go: update golang version
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-08-26 11:08:45 -06:00
Harsh Shandilya 535c611f2d QuickTileService: Don't use deprecated getDrawable method
Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
2018-08-26 11:04:01 -06:00
Harsh Shandilya 6efbf65405 Target SDK 28
Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
2018-08-26 11:04:01 -06:00
Harsh Shandilya abb121224d FragmentUtils: Make final and prevent instantiation
Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
2018-08-26 11:04:01 -06:00
Harsh Shandilya 8ad4657d6f Sort dependencies
Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
2018-08-26 11:04:01 -06:00
Harsh Shandilya 6d3f1e00a5 Supress false-positive DefaultLocale warnings
We decided in 402472237e8f that it's a bad idea for our use-case

Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
2018-08-26 11:04:01 -06:00
Harsh Shandilya c38f6c471d Extract error messages to string resources
Useful for validation errors and localisation later on

Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
2018-08-26 11:04:01 -06:00
Jason A. Donenfeld 85462de254 MonkeyedSnackbar: remove
This didn't actually help with much and caused problems.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-08-26 10:51:21 -06:00
Zhao Gang 61d4f17f5d config: fix wrong Peer endpoint string format
When a tunnel is running, saving the tunnel's config with an IPv6
address endpoint like [::1]:42 would result in the wrong format ::1:42.
This patch fixes it.

For endpoints with an IPv6 address(e.g. [::1]:42). Since the default
endpoint InetSocketAddress is created unresolved, getEndpointString()
returns "[::1]:42" (InetSocketAddress.getHostString() returns the
literal hostname). After the endpoint is resolved, getEndpointString()
returns "::1:42" (InetSocketAddress.getHostString() returns the IPv6
address without the square brackets). This inconsistent return values
caused the above mentioned bug.

With this patch, function getEndpointString would return the right
format string whether the endpoint is resolved or not.

Signed-off-by: Zhao Gang <gang.zhao.42@gmail.com>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-08-16 12:08:09 -07:00
Jason A. Donenfeld 09cf73cd3c GoBackend: make socket IPC optional
This fixes the multi-user case, which cannot be determined at compile
time and probably isn't reasonable to consider anyway in a global
manner.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-07-31 14:27:29 +02:00
Jason A. Donenfeld ffa3cefa67 Style: use attrs from appcompat rather than from frameworks
This isn't possible for colorForeground, colorBackground,
textAppearanceMedium, but at least it's useful for some things here.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-07-30 22:41:55 +02:00
Jason A. Donenfeld 8ec2cc8582 FloatingActionsMenu: don't wrap context on asus api 21
Works around frameworks bug.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-07-30 17:35:08 +02:00
Jason A. Donenfeld 75dfa0643b Show different color for multiselection
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-07-30 16:28:03 +02:00
Jason A. Donenfeld d5cde43158 Replace hard-coded colors with theme colors
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-07-30 14:43:56 +02:00
Harsh Shandilya 6493a9a1f2 Remove placeholder color and directly use alpha
Why wasn't this done like this in the first place?

Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
2018-07-30 14:28:27 +02:00
Jason A. Donenfeld f35e059194 MonkeyedSnackbar: fix typos
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-07-29 19:17:10 +02:00
Jason A. Donenfeld 3cb3e9d8b7 Version bump
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-07-29 18:52:54 +02:00
Jason A. Donenfeld 5dfc5659ad ConfigNamingDialog: use name input filter
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-07-29 18:44:30 +02:00
Jason A. Donenfeld c4102992ae MonkeyedSnackbar: work around Harsh's broken phone
I think I'd probably like to revert this, since presumably there's a
good reason in the first place why the support lib disables animations
when accessibility services are turned on?

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-07-29 18:35:26 +02:00
Jason A. Donenfeld 219f4e8016 MSF: make it more obvious what needs to be done
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-07-29 17:21:30 +02:00
Jason A. Donenfeld 6558140a7c FloatingActionButtonBehavior: animate transitions
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-07-29 17:21:30 +02:00
Jason A. Donenfeld db7b61ab80 Roll back to API 27 for now
There's no source available for API 28, which is a pain. But this commit
should be reverted whenever source is released.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-07-29 16:01:44 +02:00
Jason A. Donenfeld bce5d852e1 Target API 28
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-07-29 15:46:01 +02:00
Jason A. Donenfeld b960b4a6cd TunnelListFragment: show selected tunnel
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-07-29 05:57:53 +02:00
Jason A. Donenfeld 1b10e75168 TunnelListFragment: fix multiselection on rotation
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-07-29 04:50:16 +02:00
Jason A. Donenfeld 07359e392c FloatingActionButonBehavior: set translation back to 0 when snackbar dies
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-07-29 04:23:30 +02:00
Jason A. Donenfeld e5a5bad240 MainActivity: only show two column on tablets
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-07-29 03:46:45 +02:00
Samuel Holland ca92ac60b7 MainActivity: Fix fragment selection logic
Signed-off-by: Samuel Holland <samuel@sholland.org>
2018-07-28 17:07:37 -05:00
Jason A. Donenfeld e29c21f8df Application: refuse to run on old android
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-07-28 18:27:45 +02:00
Jason A. Donenfeld 6ceeac93bf QuickTileService: fix bug the wrong way
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-07-28 17:55:24 +02:00
Jason A. Donenfeld 9f861096ac config: show more informative error message on wrong key
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-07-27 15:20:23 +02:00
Jason A. Donenfeld 520df16885 Set ACRA install source
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-07-26 13:46:18 +02:00
93 changed files with 725 additions and 425 deletions
+8 -8
View File
@@ -6,19 +6,20 @@ apply from: 'nonnull.gradle'
final def keystorePropertiesFile = rootProject.file("keystore.properties")
android {
buildToolsVersion '28.0.1'
buildToolsVersion '28.0.3'
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
compileSdkVersion 27
compileSdkVersion 28
dataBinding.enabled true
defaultConfig {
applicationId 'com.wireguard.android'
minSdkVersion 21
targetSdkVersion 27
versionCode 437
versionName '0.0.20180725'
targetSdkVersion 28
versionCode 442
versionName '0.0.20181031'
buildConfigField 'int', 'MIN_SDK_VERSION', "$minSdkVersion.apiLevel"
}
// If the keystore file exists
if (keystorePropertiesFile.exists()) {
@@ -79,12 +80,11 @@ dependencies {
implementation "com.android.support:design:$supportLibsVersion"
implementation "com.android.support:preference-v14:$supportLibsVersion"
implementation "com.android.support:support-annotations:$supportLibsVersion"
implementation "net.sourceforge.streamsupport:android-retrofuture:$streamsupportVersion"
implementation "net.sourceforge.streamsupport:android-retrostreams:$streamsupportVersion"
implementation "com.google.code.findbugs:jsr305:$jsr305Version"
implementation "com.journeyapps:zxing-android-embedded:$zxingEmbeddedVersion"
implementation "net.sourceforge.streamsupport:android-retrofuture:$streamsupportVersion"
implementation "net.sourceforge.streamsupport:android-retrostreams:$streamsupportVersion"
implementation "ch.acra:acra-http:$acraVersion"
}
tasks.withType(JavaCompile) {
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright © 2018 Eric Kuck <eric@bluelinelabs.com>.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,15 +1,17 @@
/*
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.preference.PreferenceManager;
@@ -69,9 +71,11 @@ public class Application extends android.app.Application {
* check the DN of the certs that signed the apk, without even bothering to try
* validating that they're authentic. It's a good enough heuristic.
*/
private static boolean shouldEnableCrashReporting(final Context context) {
@SuppressWarnings("deprecation")
@Nullable
private static String getInstallSource(final Context context) {
if (BuildConfig.DEBUG)
return false;
return null;
try {
final CertificateFactory cf = CertificateFactory.getInstance("X509");
for (final Signature sig : context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES).signatures) {
@@ -82,21 +86,35 @@ public class Application extends android.app.Application {
continue;
switch (parts[1]) {
case "Google Inc.":
return "Play Store";
case "fdroid.org":
return true;
return "F-Droid";
}
}
} catch (final Exception ignored) { }
}
} catch (final Exception ignored) { }
return false;
return null;
}
@Override
protected void attachBaseContext(final Context context) {
super.attachBaseContext(context);
if (shouldEnableCrashReporting(context))
if (BuildConfig.MIN_SDK_VERSION > Build.VERSION.SDK_INT) {
final Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
System.exit(0);
}
final String installSource = getInstallSource(context);
if (installSource != null) {
ACRA.init(this);
ACRA.getErrorReporter().putCustomData("installSource", installSource);
}
}
public static Application get() {
@@ -165,9 +183,11 @@ public class Application extends android.app.Application {
asyncWorker.supplyAsync(Application::getBackend).thenAccept(backend -> {
futureBackend.complete(backend);
ACRA.getErrorReporter().putCustomData("backend", backend.getClass().getSimpleName());
asyncWorker.supplyAsync(backend::getVersion).thenAccept(version ->
ACRA.getErrorReporter().putCustomData("backendVersion", version));
if (ACRA.isInitialised()) {
ACRA.getErrorReporter().putCustomData("backend", backend.getClass().getSimpleName());
asyncWorker.supplyAsync(backend::getVersion).thenAccept(version ->
ACRA.getErrorReporter().putCustomData("backendVersion", version));
}
});
}
}
@@ -1,6 +1,5 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,6 +1,5 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -14,6 +13,7 @@ import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.Icon;
import android.os.Build;
import android.os.IBinder;
import android.service.quicksettings.Tile;
import android.service.quicksettings.TileService;
import android.support.annotation.Nullable;
@@ -44,10 +44,26 @@ public class QuickTileService extends TileService {
@Nullable private Icon iconOn;
@Nullable private Icon iconOff;
@SuppressWarnings("deprecation")
/* This works around an annoying unsolved frameworks bug some people are hitting. */
@Override
@Nullable
public IBinder onBind(final Intent intent) {
IBinder ret = null;
try {
ret = super.onBind(intent);
} catch (final Exception e) {
Log.d(TAG, "Failed to bind to TileService", e);
}
return ret;
}
@Override
public void onCreate() {
final SlashDrawable icon = new SlashDrawable(getResources().getDrawable(R.drawable.ic_tile));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
iconOff = iconOn = Icon.createWithResource(this, R.drawable.ic_tile);
return;
}
final SlashDrawable icon = new SlashDrawable(getResources().getDrawable(R.drawable.ic_tile, Application.get().getTheme()));
icon.setAnimationEnabled(false); /* Unfortunately we can't have animations, since Icons are marshaled. */
icon.setSlashed(false);
Bitmap b = Bitmap.createBitmap(icon.getIntrinsicWidth(), icon.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
@@ -55,17 +71,12 @@ public class QuickTileService extends TileService {
icon.setBounds(0, 0, c.getWidth(), c.getHeight());
icon.draw(c);
iconOn = Icon.createWithBitmap(b);
/* TODO(msf): Change this to an explicit test for P when we start targetting SDK 28 */
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O_MR1) {
iconOff = iconOn;
} else {
icon.setSlashed(true);
b = Bitmap.createBitmap(icon.getIntrinsicWidth(), icon.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
c = new Canvas(b);
icon.setBounds(0, 0, c.getWidth(), c.getHeight());
icon.draw(c);
iconOff = Icon.createWithBitmap(b);
}
icon.setSlashed(true);
b = Bitmap.createBitmap(icon.getIntrinsicWidth(), icon.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
c = new Canvas(b);
icon.setBounds(0, 0, c.getWidth(), c.getHeight());
icon.draw(c);
iconOff = Icon.createWithBitmap(b);
}
@Override
@@ -1,6 +1,5 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,6 +1,5 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -10,12 +9,13 @@ import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.support.v7.app.ActionBar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.LinearLayout;
import com.wireguard.android.R;
import com.wireguard.android.fragment.TunnelDetailFragment;
@@ -23,71 +23,46 @@ import com.wireguard.android.fragment.TunnelEditorFragment;
import com.wireguard.android.fragment.TunnelListFragment;
import com.wireguard.android.model.Tunnel;
import java.util.List;
import java9.util.stream.Stream;
/**
* CRUD interface for WireGuard tunnels. This activity serves as the main entry point to the
* WireGuard application, and contains several fragments for listing, viewing details of, and
* editing the configuration and interface state of WireGuard tunnels.
*/
public class MainActivity extends BaseActivity {
private static final String KEY_STATE = "fragment_state";
private static final String TAG = "WireGuard/" + MainActivity.class.getSimpleName();
private State state = State.EMPTY;
private boolean moveToState(final State nextState) {
if (state == nextState)
return false;
final FragmentManager fragmentManager = getSupportFragmentManager();
Log.i(TAG, "Moving from " + state.name() + " to " + nextState.name());
if (nextState.layer > state.layer + 1) {
moveToState(State.ofLayer(state.layer + 1));
moveToState(nextState);
return true;
} else if (nextState.layer == state.layer + 1) {
final Fragment fragment = Fragment.instantiate(this, nextState.fragment);
final FragmentTransaction transaction = fragmentManager.beginTransaction()
.replace(R.id.master_fragment, fragment)
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
if (state.layer > 0)
transaction.addToBackStack(null);
transaction.commitAllowingStateLoss(); /* TODO: switch back to .commit() when this function is rewritten. */
} else if (nextState.layer == state.layer - 1) {
if (fragmentManager.getBackStackEntryCount() == 0)
return false;
fragmentManager.popBackStack();
} else if (nextState.layer < state.layer - 1) {
moveToState(State.ofLayer(state.layer - 1));
moveToState(nextState);
return true;
}
state = nextState;
if (state.layer <= State.LIST.layer)
setSelectedTunnel(null);
updateActionBar();
return true;
}
public class MainActivity extends BaseActivity
implements FragmentManager.OnBackStackChangedListener {
@Nullable private ActionBar actionBar;
private boolean isTwoPaneLayout;
@Nullable private TunnelListFragment listFragment;
@Override
public void onBackPressed() {
final List<Fragment> fragments = getSupportFragmentManager().getFragments();
boolean handled = false;
if (!fragments.isEmpty() && fragments.get(0) instanceof TunnelListFragment) {
handled = ((TunnelListFragment) fragments.get(0)).collapseActionMenu();
final int backStackEntries = getSupportFragmentManager().getBackStackEntryCount();
// If the action menu is visible and expanded, collapse it instead of navigating back.
if (isTwoPaneLayout || backStackEntries == 0) {
if (listFragment != null && listFragment.collapseActionMenu())
return;
}
if (!handled) {
handled = moveToState(State.ofLayer(state.layer - 1));
// If the two-pane layout does not have an editor open, going back should exit the app.
if (isTwoPaneLayout && backStackEntries <= 1) {
finish();
return;
}
if (!handled) {
super.onBackPressed();
// Deselect the current tunnel on navigating back from the detail pane to the one-pane list.
if (!isTwoPaneLayout && backStackEntries == 1) {
setSelectedTunnel(null);
return;
}
super.onBackPressed();
}
@Override public void onBackStackChanged() {
if (actionBar == null)
return;
// Do not show the home menu when the two-pane layout is at the detail view (see above).
final int backStackEntries = getSupportFragmentManager().getBackStackEntryCount();
final int minBackStackEntries = isTwoPaneLayout ? 2 : 1;
actionBar.setDisplayHomeAsUpEnabled(backStackEntries >= minBackStackEntries);
}
// We use onTouchListener here to avoid the UI click sound, hence
@@ -97,25 +72,14 @@ public class MainActivity extends BaseActivity {
protected void onCreate(@Nullable final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
if (savedInstanceState != null && savedInstanceState.getString(KEY_STATE) != null)
state = State.valueOf(savedInstanceState.getString(KEY_STATE));
if (state == State.EMPTY) {
State initialState = getSelectedTunnel() != null ? State.DETAIL : State.LIST;
if (getIntent() != null && getIntent().getStringExtra(KEY_STATE) != null)
initialState = State.valueOf(getIntent().getStringExtra(KEY_STATE));
moveToState(initialState);
}
updateActionBar();
final int actionBarId = getResources().getIdentifier("action_bar", "id", getPackageName());
if (actionBarId != 0 && findViewById(actionBarId) != null) {
findViewById(actionBarId).setOnTouchListener((v, e) -> {
final List<Fragment> fragments = getSupportFragmentManager().getFragments();
if (!fragments.isEmpty() && fragments.get(0) instanceof TunnelListFragment) {
((TunnelListFragment) fragments.get(0)).collapseActionMenu();
}
return false;
});
}
actionBar = getSupportActionBar();
isTwoPaneLayout = findViewById(R.id.master_detail_wrapper) instanceof LinearLayout;
listFragment = (TunnelListFragment) getSupportFragmentManager().findFragmentByTag("LIST");
getSupportFragmentManager().addOnBackStackChangedListener(this);
onBackStackChanged();
final View actionBarView = findViewById(R.id.action_bar);
if (actionBarView != null)
actionBarView.setOnTouchListener((v, e) -> listFragment != null && listFragment.collapseActionMenu());
}
@Override
@@ -129,11 +93,14 @@ public class MainActivity extends BaseActivity {
switch (item.getItemId()) {
case android.R.id.home:
// The back arrow in the action bar should act the same as the back button.
moveToState(State.ofLayer(state.layer - 1));
onBackPressed();
return true;
case R.id.menu_action_edit:
if (getSelectedTunnel() != null)
moveToState(State.EDITOR);
getSupportFragmentManager().beginTransaction()
.replace(R.id.detail_container, new TunnelEditorFragment())
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
.addToBackStack(null)
.commit();
return true;
case R.id.menu_action_save:
// This menu item is handled by the editor fragment.
@@ -147,37 +114,26 @@ public class MainActivity extends BaseActivity {
}
@Override
protected void onSaveInstanceState(final Bundle outState) {
outState.putString(KEY_STATE, state.name());
super.onSaveInstanceState(outState);
}
@Override
protected void onSelectedTunnelChanged(@Nullable final Tunnel oldTunnel, @Nullable final Tunnel newTunnel) {
moveToState(newTunnel != null ? State.DETAIL : State.LIST);
}
private void updateActionBar() {
if (getSupportActionBar() != null)
getSupportActionBar().setDisplayHomeAsUpEnabled(state.layer > State.LIST.layer);
}
private enum State {
EMPTY(null, 0),
LIST(TunnelListFragment.class, 1),
DETAIL(TunnelDetailFragment.class, 2),
EDITOR(TunnelEditorFragment.class, 3);
@Nullable private final String fragment;
private final int layer;
State(@Nullable final Class<? extends Fragment> fragment, final int layer) {
this.fragment = fragment != null ? fragment.getName() : null;
this.layer = layer;
protected void onSelectedTunnelChanged(@Nullable final Tunnel oldTunnel,
@Nullable final Tunnel newTunnel) {
final FragmentManager fragmentManager = getSupportFragmentManager();
final int backStackEntries = fragmentManager.getBackStackEntryCount();
if (newTunnel == null) {
// Clear everything off the back stack (all editors and detail fragments).
fragmentManager.popBackStackImmediate(0, FragmentManager.POP_BACK_STACK_INCLUSIVE);
return;
}
private static State ofLayer(final int layer) {
return Stream.of(State.values()).filter(s -> s.layer == layer).findFirst().get();
if (backStackEntries == 2) {
// Pop the editor off the back stack to reveal the detail fragment. Use the immediate
// method to avoid the editor picking up the new tunnel while it is still visible.
fragmentManager.popBackStackImmediate();
} else if (backStackEntries == 0) {
// Create and show a new detail fragment.
fragmentManager.beginTransaction()
.add(R.id.detail_container, new TunnelDetailFragment())
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
.addToBackStack(null)
.commit();
}
}
}
@@ -1,6 +1,5 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,5 +1,5 @@
/*
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,6 +1,5 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,6 +1,5 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,6 +1,5 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,6 +1,5 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,6 +1,5 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,6 +1,5 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,6 +1,5 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,6 +1,5 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,6 +1,5 @@
/*
* Copyright © 2018 Eric Kuck <eric@bluelinelabs.com>.
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,6 +1,5 @@
/*
* Copyright © 2018 Eric Kuck <eric@bluelinelabs.com>.
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,6 +1,5 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,6 +1,5 @@
/*
* Copyright © 2018 Eric Kuck <eric@bluelinelabs.com>.
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,6 +1,5 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,6 +1,5 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -174,6 +173,7 @@ public class TunnelEditorFragment extends BaseFragment implements AppExclusionLi
}
// Tell the activity to finish itself or go back to the detail view.
getActivity().runOnUiThread(() -> {
// TODO(smaeul): Remove this hack when fixing the Config ViewModel
// The selected tunnel has to actually change, but we have to remember this one.
final Tunnel savedTunnel = tunnel;
if (savedTunnel == getSelectedTunnel())
@@ -1,6 +1,5 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -21,6 +20,7 @@ import android.support.design.widget.Snackbar;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.view.ActionMode;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
@@ -38,6 +38,8 @@ import com.wireguard.android.databinding.TunnelListFragmentBinding;
import com.wireguard.android.databinding.TunnelListItemBinding;
import com.wireguard.android.model.Tunnel;
import com.wireguard.android.util.ExceptionLoggers;
import com.wireguard.android.util.ObservableSortedKeyedList;
import com.wireguard.android.widget.MultiselectableRelativeLayout;
import com.wireguard.android.widget.fab.FloatingActionsMenuRecyclerViewScrollListener;
import com.wireguard.config.Config;
@@ -85,7 +87,7 @@ public class TunnelListFragment extends BaseFragment {
final FragmentManager fragmentManager = getFragmentManager();
if (fragmentManager != null)
ConfigNamingDialogFragment.newInstance(configText).show(fragmentManager, null);
} catch (final IllegalArgumentException|IOException exception) {
} catch (final Exception exception) {
onTunnelImportFinished(Collections.emptyList(), Collections.singletonList(exception));
}
}
@@ -260,9 +262,20 @@ public class TunnelListFragment extends BaseFragment {
super.onPause();
}
private MultiselectableRelativeLayout viewForTunnel(final Tunnel tunnel, final List tunnels) {
return (MultiselectableRelativeLayout)binding.tunnelList.findViewHolderForAdapterPosition(tunnels.indexOf(tunnel)).itemView;
}
@Override
public void onSelectedTunnelChanged(@Nullable final Tunnel oldTunnel, @Nullable final Tunnel newTunnel) {
// Do nothing.
if (binding == null)
return;
Application.getTunnelManager().getTunnels().thenAccept(tunnels -> {
if (newTunnel != null)
viewForTunnel(newTunnel, tunnels).setSingleSelected(true);
if (oldTunnel != null)
viewForTunnel(oldTunnel, tunnels).setSingleSelected(false);
});
}
private void onTunnelDeletionFinished(final Integer count, @Nullable final Throwable throwable) {
@@ -304,6 +317,26 @@ public class TunnelListFragment extends BaseFragment {
Snackbar.make(binding.mainContainer, message, Snackbar.LENGTH_LONG).show();
}
@Override
public void onSaveInstanceState(final Bundle outState) {
super.onSaveInstanceState(outState);
outState.putIntegerArrayList("CHECKED_ITEMS", actionModeListener.getCheckedItems());
}
@Override
public void onActivityCreated(@Nullable final Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (savedInstanceState != null) {
final Collection<Integer> checkedItems = savedInstanceState.getIntegerArrayList("CHECKED_ITEMS");
if (checkedItems != null) {
for (final Integer i : checkedItems)
actionModeListener.setItemChecked(i, true);
}
}
}
@Override
public void onViewStateRestored(@Nullable final Bundle savedInstanceState) {
super.onViewStateRestored(savedInstanceState);
@@ -328,7 +361,10 @@ public class TunnelListFragment extends BaseFragment {
return true;
});
binding.getRoot().setActivated(actionModeListener.checkedItems.contains(position));
if (actionMode != null)
((MultiselectableRelativeLayout)binding.getRoot()).setMultiSelected(actionModeListener.checkedItems.contains(position));
else
((MultiselectableRelativeLayout)binding.getRoot()).setSingleSelected(getSelectedTunnel() == tunnel);
});
}
@@ -377,6 +413,7 @@ public class TunnelListFragment extends BaseFragment {
resources = getActivity().getResources();
}
mode.getMenuInflater().inflate(R.menu.tunnel_list_action_mode, menu);
binding.tunnelList.getAdapter().notifyDataSetChanged();
return true;
}
@@ -384,7 +421,6 @@ public class TunnelListFragment extends BaseFragment {
public void onDestroyActionMode(final ActionMode mode) {
actionMode = null;
resources = null;
checkedItems.clear();
binding.tunnelList.getAdapter().notifyDataSetChanged();
}
@@ -393,6 +429,10 @@ public class TunnelListFragment extends BaseFragment {
setItemChecked(position, !checkedItems.contains(position));
}
public ArrayList<Integer> getCheckedItems() {
return new ArrayList<>(checkedItems);
}
void setItemChecked(final int position, final boolean checked) {
if (checked) {
checkedItems.add(position);
@@ -400,15 +440,16 @@ public class TunnelListFragment extends BaseFragment {
checkedItems.remove(position);
}
final RecyclerView.Adapter adapter = binding == null ? null : binding.tunnelList.getAdapter();
if (actionMode == null && !checkedItems.isEmpty() && getActivity() != null) {
((AppCompatActivity) getActivity()).startSupportActionMode(this);
} else if (actionMode != null && checkedItems.isEmpty()) {
actionMode.finish();
}
if (binding != null) {
binding.tunnelList.getAdapter().notifyItemChanged(position);
}
if (adapter != null)
adapter.notifyItemChanged(position);
updateTitle(actionMode);
}
@@ -1,6 +1,5 @@
/*
* Copyright © 2018 Eric Kuck <eric@bluelinelabs.com>.
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,6 +1,5 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,6 +1,5 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -15,6 +14,7 @@ import android.support.annotation.Nullable;
import com.wireguard.android.Application;
import com.wireguard.android.BR;
import com.wireguard.android.R;
import com.wireguard.android.configStore.ConfigStore;
import com.wireguard.android.model.Tunnel.State;
import com.wireguard.android.model.Tunnel.Statistics;
@@ -46,6 +46,7 @@ public final class TunnelManager extends BaseObservable {
private static final String KEY_RUNNING_TUNNELS = "enabled_configs";
private final ConfigStore configStore;
private final Context context = Application.get();
private final CompletableFuture<ObservableSortedKeyedList<String, Tunnel>> completableTunnels = new CompletableFuture<>();
private final ObservableSortedKeyedList<String, Tunnel> tunnels = new ObservableSortedKeyedArrayList<>(COMPARATOR);
@Nullable private Tunnel lastUsedTunnel;
@@ -64,9 +65,9 @@ public final class TunnelManager extends BaseObservable {
public CompletionStage<Tunnel> create(final String name, @Nullable final Config config) {
if (Tunnel.isNameInvalid(name))
return CompletableFuture.failedFuture(new IllegalArgumentException("Invalid name"));
return CompletableFuture.failedFuture(new IllegalArgumentException(context.getString(R.string.tunnel_error_invalid_name)));
if (tunnels.containsKey(name)) {
final String message = "Tunnel " + name + " already exists";
final String message = context.getString(R.string.tunnel_error_already_exists, name);
return CompletableFuture.failedFuture(new IllegalArgumentException(message));
}
return Application.getAsyncWorker().supplyAsync(() -> configStore.create(name, config))
@@ -212,9 +213,9 @@ public final class TunnelManager extends BaseObservable {
CompletionStage<String> setTunnelName(final Tunnel tunnel, final String name) {
if (Tunnel.isNameInvalid(name))
return CompletableFuture.failedFuture(new IllegalArgumentException("Invalid name"));
return CompletableFuture.failedFuture(new IllegalArgumentException(context.getString(R.string.tunnel_error_invalid_name)));
if (tunnels.containsKey(name)) {
final String message = "Tunnel " + name + " already exists";
final String message = context.getString(R.string.tunnel_error_already_exists, name);
return CompletableFuture.failedFuture(new IllegalArgumentException(message));
}
final State originalState = tunnel.getState();
@@ -1,6 +1,5 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,6 +1,5 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,5 +1,5 @@
/*
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,6 +1,5 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,6 +1,5 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,6 +1,5 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,6 +1,5 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,6 +1,5 @@
/*
* Copyright © 2018 Harsh Shandilya <msfjarvis@gmail.com>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android.util;
@@ -11,7 +10,11 @@ import android.view.ContextThemeWrapper;
import com.wireguard.android.activity.SettingsActivity;
public class FragmentUtils {
public final class FragmentUtils {
private FragmentUtils() {
// Prevent instantiation
}
public static SettingsActivity getPrefActivity(final Preference preference) {
final Context context = preference.getContext();
@@ -1,6 +1,5 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,6 +1,5 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,6 +1,5 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,6 +1,5 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,6 +1,5 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,5 +1,5 @@
/*
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,6 +1,5 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,6 +1,5 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -0,0 +1,57 @@
/*
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android.widget;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.RelativeLayout;
import com.wireguard.android.R;
public class MultiselectableRelativeLayout extends RelativeLayout {
public MultiselectableRelativeLayout(final Context context) {
super(context);
}
public MultiselectableRelativeLayout(final Context context, final AttributeSet attrs) {
super(context, attrs);
}
public MultiselectableRelativeLayout(final Context context, final AttributeSet attrs, final int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public MultiselectableRelativeLayout(final Context context, final AttributeSet attrs, final int defStyleAttr, final int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
private static final int[] STATE_MULTISELECTED = { R.attr.state_multiselected };
private boolean multiselected;
@Override
protected int[] onCreateDrawableState(final int extraSpace) {
if (multiselected) {
final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
mergeDrawableStates(drawableState, STATE_MULTISELECTED);
return drawableState;
}
return super.onCreateDrawableState(extraSpace);
}
public void setMultiSelected(final boolean on) {
if (!multiselected) {
multiselected = true;
refreshDrawableState();
}
setActivated(on);
}
public void setSingleSelected(final boolean on) {
if (multiselected) {
multiselected = false;
refreshDrawableState();
}
setActivated(on);
}
}
@@ -1,6 +1,5 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,6 +1,6 @@
/*
* Copyright © 2018 The Android Open Source Project
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,5 +1,6 @@
/*
* Copyright © 2013 The Android Open Source Project
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,18 +1,23 @@
/*
* Copyright © 2018 Harsh Shandilya <msfjarvis@gmail.com>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.android.widget.fab;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.Snackbar;
import android.support.v4.view.animation.FastOutSlowInInterpolator;
import android.util.AttributeSet;
import android.view.View;
public class FloatingActionButtonBehavior extends CoordinatorLayout.Behavior<FloatingActionsMenu> {
public FloatingActionButtonBehavior(final Context context, final AttributeSet attrs) {
super(context, attrs);
}
@@ -23,10 +28,39 @@ public class FloatingActionButtonBehavior extends CoordinatorLayout.Behavior<Flo
return dependency instanceof Snackbar.SnackbarLayout;
}
private static final long ANIMATION_DURATION = 250;
private static final TimeInterpolator FAST_OUT_SLOW_IN_INTERPOLATOR = new FastOutSlowInInterpolator();
private static void animateChange(final FloatingActionsMenu child, final float destination, final float fullSpan) {
final float origin = child.getBehaviorYTranslation();
if (Math.abs(destination - origin) < fullSpan / 2) {
child.setBehaviorYTranslation(destination);
return;
}
final ValueAnimator animator = new ValueAnimator();
animator.setFloatValues(origin, destination);
animator.setInterpolator(FAST_OUT_SLOW_IN_INTERPOLATOR);
animator.setDuration((long)(ANIMATION_DURATION * (Math.abs(destination - origin) / fullSpan)));
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(final Animator a) {
child.setBehaviorYTranslation(destination);
}
});
animator.addUpdateListener(a -> child.setBehaviorYTranslation((float)a.getAnimatedValue()));
animator.start();
}
@Override
public boolean onDependentViewChanged(final CoordinatorLayout parent, final FloatingActionsMenu child,
final View dependency) {
child.setBehaviorYTranslation(Math.min(0, dependency.getTranslationY() - dependency.getMeasuredHeight()));
animateChange(child, Math.min(0, dependency.getTranslationY() - dependency.getMeasuredHeight()), dependency.getMeasuredHeight());
return true;
}
@Override
public void onDependentViewRemoved(final CoordinatorLayout parent, final FloatingActionsMenu child,
final View dependency) {
animateChange(child, 0, dependency.getMeasuredHeight());
}
}
@@ -1,6 +1,6 @@
/*
* Copyright © 2014 Jerzy Chalupski
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -17,6 +17,7 @@ import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.Keep;
@@ -392,8 +393,10 @@ public class FloatingActionsMenu extends ViewGroup {
}
}
private static final boolean BROKEN_LABEL_STYLE = Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1 && Build.BRAND.equals("ASUS");
private void createLabels() {
final Context context = new ContextThemeWrapper(getContext(), mLabelsStyle);
final Context context = BROKEN_LABEL_STYLE ? getContext() : new ContextThemeWrapper(getContext(), mLabelsStyle);
for (int i = 0; i < mButtonsCount; i++) {
final FloatingActionButton button = (FloatingActionButton) getChildAt(i);
@@ -402,7 +405,8 @@ public class FloatingActionsMenu extends ViewGroup {
final String title = ((LabeledFloatingActionButton) button).getTitle();
final AppCompatTextView label = new AppCompatTextView(context);
label.setTextAppearance(context, mLabelsStyle);
if (!BROKEN_LABEL_STYLE)
label.setTextAppearance(context, mLabelsStyle);
label.setText(title);
addView(label);
@@ -1,5 +1,5 @@
/*
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,6 +1,6 @@
/*
* Copyright © 2014 Jerzy Chalupski
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,6 +1,6 @@
/*
* Copyright © 2014 Jerzy Chalupski
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,11 +1,11 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.config;
import android.annotation.SuppressLint;
import android.support.annotation.Nullable;
import android.text.TextUtils;
@@ -55,6 +55,7 @@ public enum Attribute {
return TextUtils.join(", ", iterable);
}
@Nullable
public static Attribute match(final CharSequence line) {
return KEY_MAP.get(SEPARATOR_PATTERN.split(line)[0].toLowerCase());
}
@@ -65,10 +66,12 @@ public enum Attribute {
return LIST_SEPARATOR_PATTERN.split(string.trim());
}
@SuppressLint("DefaultLocale")
public String composeWith(@Nullable final Object value) {
return String.format("%s = %s%n", token, value);
}
@SuppressLint("DefaultLocale")
public String composeWith(final int value) {
return String.format("%s = %d%n", token, value);
}
@@ -1,11 +1,11 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.config;
import android.content.Context;
import android.databinding.BaseObservable;
import android.databinding.Bindable;
import android.databinding.ObservableArrayList;
@@ -15,6 +15,8 @@ import android.os.Parcelable;
import android.support.annotation.Nullable;
import com.android.databinding.library.baseAdapters.BR;
import com.wireguard.android.Application;
import com.wireguard.android.R;
import java.io.BufferedReader;
import java.io.IOException;
@@ -43,6 +45,7 @@ public class Config {
public static Config from(final BufferedReader reader) throws IOException {
final Config config = new Config();
final Context context = Application.get();
Peer currentPeer = null;
String line;
boolean inInterfaceSection = false;
@@ -65,11 +68,11 @@ public class Config {
} else if (currentPeer != null) {
currentPeer.parse(line);
} else {
throw new IllegalArgumentException("Invalid configuration line: " + line);
throw new IllegalArgumentException(context.getString(R.string.tunnel_error_invalid_config_line, line));
}
}
if (!inInterfaceSection && currentPeer == null) {
throw new IllegalArgumentException("Could not find any config information");
throw new IllegalArgumentException(context.getString(R.string.tunnel_error_no_config_information));
}
return config;
}
@@ -1,6 +1,5 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -8,6 +7,9 @@ package com.wireguard.config;
import android.support.annotation.Nullable;
import com.wireguard.android.Application;
import com.wireguard.android.R;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.InetAddress;
@@ -30,7 +32,7 @@ public final class InetAddresses {
public static InetAddress parse(@Nullable final String address) {
if (address == null || address.isEmpty())
throw new IllegalArgumentException("Empty address");
throw new IllegalArgumentException(Application.get().getString(R.string.tunnel_error_empty_inetaddress));
try {
return (InetAddress) PARSER_METHOD.invoke(null, address);
} catch (final IllegalAccessException | InvocationTargetException e) {
@@ -0,0 +1,72 @@
/*
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.config;
import android.annotation.SuppressLint;
import com.wireguard.android.Application;
import com.wireguard.android.R;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.UnknownHostException;
import javax.annotation.Nullable;
public class InetEndpoint {
private final String host;
private final int port;
@Nullable private InetAddress resolvedHost;
public InetEndpoint(@Nullable final String endpoint) {
if (endpoint.indexOf('/') != -1 || endpoint.indexOf('?') != -1 || endpoint.indexOf('#') != -1)
throw new IllegalArgumentException(Application.get().getString(R.string.tunnel_error_forbidden_endpoint_chars));
final URI uri;
try {
uri = new URI("wg://" + endpoint);
} catch (final URISyntaxException e) {
throw new IllegalArgumentException(e);
}
host = uri.getHost();
port = uri.getPort();
}
public String getHost() {
return host;
}
public int getPort() {
return port;
}
@SuppressLint("DefaultLocale")
public String getResolvedEndpoint() throws UnknownHostException {
if (resolvedHost == null) {
final InetAddress[] candidates = InetAddress.getAllByName(host);
if (candidates.length == 0)
throw new UnknownHostException(host);
for (final InetAddress addr : candidates) {
if (addr instanceof Inet4Address) {
resolvedHost = addr;
break;
}
}
if (resolvedHost == null)
resolvedHost = candidates[0];
}
return String.format(resolvedHost instanceof Inet6Address ?
"[%s]:%d" : "%s:%d", resolvedHost.getHostAddress(), port);
}
@SuppressLint("DefaultLocale")
public String getEndpoint() {
return String.format(host.contains(":") && !host.contains("[") ?
"[%s]:%d" : "%s:%d", host, port);
}
}
@@ -1,6 +1,5 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,18 +1,20 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.config;
import android.content.Context;
import android.databinding.BaseObservable;
import android.databinding.Bindable;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.Nullable;
import com.wireguard.android.Application;
import com.wireguard.android.BR;
import com.wireguard.android.R;
import com.wireguard.crypto.Keypair;
import java.net.InetAddress;
@@ -31,6 +33,7 @@ public class Interface {
@Nullable private Keypair keypair;
private int listenPort;
private int mtu;
private final Context context = Application.get();
public Interface() {
addressList = new ArrayList<>();
@@ -42,7 +45,7 @@ public class Interface {
if (addresses != null && addresses.length > 0) {
for (final String addr : addresses) {
if (addr.isEmpty())
throw new IllegalArgumentException("Address is empty");
throw new IllegalArgumentException(context.getString(R.string.tunnel_error_empty_interface_address));
addressList.add(new InetNetwork(addr));
}
}
@@ -140,6 +143,8 @@ public class Interface {
public void parse(final String line) {
final Attribute key = Attribute.match(line);
if (key == null)
throw new IllegalArgumentException(String.format(context.getString(R.string.tunnel_error_interface_parse_failed), line));
switch (key) {
case ADDRESS:
addAddresses(key.parseList(line));
@@ -1,11 +1,12 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.config;
import android.annotation.SuppressLint;
import android.content.Context;
import android.databinding.BaseObservable;
import android.databinding.Bindable;
import android.os.Parcel;
@@ -13,6 +14,8 @@ import android.os.Parcelable;
import android.support.annotation.Nullable;
import com.android.databinding.library.baseAdapters.BR;
import com.wireguard.android.Application;
import com.wireguard.android.R;
import com.wireguard.crypto.KeyEncoding;
import java.net.Inet6Address;
@@ -34,10 +37,11 @@ import java9.lang.Iterables;
public class Peer {
private final List<InetNetwork> allowedIPsList;
@Nullable private InetSocketAddress endpoint;
@Nullable private InetEndpoint endpoint;
private int persistentKeepalive;
@Nullable private String preSharedKey;
@Nullable private String publicKey;
private final Context context = Application.get();
public Peer() {
allowedIPsList = new ArrayList<>();
@@ -63,7 +67,7 @@ public class Peer {
}
@Nullable
public InetSocketAddress getEndpoint() {
public InetEndpoint getEndpoint() {
return endpoint;
}
@@ -71,7 +75,7 @@ public class Peer {
private String getEndpointString() {
if (endpoint == null)
return null;
return String.format("%s:%d", endpoint.getHostString(), endpoint.getPort());
return endpoint.getEndpoint();
}
public int getPersistentKeepalive() {
@@ -98,21 +102,13 @@ public class Peer {
public String getResolvedEndpointString() throws UnknownHostException {
if (endpoint == null)
throw new UnknownHostException("{empty}");
if (endpoint.isUnresolved())
endpoint = new InetSocketAddress(endpoint.getHostString(), endpoint.getPort());
if (endpoint.isUnresolved())
throw new UnknownHostException(endpoint.getHostString());
if (endpoint.getAddress() instanceof Inet6Address)
return String.format("[%s]:%d",
endpoint.getAddress().getHostAddress(),
endpoint.getPort());
return String.format("%s:%d",
endpoint.getAddress().getHostAddress(),
endpoint.getPort());
return endpoint.getResolvedEndpoint();
}
public void parse(final String line) {
final Attribute key = Attribute.match(line);
if (key == null)
throw new IllegalArgumentException(context.getString(R.string.tunnel_error_interface_parse_failed, line));
switch (key) {
case ALLOWED_IPS:
addAllowedIPs(key.parseList(line));
@@ -139,24 +135,14 @@ public class Peer {
addAllowedIPs(Attribute.stringToList(allowedIPsString));
}
private void setEndpoint(@Nullable final InetSocketAddress endpoint) {
private void setEndpoint(@Nullable final InetEndpoint endpoint) {
this.endpoint = endpoint;
}
private void setEndpointString(@Nullable final String endpoint) {
if (endpoint != null && !endpoint.isEmpty()) {
final InetSocketAddress constructedEndpoint;
if (endpoint.indexOf('/') != -1 || endpoint.indexOf('?') != -1 || endpoint.indexOf('#') != -1)
throw new IllegalArgumentException("Forbidden characters in endpoint");
final URI uri;
try {
uri = new URI("wg://" + endpoint);
} catch (final URISyntaxException e) {
throw new IllegalArgumentException(e);
}
constructedEndpoint = InetSocketAddress.createUnresolved(uri.getHost(), uri.getPort());
setEndpoint(constructedEndpoint);
} else
if (endpoint != null && !endpoint.isEmpty())
setEndpoint(new InetEndpoint(endpoint));
else
setEndpoint(null);
}
@@ -248,7 +234,7 @@ public class Peer {
parent.setPreSharedKey(preSharedKey);
parent.setPublicKey(publicKey);
if (parent.getPublicKey() == null)
throw new IllegalArgumentException("Peer public key may not be empty");
throw new IllegalArgumentException(Application.get().getString(R.string.tunnel_error_empty_peer_public_key));
loadData(parent);
notifyChange();
}
@@ -1,5 +1,6 @@
/*
* Copyright © 2016 Southern Storm Software, Pty Ltd.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,10 +1,13 @@
/*
* Copyright © 2015-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.wireguard.crypto;
import com.wireguard.android.Application;
import com.wireguard.android.R;
/**
* This is a specialized constant-time base64 and hex implementation that resists side-channel attacks.
*/
@@ -15,11 +18,11 @@ public final class KeyEncoding {
public static final int KEY_LENGTH_BASE64 = 44;
public static final int KEY_LENGTH_HEX = 64;
private static final String KEY_LENGTH_BASE64_EXCEPTION_MESSAGE =
"WireGuard base64 keys must be 44 characters encoding 32 bytes";
Application.get().getString(R.string.key_length_base64_exception_message);
private static final String KEY_LENGTH_EXCEPTION_MESSAGE =
"WireGuard keys must be 32 bytes";
Application.get().getString(R.string.key_length_exception_message);
private static final String KEY_LENGTH_HEX_EXCEPTION_MESSAGE =
"WireGuard hex keys must be 64 characters encoding 32 bytes";
Application.get().getString(R.string.key_length_hex_exception_message);
private KeyEncoding() {
// Prevent instantiation.
@@ -1,6 +1,5 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,5 +1,5 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,5 +1,5 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,5 +1,5 @@
/*
* Copyright © 2018 Eric Kuck <eric@bluelinelabs.com>.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,5 +1,5 @@
/*
* Copyright © 2018 Samuel Holland <samuel@sholland.org>
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1,5 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/list_item_activated" android:state_activated="true" /> <!-- TODO(msf): themeify this -->
<item android:drawable="@android:color/transparent" /> <!-- TODO(msf): themeify this -->
</selector>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item>
<selector>
<item app:state_multiselected="true" android:state_activated="true">
<color android:color="?attr/colorControlActivated" />
</item>
<item app:state_multiselected="false" android:state_activated="true">
<color android:color="?attr/colorControlHighlight" />
</item>
</selector>
</item>
<item android:drawable="?attr/selectableItemBackground" />
</layer-list>
@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/list_item_ripple"> <!-- TODO(msf): themeify this -->
<item android:drawable="@drawable/list_item_background" />
<item android:id="@android:id/mask" android:drawable="@android:color/white" />
</ripple>
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/master_detail_wrapper"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="false"
android:divider="?attr/dividerHorizontal"
android:orientation="horizontal"
android:showDividers="middle"
tools:context=".activity.MainActivity">
<fragment
android:name="com.wireguard.android.fragment.TunnelListFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:tag="LIST" />
<FrameLayout
android:id="@+id/detail_container"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3" />
</LinearLayout>
+1 -1
View File
@@ -22,7 +22,7 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/list_item_background_anim"
android:background="@drawable/list_item_background"
android:padding="16dp"
android:orientation="horizontal"
android:gravity="center_vertical"
@@ -1,5 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<import type="com.wireguard.android.widget.NameInputFilter" />
</data>
<FrameLayout
android:layout_width="match_parent"
@@ -15,7 +20,9 @@
android:id="@+id/tunnel_name_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/tunnel_name" />
android:hint="@string/tunnel_name"
android:inputType="textNoSuggestions|textVisiblePassword"
app:filter="@{NameInputFilter.newInstance()}" />
</android.support.design.widget.TextInputLayout>
+14 -2
View File
@@ -1,7 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/master_fragment"
android:id="@+id/master_detail_wrapper"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:ignore="MergeRootFrame" />
tools:context=".activity.MainActivity">
<fragment
android:name="com.wireguard.android.fragment.TunnelListFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:tag="LIST" />
<FrameLayout
android:id="@+id/detail_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
@@ -120,7 +120,7 @@
<TextView
android:id="@+id/public_key_text"
style="?android:attr/editTextStyle"
style="?attr/editTextStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/public_key_label"
@@ -49,7 +49,7 @@
android:layout_width="140dp"
android:layout_height="140dp"
android:layout_gravity="center"
android:tint="@color/transparent_background_placeholder"
android:alpha="0.3333333"
android:layout_marginTop="-70dp"
android:layout_marginBottom="20dp"
android:src="@mipmap/ic_launcher" />
+3 -3
View File
@@ -25,10 +25,10 @@
type="com.wireguard.android.fragment.TunnelListFragment" />
</data>
<RelativeLayout
<com.wireguard.android.widget.MultiselectableRelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/list_item_background_anim"
android:background="@drawable/list_item_background"
android:descendantFocusability="blocksDescendants"
android:padding="16dp">
@@ -51,5 +51,5 @@
android:layout_alignParentEnd="true"
app:checked="@{item.state == State.UP}"
app:onBeforeCheckedChanged="@{fragment::setTunnelState}" />
</RelativeLayout>
</com.wireguard.android.widget.MultiselectableRelativeLayout>
</layout>
+1 -6
View File
@@ -1,13 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- TODO(msf): remove these 4 hard-coded colors and replace with theme colors -->
<color name="list_item_activated">#64cfd8dc</color>
<color name="list_item_ripple">#a0808e95</color>
<!-- TODO(msf): remove these 2 hard-coded colors and replace with theme colors -->
<color name="fab_label_text_color">#000000</color>
<color name="fab_label_background_color">#bbbbbb</color>
<color name="accent">#5e97f6</color>
<!-- TODO(msf): replace with ?android:attr/colorBackground with some alpha -->
<color name="transparent_background_placeholder">#aa2e2e2e</color>
</resources>
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="Multiselected">
<attr name="state_multiselected" format="boolean"/>
</declare-styleable>
</resources>
+1 -6
View File
@@ -1,13 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- TODO(msf): remove these 4 hard-coded colors and replace with theme colors -->
<color name="list_item_activated">#cfd8dc</color> <!-- Blue Grey 200 -->
<color name="list_item_ripple">#808e95</color> <!-- Blue Grey 200 dark -->
<!-- TODO(msf): remove these 2 hard-coded colors and replace with theme colors -->
<color name="fab_label_text_color">#ffffff</color>
<color name="fab_label_background_color">#444444</color>
<color name="accent">#2196F3</color>
<!-- TODO(msf): replace with ?android:attr/colorBackground with some alpha -->
<color name="transparent_background_placeholder">#aafafafa</color>
</resources>
+14 -2
View File
@@ -25,7 +25,7 @@
<string name="allowed_ips">Allowed IPs</string>
<string name="app_name">WireGuard</string>
<string name="cancel">Cancel</string>
<string name="config_save_error">Unable to save configuration for “%s”: %s</string>
<string name="config_save_error">Unable to save configuration for “%1$s”: %2$s</string>
<string name="config_save_success">Successfully saved configuration for “%s”</string>
<string name="create_activity_title">Create WireGuard Tunnel</string>
<string name="create_empty">Create from scratch</string>
@@ -97,8 +97,20 @@
<string name="tunnel_name">Tunnel Name</string>
<string name="tunnel_rename_error">Unable to rename tunnel: %s</string>
<string name="tunnel_rename_success">Successfully renamed tunnel to “%s”</string>
<string name="tunnel_error_invalid_name">Invalid name</string>
<string name="tunnel_error_already_exists">Tunnel %s already exists</string>
<string name="tunnel_error_empty_inetaddress">Empty address</string>
<string name="tunnel_error_empty_interface_address">Address is empty</string>
<string name="tunnel_error_interface_parse_failed">Unable to parse line: “%s”</string>
<string name="tunnel_error_forbidden_endpoint_chars">Forbidden characters in endpoint</string>
<string name="tunnel_error_empty_peer_public_key">Peer public key may not be empty</string>
<string name="tunnel_error_invalid_config_line">Invalid configuration line: %s</string>
<string name="tunnel_error_no_config_information">Could not find any config information</string>
<string name="key_length_base64_exception_message">WireGuard base64 keys must be 44 characters encoding 32 bytes</string>
<string name="key_length_exception_message">WireGuard keys must be 32 bytes</string>
<string name="key_length_hex_exception_message">WireGuard hex keys must be 64 characters encoding 32 bytes</string>
<string name="version_title">WireGuard for Android v%s"</string>
<string name="version_summary">%s backend v%s</string>
<string name="version_summary">%1$s backend v%2$s</string>
<string name="version_summary_checking">Checking %s backend version</string>
<string name="version_summary_unknown">Unknown %s version</string>
<string name="zip_exporter_title">Export tunnels to zip file</string>
+2 -1
View File
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
# Copyright © 2018 WireGuard LLC. All Rights Reserved.
cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}")
@@ -25,6 +25,7 @@ add_custom_target(libwg-go.so WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/lib
CFLAGS=${CMAKE_C_FLAGS}\ -Wno-unused-command-line-argument
LDFLAGS=${CMAKE_SHARED_LINKER_FLAGS}\ -fuse-ld=gold
DESTDIR=${CMAKE_LIBRARY_OUTPUT_DIRECTORY}
BUILDDIR=${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/../generated-src
)
# Hack to make it actually build as part of the default target
add_dependencies(libwg.so libwg-go.so)
+1 -1
View File
@@ -1,2 +1,2 @@
src/
build/
.gobuildversion
+26 -19
View File
@@ -1,8 +1,12 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
# Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
FILES := $(filter-out %/main.go,$(wildcard ../wireguard-go/*/*.go) $(wildcard ../wireguard-go/*.go))
UPSTREAM_FILES := $(filter-out %/main.go %/queueconstants.go,$(wildcard ../wireguard-go/*/*.go) $(wildcard ../wireguard-go/*.go)) ../wireguard-go/go.mod ../wireguard-go/go.sum
DOWNSTREAM_FILES := $(wildcard src/*.go) $(wildcard src/*/*.go)
BUILDDIR ?= $(CURDIR)/build
DESTDIR ?= $(CURDIR)/out
NDK_GO_ARCH_MAP_x86 := 386
NDK_GO_ARCH_MAP_x86_64 := amd64
@@ -23,15 +27,11 @@ default: $(DESTDIR)/libwg-go.so
GOBUILDARCH := $(NDK_GO_ARCH_MAP_$(shell uname -m))
GOBUILDOS := $(shell uname -s | tr '[:upper:]' '[:lower:]')
GOBUILDVERSION := 1.10.2
GOBUILDVERSION := 1.11.1
GOBUILDTARBALL := https://dl.google.com/go/go$(GOBUILDVERSION).$(GOBUILDOS)-$(GOBUILDARCH).tar.gz
GOBUILDVERSION_NEEDED := go version go$(GOBUILDVERSION) $(GOBUILDOS)/$(GOBUILDARCH)
GOBUILDVERSION_CURRENT := $(shell go version 2>/dev/null)
ifeq ($(GOBUILDVERSION_NEEDED),$(GOBUILDVERSION_CURRENT))
$(info Using system Go)
else
export GOROOT := $(CURDIR)/goroot
export GOROOT := $(BUILDDIR)/goroot
export GOPATH := $(BUILDDIR)/gopath
export PATH := $(GOROOT)/bin:$(PATH)
GOBUILDVERSION_CURRENT := $(shell $(GOROOT)/bin/go version 2>/dev/null)
ifneq ($(GOBUILDVERSION_NEEDED),$(GOBUILDVERSION_CURRENT))
@@ -42,17 +42,24 @@ $(GOROOT)/bin/go:
mkdir -p "$(GOROOT)"
curl "$(GOBUILDTARBALL)" | tar -C "$(GOROOT)" --strip-components=1 -xzf - || { rm -rf "$(GOROOT)"; exit 1; }
patch -p1 -f -N -r- -d "$(GOROOT)" < goruntime-boottime-over-monotonic.diff || { rm -rf "$(GOROOT)"; exit 1; }
$(DESTDIR)/libwg-go.so: $(GOROOT)/bin/go
endif
$(shell test "$$(cat .gobuildversion 2>/dev/null)" = "$(GOBUILDVERSION_CURRENT)" || rm -f "$(DESTDIR)/libwg-go.so")
$(DESTDIR)/libwg-go.so: $(FILES) src/git.zx2c4.com/wireguard-go/api-android.go src/git.zx2c4.com/wireguard-go/tun/api-android.go src/git.zx2c4.com/wireguard-go/jni.c
@goroot="$$(go env GOROOT)" || exit 1; patch -p1 -f -R -s --dry-run -d "$$goroot" < goruntime-boottime-over-monotonic.diff >/dev/null 2>&1 || { echo "ERROR: Your system's Go is not patched to use the suspend-aware monotonic clock. Please try again after having run: \`patch -p1 -d \"$$goroot\" < \"$(CURDIR)/goruntime-boottime-over-monotonic.diff\"\`."; exit 1; }
find . -name '*.go' -type l -delete
find . -type d -empty -delete
mkdir -p $(subst ../wireguard-go/,./src/git.zx2c4.com/wireguard-go/,$(dir $(FILES)))
$(foreach FILE,$(FILES),ln -sfrt $(subst ../wireguard-go/,./src/git.zx2c4.com/wireguard-go/,$(dir $(FILE))) $(FILE);)
GOPATH=$(PWD) go get -v -d git.zx2c4.com/wireguard-go
GOPATH=$(PWD) go build -ldflags="-X main.socketDirectory=/data/data/$(ANDROID_PACKAGE_NAME)/cache/wireguard" -v -o $(DESTDIR)/libwg-go.so -buildmode c-shared git.zx2c4.com/wireguard-go
define copy-src-to-build
$(subst $(1),$(BUILDDIR)/,$(2)): $(2)
@mkdir -vp "$$(dir $$@)"
@cp -vp "$$<" "$$@"
$(BUILDDIR)/.prepared: $(subst $(1),$(BUILDDIR)/,$(2))
endef
$(foreach FILE,$(UPSTREAM_FILES),$(eval $(call copy-src-to-build,../wireguard-go/,$(FILE))))
$(foreach FILE,$(DOWNSTREAM_FILES),$(eval $(call copy-src-to-build,src/,$(FILE))))
$(BUILDDIR)/.prepared: $(GOROOT)/bin/go
cd "$(BUILDDIR)" && go get || { chmod -fR +w "$(GOPATH)/pkg/mod"; rm -rf "$(GOPATH)/pkg/mod"; exit 1; }
chmod -fR +w "$(GOPATH)/pkg/mod"
touch "$@"
$(DESTDIR)/libwg-go.so: $(BUILDDIR)/.prepared
cd "$(BUILDDIR)" && go build -ldflags="-X main.socketDirectory=/data/data/$(ANDROID_PACKAGE_NAME)/cache/wireguard" -v -o "$@" -buildmode c-shared
go version > .gobuildversion
@@ -1,7 +1,28 @@
diff -ru b/src/runtime/sys_linux_386.s a/src/runtime/sys_linux_386.s
--- b/src/runtime/sys_linux_386.s 2018-04-30 22:26:39.000000000 +0200
+++ a/src/runtime/sys_linux_386.s 2018-05-09 17:09:42.319531743 +0200
@@ -287,13 +287,13 @@
From 6f345a38d9533db388009d91d29981673dcf95b4 Mon Sep 17 00:00:00 2001
From: Jason A. Donenfeld <Jason@zx2c4.com>
Date: Fri, 04 May 2018 03:48:23 +0200
Subject: [PATCH] runtime: use CLOCK_BOOTTIME in nanotime on Linux
This makes timers account for having expired while a computer was
asleep, which is quite common on mobile devices. Note that BOOTTIME is
identical to MONOTONIC, except that it takes into account time spent
in suspend. In Linux 4.17, the kernel will actually make MONOTONIC act
like BOOTTIME anyway, so this switch will additionally unify the
timer behavior across kernels.
BOOTTIME was introduced into Linux 2.6.39-rc1 with 70a08cca1227d in
2011.
Fixes #24595
Change-Id: I7b2a6ca0c5bc5fce57ec0eeafe7b68270b429321
---
diff --git a/src/runtime/sys_linux_386.s b/src/runtime/sys_linux_386.s
index 8d5a4ff..bfad064 100644
--- a/src/runtime/sys_linux_386.s
+++ b/src/runtime/sys_linux_386.s
@@ -285,13 +285,13 @@
LEAL 8(SP), BX // &ts (struct timespec)
MOVL BX, 4(SP)
@@ -17,11 +38,12 @@ diff -ru b/src/runtime/sys_linux_386.s a/src/runtime/sys_linux_386.s
LEAL 8(SP), CX
INVOKE_SYSCALL
diff -ru b/src/runtime/sys_linux_amd64.s a/src/runtime/sys_linux_amd64.s
--- b/src/runtime/sys_linux_amd64.s 2018-04-30 22:26:39.000000000 +0200
+++ a/src/runtime/sys_linux_amd64.s 2018-05-09 17:09:42.319531743 +0200
@@ -258,7 +258,7 @@
MOVQ runtime·__vdso_clock_gettime_sym(SB), AX
diff --git a/src/runtime/sys_linux_amd64.s b/src/runtime/sys_linux_amd64.s
index 62d8024..8510be4 100644
--- a/src/runtime/sys_linux_amd64.s
+++ b/src/runtime/sys_linux_amd64.s
@@ -257,7 +257,7 @@
MOVQ runtime·vdsoClockgettimeSym(SB), AX
CMPQ AX, $0
JEQ fallback
- MOVL $1, DI // CLOCK_MONOTONIC
@@ -29,34 +51,55 @@ diff -ru b/src/runtime/sys_linux_amd64.s a/src/runtime/sys_linux_amd64.s
LEAQ 0(SP), SI
CALL AX
MOVQ 0(SP), AX // sec
diff -ru b/src/runtime/sys_linux_arm64.s a/src/runtime/sys_linux_arm64.s
--- b/src/runtime/sys_linux_arm64.s 2018-04-30 22:26:39.000000000 +0200
+++ a/src/runtime/sys_linux_arm64.s 2018-05-09 17:12:47.844591628 +0200
@@ -201,7 +201,7 @@
RET
diff --git a/src/runtime/sys_linux_arm.s b/src/runtime/sys_linux_arm.s
index aa39732..d29cb88 100644
--- a/src/runtime/sys_linux_arm.s
+++ b/src/runtime/sys_linux_arm.s
@@ -11,7 +11,7 @@
#include "textflag.h"
TEXT runtime·nanotime(SB),NOSPLIT,$24-8
- MOVW $1, R0 // CLOCK_MONOTONIC
+ MOVW $7, R0 // CLOCK_BOOTTIME
MOVD RSP, R1
MOVD $SYS_clock_gettime, R8
SVC
diff -ru b/src/runtime/sys_linux_arm.s a/src/runtime/sys_linux_arm.s
--- b/src/runtime/sys_linux_arm.s 2018-04-30 22:26:39.000000000 +0200
+++ a/src/runtime/sys_linux_arm.s 2018-05-09 17:13:18.983281049 +0200
@@ -235,7 +235,7 @@
#define CLOCK_REALTIME 0
-#define CLOCK_MONOTONIC 1
+#define CLOCK_BOOTTIME 7
// int64 nanotime(void)
TEXT runtime·nanotime(SB),NOSPLIT,$32
- MOVW $1, R0 // CLOCK_MONOTONIC
+ MOVW $7, R0 // CLOCK_BOOTTIME
MOVW $8(R13), R1 // timespec
MOVW $SYS_clock_gettime, R7
SWI $0
diff -ru b/src/runtime/sys_linux_mips64x.s a/src/runtime/sys_linux_mips64x.s
--- b/src/runtime/sys_linux_mips64x.s 2018-04-30 22:26:39.000000000 +0200
+++ a/src/runtime/sys_linux_mips64x.s 2018-05-09 17:09:42.321531721 +0200
@@ -197,7 +197,7 @@
// for EABI, as we don't support OABI
#define SYS_BASE 0x0
@@ -287,7 +287,7 @@
SUB $24, R13 // Space for results
BIC $0x7, R13 // Align for C code
- MOVW $CLOCK_MONOTONIC, R0
+ MOVW $CLOCK_BOOTTIME, R0
MOVW $8(R13), R1 // timespec
MOVW runtime·vdsoClockgettimeSym(SB), R11
CMP $0, R11
diff --git a/src/runtime/sys_linux_arm64.s b/src/runtime/sys_linux_arm64.s
index c6afd76..24294e8 100644
--- a/src/runtime/sys_linux_arm64.s
+++ b/src/runtime/sys_linux_arm64.s
@@ -13,7 +13,7 @@
#define AT_FDCWD -100
#define CLOCK_REALTIME 0
-#define CLOCK_MONOTONIC 1
+#define CLOCK_BOOTTIME 7
#define SYS_exit 93
#define SYS_read 63
@@ -243,7 +243,7 @@
BIC $15, R1
MOVD R1, RSP
- MOVW $CLOCK_MONOTONIC, R0
+ MOVW $CLOCK_BOOTTIME, R0
MOVD runtime·vdsoClockgettimeSym(SB), R2
CBZ R2, fallback
BL (R2)
diff --git a/src/runtime/sys_linux_mips64x.s b/src/runtime/sys_linux_mips64x.s
index 8e64f1c..521062f 100644
--- a/src/runtime/sys_linux_mips64x.s
+++ b/src/runtime/sys_linux_mips64x.s
@@ -185,7 +185,7 @@
RET
TEXT runtime·nanotime(SB),NOSPLIT,$16
@@ -65,10 +108,11 @@ diff -ru b/src/runtime/sys_linux_mips64x.s a/src/runtime/sys_linux_mips64x.s
MOVV $0(R29), R5
MOVV $SYS_clock_gettime, R2
SYSCALL
diff -ru b/src/runtime/sys_linux_mipsx.s a/src/runtime/sys_linux_mipsx.s
--- b/src/runtime/sys_linux_mipsx.s 2018-04-30 22:26:39.000000000 +0200
+++ a/src/runtime/sys_linux_mipsx.s 2018-05-09 17:09:42.321531721 +0200
@@ -202,7 +202,7 @@
diff --git a/src/runtime/sys_linux_mipsx.s b/src/runtime/sys_linux_mipsx.s
index a6bca3b..920ed9a 100644
--- a/src/runtime/sys_linux_mipsx.s
+++ b/src/runtime/sys_linux_mipsx.s
@@ -189,7 +189,7 @@
RET
TEXT runtime·nanotime(SB),NOSPLIT,$8-8
@@ -77,10 +121,11 @@ diff -ru b/src/runtime/sys_linux_mipsx.s a/src/runtime/sys_linux_mipsx.s
MOVW $4(R29), R5
MOVW $SYS_clock_gettime, R2
SYSCALL
diff -ru b/src/runtime/sys_linux_ppc64x.s a/src/runtime/sys_linux_ppc64x.s
--- b/src/runtime/sys_linux_ppc64x.s 2018-04-30 22:26:39.000000000 +0200
+++ a/src/runtime/sys_linux_ppc64x.s 2018-05-09 17:09:42.322531710 +0200
@@ -176,7 +176,7 @@
diff --git a/src/runtime/sys_linux_ppc64x.s b/src/runtime/sys_linux_ppc64x.s
index 483cb8e..11f3c49 100644
--- a/src/runtime/sys_linux_ppc64x.s
+++ b/src/runtime/sys_linux_ppc64x.s
@@ -164,7 +164,7 @@
RET
TEXT runtime·nanotime(SB),NOSPLIT,$16
@@ -89,10 +134,11 @@ diff -ru b/src/runtime/sys_linux_ppc64x.s a/src/runtime/sys_linux_ppc64x.s
MOVD $0(R1), R4
SYSCALL $SYS_clock_gettime
MOVD 0(R1), R3 // sec
diff -ru b/src/runtime/sys_linux_s390x.s a/src/runtime/sys_linux_s390x.s
--- b/src/runtime/sys_linux_s390x.s 2018-04-30 22:26:39.000000000 +0200
+++ a/src/runtime/sys_linux_s390x.s 2018-05-09 17:09:42.322531710 +0200
@@ -188,7 +188,7 @@
diff --git a/src/runtime/sys_linux_s390x.s b/src/runtime/sys_linux_s390x.s
index 1ff110c..e9049e0 100644
--- a/src/runtime/sys_linux_s390x.s
+++ b/src/runtime/sys_linux_s390x.s
@@ -176,7 +176,7 @@
RET
TEXT runtime·nanotime(SB),NOSPLIT,$16
@@ -91,28 +91,28 @@ func wgTurnOn(ifnameRef string, tun_fd int32, settings string) int32 {
return -1
}
var uapi net.Listener;
uapiFile, err := UAPIOpen(name)
if err != nil {
unix.Close(int(tun_fd))
logger.Error.Println(err)
return -1
}
uapi, err := UAPIListen(name, uapiFile)
if err != nil {
uapiFile.Close()
unix.Close(int(tun_fd))
logger.Error.Println(err)
return -1
}
go func() {
for {
conn, err := uapi.Accept()
if err != nil {
return
}
go ipcHandle(device, conn)
} else {
uapi, err = UAPIListen(name, uapiFile)
if err != nil {
uapiFile.Close()
logger.Error.Println(err)
} else {
go func() {
for {
conn, err := uapi.Accept()
if err != nil {
return
}
go ipcHandle(device, conn)
}
}()
}
}()
}
device.Up()
logger.Info.Println("Device started")
@@ -138,7 +138,9 @@ func wgTurnOff(tunnelHandle int32) {
return
}
delete(tunnelHandles, tunnelHandle)
handle.uapi.Close()
if handle.uapi != nil {
handle.uapi.Close()
}
handle.device.Close()
}
+16
View File
@@ -0,0 +1,16 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package main
/* Reduce memory consumption for Android */
const (
QueueOutboundSize = 1024
QueueInboundSize = 1024
QueueHandshakeSize = 1024
MaxSegmentSize = 2200
PreallocatedBuffersPerPool = 4096
)
@@ -11,11 +11,13 @@ import (
)
func CreateTUNFromFD(tun_fd int) (TUNDevice, string, error) {
file := os.NewFile(uintptr(tun_fd), "/dev/tun")
tun := &nativeTun{
fd: os.NewFile(uintptr(tun_fd), "/dev/tun"),
events: make(chan TUNEvent, 5),
errors: make(chan error, 5),
nopi: true,
tunFile: file,
fd: file.Fd(),
events: make(chan TUNEvent, 5),
errors: make(chan error, 5),
nopi: true,
}
var err error
tun.fdCancel, err = rwcancel.NewRWCancel(tun_fd)
+1 -1
View File
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: BSD
*
* Copyright (C) 2015-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
*
*/
+1 -1
View File
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: BSD
*
* Copyright (C) 2015-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright © 2017-2018 WireGuard LLC. All Rights Reserved.
*
*/
+1 -1
View File
@@ -7,7 +7,7 @@ allprojects {
buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:3.1.3'
classpath 'com.android.tools.build:gradle:3.2.0'
}
repositories {
google()
+2 -1
View File
@@ -1,5 +1,6 @@
#Mon Oct 01 15:59:48 CEST 2018
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip