summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorEric Kuck <eric@bluelinelabs.com>2018-07-12 19:10:35 -0500
committerJason A. Donenfeld <Jason@zx2c4.com>2018-07-13 03:46:23 +0200
commit67ea8b2936343526ff0b3f476c515f0e11dbb272 (patch)
tree84f904d66f6111a7d8f897164eb236bc62199cae
parentfbaa4d9ab1b59ba4610fe273743872f35e7e9091 (diff)
global: Add nullity annotations
Signed-off-by: Eric Kuck <eric@bluelinelabs.com>
-rw-r--r--.gitignore1
-rw-r--r--.idea/codeStyles/Project.xml2
-rw-r--r--app/build.gradle3
-rw-r--r--app/nonnull.gradle87
-rw-r--r--app/src/main/java/com/wireguard/android/Application.java34
-rw-r--r--app/src/main/java/com/wireguard/android/QuickTileService.java11
-rw-r--r--app/src/main/java/com/wireguard/android/activity/BaseActivity.java15
-rw-r--r--app/src/main/java/com/wireguard/android/activity/MainActivity.java39
-rw-r--r--app/src/main/java/com/wireguard/android/activity/SettingsActivity.java13
-rw-r--r--app/src/main/java/com/wireguard/android/activity/ThemeChangeAwareActivity.java5
-rw-r--r--app/src/main/java/com/wireguard/android/activity/TunnelCreatorActivity.java5
-rw-r--r--app/src/main/java/com/wireguard/android/backend/GoBackend.java10
-rw-r--r--app/src/main/java/com/wireguard/android/backend/WgQuickBackend.java7
-rw-r--r--app/src/main/java/com/wireguard/android/databinding/ItemChangeListener.java16
-rw-r--r--app/src/main/java/com/wireguard/android/databinding/ObservableKeyedRecyclerViewAdapter.java21
-rw-r--r--app/src/main/java/com/wireguard/android/fragment/AppListDialogFragment.java16
-rw-r--r--app/src/main/java/com/wireguard/android/fragment/BaseFragment.java15
-rw-r--r--app/src/main/java/com/wireguard/android/fragment/TunnelDetailFragment.java22
-rw-r--r--app/src/main/java/com/wireguard/android/fragment/TunnelEditorFragment.java38
-rw-r--r--app/src/main/java/com/wireguard/android/fragment/TunnelListFragment.java40
-rw-r--r--app/src/main/java/com/wireguard/android/model/ApplicationData.java12
-rw-r--r--app/src/main/java/com/wireguard/android/model/Tunnel.java29
-rw-r--r--app/src/main/java/com/wireguard/android/model/TunnelManager.java17
-rw-r--r--app/src/main/java/com/wireguard/android/preference/LogExporterPreference.java5
-rw-r--r--app/src/main/java/com/wireguard/android/preference/ToolsInstallerPreference.java8
-rw-r--r--app/src/main/java/com/wireguard/android/preference/VersionPreference.java5
-rw-r--r--app/src/main/java/com/wireguard/android/preference/ZipExporterPreference.java5
-rw-r--r--app/src/main/java/com/wireguard/android/util/ExceptionLoggers.java6
-rw-r--r--app/src/main/java/com/wireguard/android/util/ObservableKeyedArrayList.java16
-rw-r--r--app/src/main/java/com/wireguard/android/util/ObservableSortedKeyedArrayList.java10
-rw-r--r--app/src/main/java/com/wireguard/android/util/RootShell.java11
-rw-r--r--app/src/main/java/com/wireguard/android/util/SharedLibraryLoader.java3
-rw-r--r--app/src/main/java/com/wireguard/android/util/ToolsInstaller.java8
-rw-r--r--app/src/main/java/com/wireguard/android/widget/KeyInputFilter.java3
-rw-r--r--app/src/main/java/com/wireguard/android/widget/NameInputFilter.java3
-rw-r--r--app/src/main/java/com/wireguard/android/widget/SlashDrawable.java29
-rw-r--r--app/src/main/java/com/wireguard/android/widget/ToggleSwitch.java13
-rw-r--r--app/src/main/java/com/wireguard/android/widget/fab/FloatingActionsMenu.java18
-rw-r--r--app/src/main/java/com/wireguard/android/widget/fab/LabeledFloatingActionButton.java9
-rw-r--r--app/src/main/java/com/wireguard/android/widget/fab/TouchDelegateGroup.java8
-rw-r--r--app/src/main/java/com/wireguard/config/Attribute.java7
-rw-r--r--app/src/main/java/com/wireguard/config/Config.java26
-rw-r--r--app/src/main/java/com/wireguard/config/InetAddresses.java2
-rw-r--r--app/src/main/java/com/wireguard/config/InetNetwork.java5
-rw-r--r--app/src/main/java/com/wireguard/config/Interface.java53
-rw-r--r--app/src/main/java/com/wireguard/config/Peer.java51
-rw-r--r--app/src/main/java/com/wireguard/crypto/Curve25519.java4
-rw-r--r--app/src/main/java/com/wireguard/util/NonNullForAll.java25
48 files changed, 481 insertions, 310 deletions
diff --git a/.gitignore b/.gitignore
index 3dde301c..d85bf2d3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,3 +15,4 @@ build/
*.iml
*.jks
keystore.properties
+package-info.java
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
index 56aadf89..b9a1bf45 100644
--- a/.idea/codeStyles/Project.xml
+++ b/.idea/codeStyles/Project.xml
@@ -94,6 +94,8 @@
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
</XML>
<codeStyleSettings language="JAVA">
+ <option name="METHOD_ANNOTATION_WRAP" value="0" />
+ <option name="FIELD_ANNOTATION_WRAP" value="0" />
<arrangement>
<groups />
<rules>
diff --git a/app/build.gradle b/app/build.gradle
index b0bcc3b6..f63726d3 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -1,4 +1,5 @@
apply plugin: 'com.android.application'
+apply from: 'nonnull.gradle'
// Create a variable called keystorePropertiesFile, and initialize it to your
// keystore.properties file, in the rootProject folder.
@@ -56,6 +57,7 @@ ext {
databindingVersion = '3.1.3'
supportLibsVersion = '27.1.1'
streamsupportVersion = '1.6.0'
+ jsr305Version = '3.0.2'
}
dependencies {
@@ -67,6 +69,7 @@ dependencies {
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"
}
tasks.withType(JavaCompile) {
diff --git a/app/nonnull.gradle b/app/nonnull.gradle
new file mode 100644
index 00000000..014e999a
--- /dev/null
+++ b/app/nonnull.gradle
@@ -0,0 +1,87 @@
+/*
+ * Copyright © 2018 Eric Kuck <eric@bluelinelabs.com>.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+task generateNonNullJavaFiles(dependsOn: "assembleDebug", type: Copy) {
+ group = "Copying"
+ description = "Generate package-info.java classes"
+
+ def basePackage = "com" + File.separatorChar + "wireguard"
+ def mainSrcPhrase = "src" + File.separatorChar + "main" + File.separatorChar +
+ "java" + File.separatorChar
+ def mainTestSrcPhrase = "src" + File.separatorChar + "test" + File.separatorChar +
+ "java" + File.separatorChar
+ def mainAndroidTestSrcPhrase = "src" + File.separatorChar + "androidTest" + File.separatorChar +
+ "java" + File.separatorChar
+
+ def sourceDir = file( "${projectDir}" + File.separatorChar + "src" + File.separatorChar +
+ "main" + File.separatorChar + "java" + File.separatorChar +
+ basePackage )
+ def testSourceDir = file( "${projectDir}" + File.separatorChar + "src" + File.separatorChar +
+ "test" + File.separatorChar + "java" + File.separatorChar +
+ basePackage)
+ def androidTestSourceDir = file( "${projectDir}" + File.separatorChar + "src" + File
+ .separatorChar +
+ "androidTest" + File.separatorChar + "java" + File.separatorChar +
+ basePackage )
+
+ generateInfoFiles(sourceDir, mainSrcPhrase);
+ sourceDir.eachDirRecurse { dir ->
+ generateInfoFiles(dir, mainSrcPhrase)
+ }
+ if (file(testSourceDir).exists()) {
+ generateInfoFiles(testSourceDir, mainTestSrcPhrase);
+ testSourceDir.eachDirRecurse { dir ->
+ generateInfoFiles(dir, mainTestSrcPhrase)
+ }
+ }
+ if (file(androidTestSourceDir).exists()) {
+ generateInfoFiles(androidTestSourceDir, mainAndroidTestSrcPhrase);
+ androidTestSourceDir.eachDirRecurse { dir ->
+ generateInfoFiles(dir, mainAndroidTestSrcPhrase)
+ }
+ }
+ println "[SUCCESS] NonNull generator: package-info.java files checked"
+}
+
+private void generateInfoFiles(File dir, String mainSrcPhrase) {
+ def infoFileContentHeader = getFileContentHeader();
+ def infoFileContentFooter = getFileContentFooter();
+ def infoFilePath = dir.getAbsolutePath() + File.separatorChar + "package-info.java"
+
+ //file(infoFilePath).delete(); //do not use in production code
+ if (!file(infoFilePath).exists()) {
+ def infoFileContentPackage = getFileContentPackage(dir.getAbsolutePath(), mainSrcPhrase);
+ new File(infoFilePath).write(infoFileContentHeader +
+ infoFileContentPackage + infoFileContentFooter)
+ println "[dir] " + infoFilePath + " created";
+ }
+}
+
+def getFileContentPackage(String path, String mainSrcPhrase) {
+ def mainSrcPhraseIndex = path.indexOf(mainSrcPhrase)
+ def output = path.substring(mainSrcPhraseIndex)
+
+ // Win hotfix
+ if (System.properties['os.name'].toLowerCase().contains('windows')) {
+ output = output.replace("\\", "/")
+ mainSrcPhrase = mainSrcPhrase.replace("\\", "/")
+ }
+
+ return "package " + output.replaceAll(mainSrcPhrase, "").replaceAll(
+ "/", ".") + ";\n"
+}
+
+def getFileContentHeader() {
+ return "/**\n" +
+ " * Make all method parameters @NonNull by default.\n" +
+ " */\n" +
+ "@NonNullForAll\n"
+}
+
+def getFileContentFooter() {
+ return "\n" +
+ "import com.wireguard.util.NonNullForAll;\n"
+}
+
diff --git a/app/src/main/java/com/wireguard/android/Application.java b/app/src/main/java/com/wireguard/android/Application.java
index f3045831..f4a4290e 100644
--- a/app/src/main/java/com/wireguard/android/Application.java
+++ b/app/src/main/java/com/wireguard/android/Application.java
@@ -10,6 +10,7 @@ import android.os.AsyncTask;
import android.os.Handler;
import android.os.Looper;
import android.preference.PreferenceManager;
+import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatDelegate;
import com.wireguard.android.backend.Backend;
@@ -26,18 +27,19 @@ import java.io.File;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Objects;
import java.util.concurrent.Executor;
public class Application extends android.app.Application {
- private static WeakReference<Application> weakSelf;
- private AsyncWorker asyncWorker;
- private Backend backend;
- private RootShell rootShell;
- private SharedPreferences sharedPreferences;
- private ToolsInstaller toolsInstaller;
- private TunnelManager tunnelManager;
- private Handler handler;
- private Collection<BackendCallback> haveBackendCallbacks = new ArrayList<>();
+ @SuppressWarnings("NullableProblems") private static WeakReference<Application> weakSelf;
+ @SuppressWarnings("NullableProblems") private AsyncWorker asyncWorker;
+ @SuppressWarnings("NullableProblems") private RootShell rootShell;
+ @SuppressWarnings("NullableProblems") private SharedPreferences sharedPreferences;
+ @SuppressWarnings("NullableProblems") private ToolsInstaller toolsInstaller;
+ @SuppressWarnings("NullableProblems") private TunnelManager tunnelManager;
+ @SuppressWarnings("NullableProblems") private Handler handler;
+ @Nullable private Backend backend;
+ @Nullable private Collection<BackendCallback> haveBackendCallbacks = new ArrayList<>();
private final Object haveBackendCallbacksLock = new Object();
public Application() {
@@ -65,9 +67,11 @@ public class Application extends android.app.Application {
if (app.backend == null)
app.backend = new GoBackend(app.getApplicationContext());
synchronized (app.haveBackendCallbacksLock) {
- for (final BackendCallback callback : app.haveBackendCallbacks)
- app.handler.post(() -> callback.callback(app.backend));
- app.haveBackendCallbacks = null;
+ if (app.haveBackendCallbacks != null) {
+ for (final BackendCallback callback : app.haveBackendCallbacks)
+ app.handler.post(() -> callback.callback(app.backend));
+ app.haveBackendCallbacks = null;
+ }
}
}
return app.backend;
@@ -82,10 +86,12 @@ public class Application extends android.app.Application {
public static void onHaveBackend(final BackendCallback callback) {
final Application app = get();
synchronized (app.haveBackendCallbacksLock) {
- if (app.haveBackendCallbacks == null)
+ if (app.haveBackendCallbacks == null) {
+ Objects.requireNonNull(app.backend, "Backend still null in onHaveBackend call");
callback.callback(app.backend);
- else
+ } else {
app.haveBackendCallbacks.add(callback);
+ }
}
}
diff --git a/app/src/main/java/com/wireguard/android/QuickTileService.java b/app/src/main/java/com/wireguard/android/QuickTileService.java
index 77f01502..008fdee8 100644
--- a/app/src/main/java/com/wireguard/android/QuickTileService.java
+++ b/app/src/main/java/com/wireguard/android/QuickTileService.java
@@ -12,12 +12,11 @@ import android.databinding.Observable;
import android.databinding.Observable.OnPropertyChangedCallback;
import android.graphics.Bitmap;
import android.graphics.Canvas;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.os.Build;
import android.service.quicksettings.Tile;
import android.service.quicksettings.TileService;
+import android.support.annotation.Nullable;
import android.util.Log;
import android.widget.Toast;
@@ -41,9 +40,9 @@ public class QuickTileService extends TileService {
private final OnStateChangedCallback onStateChangedCallback = new OnStateChangedCallback();
private final OnTunnelChangedCallback onTunnelChangedCallback = new OnTunnelChangedCallback();
- private Tunnel tunnel;
- private Icon iconOn;
- private Icon iconOff;
+ @Nullable private Tunnel tunnel;
+ @Nullable private Icon iconOn;
+ @Nullable private Icon iconOff;
@SuppressWarnings("deprecation")
@Override
@@ -91,7 +90,7 @@ public class QuickTileService extends TileService {
}
private void onToggleFinished(@SuppressWarnings("unused") final State state,
- final Throwable throwable) {
+ @Nullable final Throwable throwable) {
if (throwable == null)
return;
final String error = ExceptionLoggers.unwrapMessage(throwable);
diff --git a/app/src/main/java/com/wireguard/android/activity/BaseActivity.java b/app/src/main/java/com/wireguard/android/activity/BaseActivity.java
index 9b535d79..51357d89 100644
--- a/app/src/main/java/com/wireguard/android/activity/BaseActivity.java
+++ b/app/src/main/java/com/wireguard/android/activity/BaseActivity.java
@@ -9,6 +9,7 @@ package com.wireguard.android.activity;
import android.databinding.CallbackRegistry;
import android.databinding.CallbackRegistry.NotifierCallback;
import android.os.Bundle;
+import android.support.annotation.Nullable;
import com.wireguard.android.Application;
import com.wireguard.android.model.Tunnel;
@@ -24,19 +25,19 @@ public abstract class BaseActivity extends ThemeChangeAwareActivity {
private static final String KEY_SELECTED_TUNNEL = "selected_tunnel";
private final SelectionChangeRegistry selectionChangeRegistry = new SelectionChangeRegistry();
- private Tunnel selectedTunnel;
+ @Nullable private Tunnel selectedTunnel;
- public void addOnSelectedTunnelChangedListener(
- final OnSelectedTunnelChangedListener listener) {
+ public void addOnSelectedTunnelChangedListener(final OnSelectedTunnelChangedListener listener) {
selectionChangeRegistry.add(listener);
}
+ @Nullable
public Tunnel getSelectedTunnel() {
return selectedTunnel;
}
@Override
- protected void onCreate(final Bundle savedInstanceState) {
+ protected void onCreate(@Nullable final Bundle savedInstanceState) {
// Restore the saved tunnel if there is one; otherwise grab it from the arguments.
String savedTunnelName = null;
if (savedInstanceState != null)
@@ -59,14 +60,14 @@ public abstract class BaseActivity extends ThemeChangeAwareActivity {
super.onSaveInstanceState(outState);
}
- protected abstract void onSelectedTunnelChanged(Tunnel oldTunnel, Tunnel newTunnel);
+ protected abstract void onSelectedTunnelChanged(@Nullable Tunnel oldTunnel, @Nullable Tunnel newTunnel);
public void removeOnSelectedTunnelChangedListener(
final OnSelectedTunnelChangedListener listener) {
selectionChangeRegistry.remove(listener);
}
- public void setSelectedTunnel(final Tunnel tunnel) {
+ public void setSelectedTunnel(@Nullable final Tunnel tunnel) {
final Tunnel oldTunnel = selectedTunnel;
if (Objects.equals(oldTunnel, tunnel))
return;
@@ -76,7 +77,7 @@ public abstract class BaseActivity extends ThemeChangeAwareActivity {
}
public interface OnSelectedTunnelChangedListener {
- void onSelectedTunnelChanged(Tunnel oldTunnel, Tunnel newTunnel);
+ void onSelectedTunnelChanged(@Nullable Tunnel oldTunnel, @Nullable Tunnel newTunnel);
}
private static final class SelectionChangeNotifier
diff --git a/app/src/main/java/com/wireguard/android/activity/MainActivity.java b/app/src/main/java/com/wireguard/android/activity/MainActivity.java
index e7f438f2..5a8134f3 100644
--- a/app/src/main/java/com/wireguard/android/activity/MainActivity.java
+++ b/app/src/main/java/com/wireguard/android/activity/MainActivity.java
@@ -9,6 +9,7 @@ package com.wireguard.android.activity;
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;
@@ -22,6 +23,8 @@ 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;
/**
@@ -33,6 +36,7 @@ import java9.util.stream.Stream;
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) {
@@ -70,13 +74,19 @@ public class MainActivity extends BaseActivity {
@Override
public void onBackPressed() {
- TunnelListFragment fragment = null;
- try {
- fragment = ((TunnelListFragment) getSupportFragmentManager().getFragments().get(0));
- } catch (final ClassCastException ignored) { }
- if (fragment == null || !fragment.collapseActionMenu()) {
- if (!moveToState(State.ofLayer(state.layer - 1)))
- super.onBackPressed();
+ final List<Fragment> fragments = getSupportFragmentManager().getFragments();
+
+ boolean handled = false;
+ if (!fragments.isEmpty() && fragments.get(0) instanceof TunnelListFragment) {
+ handled = ((TunnelListFragment) fragments.get(0)).collapseActionMenu();
+ }
+
+ if (!handled) {
+ handled = moveToState(State.ofLayer(state.layer - 1));
+ }
+
+ if (!handled) {
+ super.onBackPressed();
}
}
@@ -84,7 +94,7 @@ public class MainActivity extends BaseActivity {
// calling View#performClick defeats the purpose of it.
@SuppressLint("ClickableViewAccessibility")
@Override
- protected void onCreate(final Bundle savedInstanceState) {
+ protected void onCreate(@Nullable final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
if (savedInstanceState != null && savedInstanceState.getString(KEY_STATE) != null)
@@ -99,9 +109,10 @@ public class MainActivity extends BaseActivity {
final int actionBarId = getResources().getIdentifier("action_bar", "id", getPackageName());
if (actionBarId != 0 && findViewById(actionBarId) != null) {
findViewById(actionBarId).setOnTouchListener((v, e) -> {
- try {
- ((TunnelListFragment) getSupportFragmentManager().getFragments().get(0)).collapseActionMenu();
- } catch (final ClassCastException ignored) { }
+ final List<Fragment> fragments = getSupportFragmentManager().getFragments();
+ if (!fragments.isEmpty() && fragments.get(0) instanceof TunnelListFragment) {
+ ((TunnelListFragment) fragments.get(0)).collapseActionMenu();
+ }
return false;
});
}
@@ -142,7 +153,7 @@ public class MainActivity extends BaseActivity {
}
@Override
- protected void onSelectedTunnelChanged(final Tunnel oldTunnel, final Tunnel newTunnel) {
+ protected void onSelectedTunnelChanged(@Nullable final Tunnel oldTunnel, @Nullable final Tunnel newTunnel) {
moveToState(newTunnel != null ? State.DETAIL : State.LIST);
}
@@ -157,10 +168,10 @@ public class MainActivity extends BaseActivity {
DETAIL(TunnelDetailFragment.class, 2),
EDITOR(TunnelEditorFragment.class, 3);
- private final String fragment;
+ @Nullable private final String fragment;
private final int layer;
- State(final Class<? extends Fragment> fragment, final int layer) {
+ State(@Nullable final Class<? extends Fragment> fragment, final int layer) {
this.fragment = fragment != null ? fragment.getName() : null;
this.layer = layer;
}
diff --git a/app/src/main/java/com/wireguard/android/activity/SettingsActivity.java b/app/src/main/java/com/wireguard/android/activity/SettingsActivity.java
index ed2da4dc..066d377f 100644
--- a/app/src/main/java/com/wireguard/android/activity/SettingsActivity.java
+++ b/app/src/main/java/com/wireguard/android/activity/SettingsActivity.java
@@ -8,12 +8,13 @@ package com.wireguard.android.activity;
import android.content.pm.PackageManager;
import android.os.Bundle;
-import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceFragmentCompat;
import android.support.v7.preference.PreferenceScreen;
+import android.util.SparseArray;
import android.view.MenuItem;
import com.wireguard.android.Application;
@@ -22,16 +23,14 @@ import com.wireguard.android.backend.WgQuickBackend;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
/**
* Interface for changing application-global persistent settings.
*/
public class SettingsActivity extends ThemeChangeAwareActivity {
- private final Map<Integer, PermissionRequestCallback> permissionRequestCallbacks = new HashMap<>();
+ private final SparseArray<PermissionRequestCallback> permissionRequestCallbacks = new SparseArray<>();
private int permissionRequestCounter;
public void ensurePermissions(final String[] permissions, final PermissionRequestCallback cb) {
@@ -54,7 +53,7 @@ public class SettingsActivity extends ThemeChangeAwareActivity {
}
@Override
- protected void onCreate(final Bundle savedInstanceState) {
+ protected void onCreate(@Nullable final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getSupportFragmentManager().findFragmentById(android.R.id.content) == null) {
getSupportFragmentManager().beginTransaction()
@@ -76,8 +75,8 @@ public class SettingsActivity extends ThemeChangeAwareActivity {
@Override
public void onRequestPermissionsResult(final int requestCode,
- @NonNull final String[] permissions,
- @NonNull final int[] grantResults) {
+ final String[] permissions,
+ final int[] grantResults) {
final PermissionRequestCallback f = permissionRequestCallbacks.get(requestCode);
if (f != null) {
permissionRequestCallbacks.remove(requestCode);
diff --git a/app/src/main/java/com/wireguard/android/activity/ThemeChangeAwareActivity.java b/app/src/main/java/com/wireguard/android/activity/ThemeChangeAwareActivity.java
index be61f256..d85a0170 100644
--- a/app/src/main/java/com/wireguard/android/activity/ThemeChangeAwareActivity.java
+++ b/app/src/main/java/com/wireguard/android/activity/ThemeChangeAwareActivity.java
@@ -8,6 +8,7 @@ package com.wireguard.android.activity;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.os.Bundle;
+import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.app.AppCompatDelegate;
import android.util.Log;
@@ -19,7 +20,7 @@ import java.lang.reflect.Field;
public abstract class ThemeChangeAwareActivity extends AppCompatActivity implements SharedPreferences.OnSharedPreferenceChangeListener {
private static final String TAG = "WireGuard/" + ThemeChangeAwareActivity.class.getSimpleName();
- private static Resources lastResources;
+ @Nullable private static Resources lastResources;
private static boolean lastDarkMode;
private static synchronized void invalidateDrawableCache(final Resources resources, final boolean darkMode) {
if (resources == lastResources && darkMode == lastDarkMode)
@@ -51,7 +52,7 @@ public abstract class ThemeChangeAwareActivity extends AppCompatActivity impleme
@Override
- protected void onCreate(final Bundle savedInstanceState) {
+ protected void onCreate(@Nullable final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Application.getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}
diff --git a/app/src/main/java/com/wireguard/android/activity/TunnelCreatorActivity.java b/app/src/main/java/com/wireguard/android/activity/TunnelCreatorActivity.java
index 044548ce..99bb4141 100644
--- a/app/src/main/java/com/wireguard/android/activity/TunnelCreatorActivity.java
+++ b/app/src/main/java/com/wireguard/android/activity/TunnelCreatorActivity.java
@@ -7,6 +7,7 @@
package com.wireguard.android.activity;
import android.os.Bundle;
+import android.support.annotation.Nullable;
import com.wireguard.android.fragment.TunnelEditorFragment;
import com.wireguard.android.model.Tunnel;
@@ -18,7 +19,7 @@ import com.wireguard.android.model.Tunnel;
public class TunnelCreatorActivity extends BaseActivity {
@Override
@SuppressWarnings("UnnecessaryFullyQualifiedName")
- protected void onCreate(final Bundle savedInstanceState) {
+ protected void onCreate(@Nullable final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getSupportFragmentManager().findFragmentById(android.R.id.content) == null) {
getSupportFragmentManager().beginTransaction()
@@ -28,7 +29,7 @@ public class TunnelCreatorActivity extends BaseActivity {
}
@Override
- protected void onSelectedTunnelChanged(final Tunnel oldTunnel, final Tunnel newTunnel) {
+ protected void onSelectedTunnelChanged(@Nullable final Tunnel oldTunnel, @Nullable final Tunnel newTunnel) {
finish();
}
}
diff --git a/app/src/main/java/com/wireguard/android/backend/GoBackend.java b/app/src/main/java/com/wireguard/android/backend/GoBackend.java
index 66d3698f..a075913f 100644
--- a/app/src/main/java/com/wireguard/android/backend/GoBackend.java
+++ b/app/src/main/java/com/wireguard/android/backend/GoBackend.java
@@ -10,6 +10,7 @@ import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.ParcelFileDescriptor;
+import android.support.annotation.Nullable;
import android.support.v4.util.ArraySet;
import android.util.Log;
@@ -29,6 +30,7 @@ import com.wireguard.crypto.KeyEncoding;
import java.net.InetAddress;
import java.util.Collections;
import java.util.Formatter;
+import java.util.Objects;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
@@ -40,7 +42,7 @@ public final class GoBackend implements Backend {
private static CompletableFuture<VpnService> vpnService = new CompletableFuture<>();
private final Context context;
- private Tunnel currentTunnel;
+ @Nullable private Tunnel currentTunnel;
private int currentTunnelHandle = -1;
public GoBackend(final Context context) {
@@ -114,12 +116,14 @@ public final class GoBackend implements Backend {
return getState(tunnel);
}
- private void setStateInternal(final Tunnel tunnel, final Config config, final State state)
+ private void setStateInternal(final Tunnel tunnel, @Nullable final Config config, final State state)
throws Exception {
if (state == State.UP) {
Log.i(TAG, "Bringing tunnel up");
+ Objects.requireNonNull(config, "Trying to bring up a tunnel with no config");
+
if (VpnService.prepare(context) != null)
throw new Exception("VPN service not authorized by user");
@@ -245,7 +249,7 @@ public final class GoBackend implements Backend {
}
@Override
- public int onStartCommand(final Intent intent, final int flags, final int startId) {
+ public int onStartCommand(@Nullable final Intent intent, final int flags, final int startId) {
vpnService.complete(this);
if (intent == null || intent.getComponent() == null || !intent.getComponent().getPackageName().equals(getPackageName())) {
Log.d(TAG, "Service started by Always-on VPN feature");
diff --git a/app/src/main/java/com/wireguard/android/backend/WgQuickBackend.java b/app/src/main/java/com/wireguard/android/backend/WgQuickBackend.java
index fbc43dc0..25634841 100644
--- a/app/src/main/java/com/wireguard/android/backend/WgQuickBackend.java
+++ b/app/src/main/java/com/wireguard/android/backend/WgQuickBackend.java
@@ -7,6 +7,7 @@
package com.wireguard.android.backend;
import android.content.Context;
+import android.support.annotation.Nullable;
import android.util.Log;
import com.wireguard.android.Application;
@@ -21,6 +22,7 @@ import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Objects;
import java.util.Set;
import java9.util.stream.Collectors;
@@ -106,8 +108,9 @@ public final class WgQuickBackend implements Backend {
return getState(tunnel);
}
- private void setStateInternal(final Tunnel tunnel, final Config config, final State state)
- throws Exception {
+ private void setStateInternal(final Tunnel tunnel, @Nullable final Config config, final State state) throws Exception {
+ Objects.requireNonNull(config, "Trying to set state with a null config");
+
final File tempFile = new File(localTemporaryDir, tunnel.getName() + ".conf");
try (final FileOutputStream stream = new FileOutputStream(tempFile, false)) {
stream.write(config.toString().getBytes(StandardCharsets.UTF_8));
diff --git a/app/src/main/java/com/wireguard/android/databinding/ItemChangeListener.java b/app/src/main/java/com/wireguard/android/databinding/ItemChangeListener.java
index 0a87d491..909adddc 100644
--- a/app/src/main/java/com/wireguard/android/databinding/ItemChangeListener.java
+++ b/app/src/main/java/com/wireguard/android/databinding/ItemChangeListener.java
@@ -9,6 +9,7 @@ package com.wireguard.android.databinding;
import android.databinding.DataBindingUtil;
import android.databinding.ObservableList;
import android.databinding.ViewDataBinding;
+import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -16,6 +17,7 @@ import android.view.ViewGroup;
import com.wireguard.android.BR;
import java.lang.ref.WeakReference;
+import java.util.Objects;
/**
* Helper class for binding an ObservableList to the children of a ViewGroup.
@@ -26,7 +28,7 @@ class ItemChangeListener<T> {
private final ViewGroup container;
private final int layoutId;
private final LayoutInflater layoutInflater;
- private ObservableList<T> list;
+ @Nullable private ObservableList<T> list;
ItemChangeListener(final ViewGroup container, final int layoutId) {
this.container = container;
@@ -34,17 +36,21 @@ class ItemChangeListener<T> {
layoutInflater = LayoutInflater.from(container.getContext());
}
- private View getView(final int position, final View convertView) {
- ViewDataBinding binding = DataBindingUtil.getBinding(convertView);
- if (binding == null)
+ private View getView(final int position, @Nullable final View convertView) {
+ ViewDataBinding binding = convertView != null ? DataBindingUtil.getBinding(convertView) : null;
+ if (binding == null) {
binding = DataBindingUtil.inflate(layoutInflater, layoutId, container, false);
+ }
+
+ Objects.requireNonNull(list, "Trying to get a view while list is still null");
+
binding.setVariable(BR.collection, list);
binding.setVariable(BR.item, list.get(position));
binding.executePendingBindings();
return binding.getRoot();
}
- void setList(final ObservableList<T> newList) {
+ void setList(@Nullable final ObservableList<T> newList) {
if (list != null)
list.removeOnListChangedCallback(callback);
list = newList;
diff --git a/app/src/main/java/com/wireguard/android/databinding/ObservableKeyedRecyclerViewAdapter.java b/app/src/main/java/com/wireguard/android/databinding/ObservableKeyedRecyclerViewAdapter.java
index d45e60a5..835a3dc4 100644
--- a/app/src/main/java/com/wireguard/android/databinding/ObservableKeyedRecyclerViewAdapter.java
+++ b/app/src/main/java/com/wireguard/android/databinding/ObservableKeyedRecyclerViewAdapter.java
@@ -10,7 +10,7 @@ import android.content.Context;
import android.databinding.DataBindingUtil;
import android.databinding.ObservableList;
import android.databinding.ViewDataBinding;
-import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.Adapter;
import android.view.LayoutInflater;
@@ -31,8 +31,8 @@ public class ObservableKeyedRecyclerViewAdapter<K, E extends Keyed<? extends K>>
private final OnListChangedCallback<E> callback = new OnListChangedCallback<>(this);
private final int layoutId;
private final LayoutInflater layoutInflater;
- private ObservableKeyedList<K, E> list;
- private RowConfigurationHandler rowConfigurationHandler;
+ @Nullable private ObservableKeyedList<K, E> list;
+ @Nullable private RowConfigurationHandler rowConfigurationHandler;
ObservableKeyedRecyclerViewAdapter(final Context context, final int layoutId,
final ObservableKeyedList<K, E> list) {
@@ -46,6 +46,7 @@ public class ObservableKeyedRecyclerViewAdapter<K, E extends Keyed<? extends K>>
return list != null ? list.size() : 0;
}
+ @Nullable
private E getItem(final int position) {
if (list == null || position < 0 || position >= list.size())
return null;
@@ -58,30 +59,34 @@ public class ObservableKeyedRecyclerViewAdapter<K, E extends Keyed<? extends K>>
return key != null ? key.hashCode() : -1;
}
+ @Nullable
private K getKey(final int position) {
final E item = getItem(position);
return item != null ? item.getKey() : null;
}
- @NonNull @Override
- public ViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int viewType) {
+ @Override
+ public ViewHolder onCreateViewHolder(final ViewGroup parent, final int viewType) {
return new ViewHolder(DataBindingUtil.inflate(layoutInflater, layoutId, parent, false));
}
@SuppressWarnings("unchecked")
@Override
- public void onBindViewHolder(@NonNull final ViewHolder holder, final int position) {
+ public void onBindViewHolder(final ViewHolder holder, final int position) {
holder.binding.setVariable(BR.collection, list);
holder.binding.setVariable(BR.key, getKey(position));
holder.binding.setVariable(BR.item, getItem(position));
holder.binding.executePendingBindings();
if (rowConfigurationHandler != null) {
- rowConfigurationHandler.onConfigureRow(holder.binding, getItem(position), position);
+ E item = getItem(position);
+ if (item != null) {
+ rowConfigurationHandler.onConfigureRow(holder.binding, item, position);
+ }
}
}
- void setList(final ObservableKeyedList<K, E> newList) {
+ void setList(@Nullable final ObservableKeyedList<K, E> newList) {
if (list != null)
list.removeOnListChangedCallback(callback);
list = newList;
diff --git a/app/src/main/java/com/wireguard/android/fragment/AppListDialogFragment.java b/app/src/main/java/com/wireguard/android/fragment/AppListDialogFragment.java
index 15571297..50de0c39 100644
--- a/app/src/main/java/com/wireguard/android/fragment/AppListDialogFragment.java
+++ b/app/src/main/java/com/wireguard/android/fragment/AppListDialogFragment.java
@@ -39,7 +39,7 @@ public class AppListDialogFragment extends DialogFragment {
private static final String KEY_EXCLUDED_APPS = "excludedApps";
- private List<String> currentlyExcludedApps;
+ private final List<String> currentlyExcludedApps = Arrays.asList(getArguments().getStringArray(KEY_EXCLUDED_APPS));
private final ObservableKeyedList<String, ApplicationData> appData = new ObservableKeyedArrayList<>();
public static <T extends Fragment & AppExclusionListener> AppListDialogFragment newInstance(final String[] excludedApps, final T target) {
@@ -52,23 +52,11 @@ public class AppListDialogFragment extends DialogFragment {
}
@Override
- public void onCreate(@Nullable final Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- currentlyExcludedApps = Arrays.asList(getArguments().getStringArray(KEY_EXCLUDED_APPS));
- }
-
- @Override
- public void onAttach(final Context context) {
- super.onAttach(context);
- }
-
- @Override
public Dialog onCreateDialog(final Bundle savedInstanceState) {
final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getActivity());
alertDialogBuilder.setTitle(R.string.excluded_applications);
- AppListDialogFragmentBinding binding = AppListDialogFragmentBinding.inflate(getActivity().getLayoutInflater(), null, false);
+ final AppListDialogFragmentBinding binding = AppListDialogFragmentBinding.inflate(getActivity().getLayoutInflater(), null, false);
binding.executePendingBindings();
alertDialogBuilder.setView(binding.getRoot());
diff --git a/app/src/main/java/com/wireguard/android/fragment/BaseFragment.java b/app/src/main/java/com/wireguard/android/fragment/BaseFragment.java
index e1d4c87b..f4c6ea81 100644
--- a/app/src/main/java/com/wireguard/android/fragment/BaseFragment.java
+++ b/app/src/main/java/com/wireguard/android/fragment/BaseFragment.java
@@ -10,7 +10,7 @@ import android.content.Context;
import android.content.Intent;
import android.databinding.DataBindingUtil;
import android.databinding.ViewDataBinding;
-import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment;
import android.util.Log;
@@ -37,10 +37,11 @@ public abstract class BaseFragment extends Fragment implements OnSelectedTunnelC
private static final String TAG = "WireGuard/" + BaseFragment.class.getSimpleName();
private static final int REQUEST_CODE_VPN_PERMISSION = 23491;
- private BaseActivity activity;
- private Tunnel pendingTunnel;
- private Boolean pendingTunnelUp;
+ @Nullable private BaseActivity activity;
+ @Nullable private Tunnel pendingTunnel;
+ @Nullable private Boolean pendingTunnelUp;
+ @Nullable
protected Tunnel getSelectedTunnel() {
return activity != null ? activity.getSelectedTunnel() : null;
}
@@ -65,7 +66,7 @@ public abstract class BaseFragment extends Fragment implements OnSelectedTunnelC
}
@Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ public void onActivityResult(final int requestCode, final int resultCode, @Nullable final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_VPN_PERMISSION) {
@@ -76,7 +77,7 @@ public abstract class BaseFragment extends Fragment implements OnSelectedTunnelC
}
}
- protected void setSelectedTunnel(final Tunnel tunnel) {
+ protected void setSelectedTunnel(@Nullable final Tunnel tunnel) {
if (activity != null)
activity.setSelectedTunnel(tunnel);
}
@@ -106,7 +107,7 @@ public abstract class BaseFragment extends Fragment implements OnSelectedTunnelC
});
}
- private void setTunnelStateWithPermissionsResult(@NonNull final Tunnel tunnel, final boolean checked) {
+ private void setTunnelStateWithPermissionsResult(final Tunnel tunnel, final boolean checked) {
tunnel.setState(State.of(checked)).whenComplete((state, throwable) -> {
if (throwable == null)
return;
diff --git a/app/src/main/java/com/wireguard/android/fragment/TunnelDetailFragment.java b/app/src/main/java/com/wireguard/android/fragment/TunnelDetailFragment.java
index 5c35686f..cb1712fc 100644
--- a/app/src/main/java/com/wireguard/android/fragment/TunnelDetailFragment.java
+++ b/app/src/main/java/com/wireguard/android/fragment/TunnelDetailFragment.java
@@ -7,7 +7,7 @@
package com.wireguard.android.fragment;
import android.os.Bundle;
-import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
@@ -24,14 +24,16 @@ import com.wireguard.config.Config;
*/
public class TunnelDetailFragment extends BaseFragment {
- private TunnelDetailFragmentBinding binding;
+ @Nullable private TunnelDetailFragmentBinding binding;
private void onConfigLoaded(final String name, final Config config) {
- binding.setConfig(new Config.Observable(config, name));
+ if (binding != null) {
+ binding.setConfig(new Config.Observable(config, name));
+ }
}
@Override
- public void onCreate(final Bundle savedInstanceState) {
+ public void onCreate(@Nullable final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
@@ -42,8 +44,8 @@ public class TunnelDetailFragment extends BaseFragment {
}
@Override
- public View onCreateView(@NonNull final LayoutInflater inflater, final ViewGroup container,
- final Bundle savedInstanceState) {
+ public View onCreateView(final LayoutInflater inflater, @Nullable final ViewGroup container,
+ @Nullable final Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
binding = TunnelDetailFragmentBinding.inflate(inflater, container, false);
binding.executePendingBindings();
@@ -57,7 +59,7 @@ public class TunnelDetailFragment extends BaseFragment {
}
@Override
- public void onSelectedTunnelChanged(final Tunnel oldTunnel, final Tunnel newTunnel) {
+ public void onSelectedTunnelChanged(@Nullable final Tunnel oldTunnel, @Nullable final Tunnel newTunnel) {
if (binding == null)
return;
binding.setTunnel(newTunnel);
@@ -68,7 +70,11 @@ public class TunnelDetailFragment extends BaseFragment {
}
@Override
- public void onViewStateRestored(final Bundle savedInstanceState) {
+ public void onViewStateRestored(@Nullable final Bundle savedInstanceState) {
+ if (binding == null) {
+ return;
+ }
+
binding.setFragment(this);
onSelectedTunnelChanged(null, getSelectedTunnel());
super.onViewStateRestored(savedInstanceState);
diff --git a/app/src/main/java/com/wireguard/android/fragment/TunnelEditorFragment.java b/app/src/main/java/com/wireguard/android/fragment/TunnelEditorFragment.java
index f6f1483a..a6e315f9 100644
--- a/app/src/main/java/com/wireguard/android/fragment/TunnelEditorFragment.java
+++ b/app/src/main/java/com/wireguard/android/fragment/TunnelEditorFragment.java
@@ -11,7 +11,7 @@ import android.content.Context;
import android.databinding.Observable;
import android.databinding.ObservableList;
import android.os.Bundle;
-import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar;
import android.support.v4.app.FragmentManager;
import android.util.Log;
@@ -37,6 +37,7 @@ import com.wireguard.config.Config;
import com.wireguard.config.Peer;
import java.util.List;
+import java.util.Objects;
/**
* Fragment for editing a WireGuard configuration.
@@ -47,15 +48,17 @@ public class TunnelEditorFragment extends BaseFragment implements AppExclusionLi
private static final String KEY_ORIGINAL_NAME = "original_name";
private static final String TAG = "WireGuard/" + TunnelEditorFragment.class.getSimpleName();
- private TunnelEditorFragmentBinding binding;
- private Tunnel tunnel;
+ @Nullable private TunnelEditorFragmentBinding binding;
+ @Nullable private Tunnel tunnel;
private void onConfigLoaded(final String name, final Config config) {
- binding.setConfig(new Config.Observable(config, name));
+ if (binding != null) {
+ binding.setConfig(new Config.Observable(config, name));
+ }
}
private void onConfigSaved(final Tunnel savedTunnel,
- final Throwable throwable) {
+ @Nullable final Throwable throwable) {
final String message;
if (throwable == null) {
message = getString(R.string.config_save_success, savedTunnel.getName());
@@ -73,7 +76,7 @@ public class TunnelEditorFragment extends BaseFragment implements AppExclusionLi
}
@Override
- public void onCreate(final Bundle savedInstanceState) {
+ public void onCreate(@Nullable final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
@@ -124,8 +127,8 @@ public class TunnelEditorFragment extends BaseFragment implements AppExclusionLi
};
@Override
- public View onCreateView(@NonNull final LayoutInflater inflater, final ViewGroup container,
- final Bundle savedInstanceState) {
+ public View onCreateView(final LayoutInflater inflater, @Nullable final ViewGroup container,
+ @Nullable final Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
binding = TunnelEditorFragmentBinding.inflate(inflater, container, false);
binding.addOnPropertyChangedCallback(breakObjectOrientedLayeringHandler);
@@ -197,14 +200,14 @@ public class TunnelEditorFragment extends BaseFragment implements AppExclusionLi
}
@Override
- public void onSaveInstanceState(@NonNull final Bundle outState) {
+ public void onSaveInstanceState(final Bundle outState) {
outState.putParcelable(KEY_LOCAL_CONFIG, binding.getConfig());
outState.putString(KEY_ORIGINAL_NAME, tunnel == null ? null : tunnel.getName());
super.onSaveInstanceState(outState);
}
@Override
- public void onSelectedTunnelChanged(final Tunnel oldTunnel, final Tunnel newTunnel) {
+ public void onSelectedTunnelChanged(@Nullable final Tunnel oldTunnel, @Nullable final Tunnel newTunnel) {
tunnel = newTunnel;
if (binding == null)
return;
@@ -213,7 +216,7 @@ public class TunnelEditorFragment extends BaseFragment implements AppExclusionLi
tunnel.getConfigAsync().thenAccept(a -> onConfigLoaded(tunnel.getName(), a));
}
- private void onTunnelCreated(final Tunnel newTunnel, final Throwable throwable) {
+ private void onTunnelCreated(final Tunnel newTunnel, @Nullable final Throwable throwable) {
final String message;
if (throwable == null) {
tunnel = newTunnel;
@@ -232,7 +235,7 @@ public class TunnelEditorFragment extends BaseFragment implements AppExclusionLi
}
private void onTunnelRenamed(final Tunnel renamedTunnel, final Config newConfig,
- final Throwable throwable) {
+ @Nullable final Throwable throwable) {
final String message;
if (throwable == null) {
message = getString(R.string.tunnel_rename_success, renamedTunnel.getName());
@@ -251,7 +254,11 @@ public class TunnelEditorFragment extends BaseFragment implements AppExclusionLi
}
@Override
- public void onViewStateRestored(final Bundle savedInstanceState) {
+ public void onViewStateRestored(@Nullable final Bundle savedInstanceState) {
+ if (binding == null) {
+ return;
+ }
+
binding.setFragment(this);
if (savedInstanceState == null) {
@@ -271,15 +278,16 @@ public class TunnelEditorFragment extends BaseFragment implements AppExclusionLi
public void onRequestSetExcludedApplications(@SuppressWarnings("unused") final View view) {
final FragmentManager fragmentManager = getFragmentManager();
- if (fragmentManager != null) {
+ if (fragmentManager != null && binding != null) {
final String[] excludedApps = Attribute.stringToList(binding.getConfig().getInterfaceSection().getExcludedApplications());
final AppListDialogFragment fragment = AppListDialogFragment.newInstance(excludedApps, this);
- fragment.show(getFragmentManager(), null);
+ fragment.show(fragmentManager, null);
}
}
@Override
public void onExcludedAppsSelected(final List<String> excludedApps) {
+ Objects.requireNonNull(binding, "Tried to set excluded apps while no view was loaded");
binding.getConfig().getInterfaceSection().setExcludedApplications(Attribute.iterableToString(excludedApps));
}
diff --git a/app/src/main/java/com/wireguard/android/fragment/TunnelListFragment.java b/app/src/main/java/com/wireguard/android/fragment/TunnelListFragment.java
index 5dda6cfe..dd8e1337 100644
--- a/app/src/main/java/com/wireguard/android/fragment/TunnelListFragment.java
+++ b/app/src/main/java/com/wireguard/android/fragment/TunnelListFragment.java
@@ -15,7 +15,6 @@ import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.OpenableColumns;
-import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
@@ -60,20 +59,20 @@ public class TunnelListFragment extends BaseFragment {
private static final String TAG = "WireGuard/" + TunnelListFragment.class.getSimpleName();
private final ActionModeListener actionModeListener = new ActionModeListener();
- private ActionMode actionMode;
- private TunnelListFragmentBinding binding;
+ @Nullable private ActionMode actionMode;
+ @Nullable private TunnelListFragmentBinding binding;
public boolean collapseActionMenu() {
- if (binding.createMenu.isExpanded()) {
+ if (binding != null && binding.createMenu.isExpanded()) {
binding.createMenu.collapse();
return true;
}
return false;
}
- private void importTunnel(final Uri uri) {
+ private void importTunnel(@Nullable final Uri uri) {
final Activity activity = getActivity();
- if (activity == null)
+ if (activity == null || uri == null)
return;
final ContentResolver contentResolver = activity.getContentResolver();
@@ -165,10 +164,10 @@ public class TunnelListFragment extends BaseFragment {
}
@Override
- public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
+ public void onActivityResult(final int requestCode, final int resultCode, @Nullable final Intent data) {
switch (requestCode) {
case REQUEST_IMPORT:
- if (resultCode == Activity.RESULT_OK)
+ if (resultCode == Activity.RESULT_OK && data != null)
importTunnel(data.getData());
return;
default:
@@ -178,8 +177,8 @@ public class TunnelListFragment extends BaseFragment {
@SuppressLint("ClickableViewAccessibility")
@Override
- public View onCreateView(@NonNull final LayoutInflater inflater, final ViewGroup container,
- final Bundle savedInstanceState) {
+ public View onCreateView(final LayoutInflater inflater, @Nullable final ViewGroup container,
+ @Nullable final Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
binding = TunnelListFragmentBinding.inflate(inflater, container, false);
@@ -216,16 +215,18 @@ public class TunnelListFragment extends BaseFragment {
@Override
public void onPause() {
- binding.createMenu.collapse();
+ if (binding != null) {
+ binding.createMenu.collapse();
+ }
super.onPause();
}
@Override
- public void onSelectedTunnelChanged(final Tunnel oldTunnel, final Tunnel newTunnel) {
+ public void onSelectedTunnelChanged(@Nullable final Tunnel oldTunnel, @Nullable final Tunnel newTunnel) {
// Do nothing.
}
- private void onTunnelDeletionFinished(final Integer count, final Throwable throwable) {
+ private void onTunnelDeletionFinished(final Integer count, @Nullable final Throwable throwable) {
final String message;
if (throwable == null) {
message = getResources().getQuantityString(R.plurals.delete_success, count, count);
@@ -265,8 +266,13 @@ public class TunnelListFragment extends BaseFragment {
}
@Override
- public void onViewStateRestored(final Bundle savedInstanceState) {
+ public void onViewStateRestored(@Nullable final Bundle savedInstanceState) {
super.onViewStateRestored(savedInstanceState);
+
+ if (binding == null) {
+ return;
+ }
+
binding.setFragment(this);
binding.setTunnels(Application.getTunnelManager().getTunnels());
binding.setRowConfigurationHandler((ObservableKeyedRecyclerViewAdapter.RowConfigurationHandler<TunnelListItemBinding, Tunnel>) (binding, tunnel, position) -> {
@@ -290,7 +296,7 @@ public class TunnelListFragment extends BaseFragment {
private final class ActionModeListener implements ActionMode.Callback {
private final Collection<Integer> checkedItems = new HashSet<>();
- private Resources resources;
+ @Nullable private Resources resources;
@Override
public boolean onActionItemClicked(final ActionMode mode, final MenuItem item) {
@@ -357,7 +363,9 @@ public class TunnelListFragment extends BaseFragment {
actionMode.finish();
}
- binding.tunnelList.getAdapter().notifyItemChanged(position);
+ if (binding != null) {
+ binding.tunnelList.getAdapter().notifyItemChanged(position);
+ }
updateTitle(actionMode);
}
diff --git a/app/src/main/java/com/wireguard/android/model/ApplicationData.java b/app/src/main/java/com/wireguard/android/model/ApplicationData.java
index 26f81030..73dfb4a9 100644
--- a/app/src/main/java/com/wireguard/android/model/ApplicationData.java
+++ b/app/src/main/java/com/wireguard/android/model/ApplicationData.java
@@ -9,36 +9,32 @@ package com.wireguard.android.model;
import android.databinding.BaseObservable;
import android.databinding.Bindable;
import android.graphics.drawable.Drawable;
-import android.support.annotation.NonNull;
import com.wireguard.android.BR;
import com.wireguard.util.Keyed;
public class ApplicationData extends BaseObservable implements Keyed<String> {
- @NonNull private final Drawable icon;
- @NonNull private final String name;
- @NonNull private final String packageName;
+ private final Drawable icon;
+ private final String name;
+ private final String packageName;
private boolean excludedFromTunnel;
- public ApplicationData(@NonNull final Drawable icon, @NonNull final String name, @NonNull final String packageName, final boolean excludedFromTunnel) {
+ public ApplicationData(final Drawable icon, final String name, final String packageName, final boolean excludedFromTunnel) {
this.icon = icon;
this.name = name;
this.packageName = packageName;
this.excludedFromTunnel = excludedFromTunnel;
}
- @NonNull
public Drawable getIcon() {
return icon;
}
- @NonNull
public String getName() {
return name;
}
- @NonNull
public String getPackageName() {
return packageName;
}
diff --git a/app/src/main/java/com/wireguard/android/model/Tunnel.java b/app/src/main/java/com/wireguard/android/model/Tunnel.java
index 5ea2c0a8..b0d2c1da 100644
--- a/app/src/main/java/com/wireguard/android/model/Tunnel.java
+++ b/app/src/main/java/com/wireguard/android/model/Tunnel.java
@@ -8,13 +8,12 @@ package com.wireguard.android.model;
import android.databinding.BaseObservable;
import android.databinding.Bindable;
-import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.wireguard.android.BR;
import com.wireguard.android.util.ExceptionLoggers;
-import com.wireguard.util.Keyed;
import com.wireguard.config.Config;
+import com.wireguard.util.Keyed;
import java.util.regex.Pattern;
@@ -30,20 +29,20 @@ public class Tunnel extends BaseObservable implements Keyed<String> {
private static final Pattern NAME_PATTERN = Pattern.compile("[a-zA-Z0-9_=+.-]{1,15}");
private final TunnelManager manager;
- private Config config;
+ @Nullable private Config config;
private String name;
private State state;
- private Statistics statistics;
+ @Nullable private Statistics statistics;
- Tunnel(@NonNull final TunnelManager manager, @NonNull final String name,
- @Nullable final Config config, @NonNull final State state) {
+ Tunnel(final TunnelManager manager, final String name,
+ @Nullable final Config config, final State state) {
this.manager = manager;
this.name = name;
this.config = config;
this.state = state;
}
- public static boolean isNameInvalid(@NonNull final CharSequence name) {
+ public static boolean isNameInvalid(final CharSequence name) {
return !NAME_PATTERN.matcher(name).matches();
}
@@ -51,7 +50,7 @@ public class Tunnel extends BaseObservable implements Keyed<String> {
return manager.delete(this);
}
- @Bindable
+ @Bindable @Nullable
public Config getConfig() {
if (config == null)
manager.getTunnelConfig(this).whenComplete(ExceptionLoggers.E);
@@ -83,7 +82,7 @@ public class Tunnel extends BaseObservable implements Keyed<String> {
return TunnelManager.getTunnelState(this);
}
- @Bindable
+ @Bindable @Nullable
public Statistics getStatistics() {
// FIXME: Check age of statistics.
if (statistics == null)
@@ -118,25 +117,26 @@ public class Tunnel extends BaseObservable implements Keyed<String> {
return state;
}
- Statistics onStatisticsChanged(final Statistics statistics) {
+ @Nullable
+ Statistics onStatisticsChanged(@Nullable final Statistics statistics) {
this.statistics = statistics;
notifyPropertyChanged(BR.statistics);
return statistics;
}
- public CompletionStage<Config> setConfig(@NonNull final Config config) {
+ public CompletionStage<Config> setConfig(final Config config) {
if (!config.equals(this.config))
return manager.setTunnelConfig(this, config);
return CompletableFuture.completedFuture(this.config);
}
- public CompletionStage<String> setName(@NonNull final String name) {
+ public CompletionStage<String> setName(final String name) {
if (!name.equals(this.name))
return manager.setTunnelName(this, name);
return CompletableFuture.completedFuture(this.name);
}
- public CompletionStage<State> setState(@NonNull final State state) {
+ public CompletionStage<State> setState(final State state) {
if (state != this.state)
return manager.setTunnelState(this, state);
return CompletableFuture.completedFuture(this.state);
@@ -152,6 +152,5 @@ public class Tunnel extends BaseObservable implements Keyed<String> {
}
}
- public static class Statistics extends BaseObservable {
- }
+ public static class Statistics extends BaseObservable { }
}
diff --git a/app/src/main/java/com/wireguard/android/model/TunnelManager.java b/app/src/main/java/com/wireguard/android/model/TunnelManager.java
index a9998d5a..f7b18c07 100644
--- a/app/src/main/java/com/wireguard/android/model/TunnelManager.java
+++ b/app/src/main/java/com/wireguard/android/model/TunnelManager.java
@@ -11,7 +11,7 @@ import android.content.Context;
import android.content.Intent;
import android.databinding.BaseObservable;
import android.databinding.Bindable;
-import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import com.wireguard.android.Application;
import com.wireguard.android.BR;
@@ -47,9 +47,8 @@ public final class TunnelManager extends BaseObservable {
private static final String KEY_RUNNING_TUNNELS = "enabled_configs";
private final ConfigStore configStore;
- private final ObservableSortedKeyedList<String, Tunnel> tunnels =
- new ObservableSortedKeyedArrayList<>(COMPARATOR);
- private Tunnel lastUsedTunnel;
+ private final ObservableSortedKeyedList<String, Tunnel> tunnels = new ObservableSortedKeyedArrayList<>(COMPARATOR);
+ @Nullable private Tunnel lastUsedTunnel;
private boolean haveLoaded;
private final ArrayList<CompletableFuture<Void>> delayedLoadRestoreTunnels = new ArrayList<>();
@@ -57,13 +56,13 @@ public final class TunnelManager extends BaseObservable {
this.configStore = configStore;
}
- private Tunnel addToList(final String name, final Config config, final State state) {
+ private Tunnel addToList(final String name, @Nullable final Config config, final State state) {
final Tunnel tunnel = new Tunnel(this, name, config, state);
tunnels.add(tunnel);
return tunnel;
}
- public CompletionStage<Tunnel> create(@NonNull final String name, final Config config) {
+ public CompletionStage<Tunnel> create(final String name, @Nullable final Config config) {
if (Tunnel.isNameInvalid(name))
return CompletableFuture.failedFuture(new IllegalArgumentException("Invalid name"));
if (tunnels.containsKey(name)) {
@@ -102,7 +101,7 @@ public final class TunnelManager extends BaseObservable {
});
}
- @Bindable
+ @Bindable @Nullable
public Tunnel getLastUsedTunnel() {
return lastUsedTunnel;
}
@@ -191,7 +190,7 @@ public final class TunnelManager extends BaseObservable {
Application.getSharedPreferences().edit().putStringSet(KEY_RUNNING_TUNNELS, runningTunnels).apply();
}
- private void setLastUsedTunnel(final Tunnel tunnel) {
+ private void setLastUsedTunnel(@Nullable final Tunnel tunnel) {
if (tunnel == lastUsedTunnel)
return;
lastUsedTunnel = tunnel;
@@ -256,7 +255,7 @@ public final class TunnelManager extends BaseObservable {
public static final class IntentReceiver extends BroadcastReceiver {
@Override
- public void onReceive(final Context context, final Intent intent) {
+ public void onReceive(final Context context, @Nullable final Intent intent) {
final TunnelManager manager = Application.getTunnelManager();
if (intent == null)
return;
diff --git a/app/src/main/java/com/wireguard/android/preference/LogExporterPreference.java b/app/src/main/java/com/wireguard/android/preference/LogExporterPreference.java
index f9ac9a41..a96cb9c8 100644
--- a/app/src/main/java/com/wireguard/android/preference/LogExporterPreference.java
+++ b/app/src/main/java/com/wireguard/android/preference/LogExporterPreference.java
@@ -10,6 +10,7 @@ import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Environment;
+import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar;
import android.support.v7.preference.Preference;
import android.util.AttributeSet;
@@ -33,7 +34,7 @@ import java.io.InputStreamReader;
public class LogExporterPreference extends Preference {
private static final String TAG = "WireGuard/" + LogExporterPreference.class.getSimpleName();
- private String exportedFilePath;
+ @Nullable private String exportedFilePath;
public LogExporterPreference(final Context context, final AttributeSet attrs) {
super(context, attrs);
@@ -73,7 +74,7 @@ public class LogExporterPreference extends Preference {
}).whenComplete(this::exportLogComplete);
}
- private void exportLogComplete(final String filePath, final Throwable throwable) {
+ private void exportLogComplete(final String filePath, @Nullable final Throwable throwable) {
if (throwable != null) {
final String error = ExceptionLoggers.unwrapMessage(throwable);
final String message = getContext().getString(R.string.log_export_error, error);
diff --git a/app/src/main/java/com/wireguard/android/preference/ToolsInstallerPreference.java b/app/src/main/java/com/wireguard/android/preference/ToolsInstallerPreference.java
index 44599edc..4006d0e8 100644
--- a/app/src/main/java/com/wireguard/android/preference/ToolsInstallerPreference.java
+++ b/app/src/main/java/com/wireguard/android/preference/ToolsInstallerPreference.java
@@ -7,7 +7,7 @@
package com.wireguard.android.preference;
import android.content.Context;
-import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.support.v7.preference.Preference;
import android.util.AttributeSet;
@@ -43,7 +43,7 @@ public class ToolsInstallerPreference extends Preference {
Application.getAsyncWorker().supplyAsync(Application.getToolsInstaller()::areInstalled).whenComplete(this::onCheckResult);
}
- private void onCheckResult(final int state, final Throwable throwable) {
+ private void onCheckResult(final int state, @Nullable final Throwable throwable) {
if (throwable != null || state == ToolsInstaller.ERROR)
setState(State.INITIAL);
else if ((state & ToolsInstaller.YES) == ToolsInstaller.YES)
@@ -62,7 +62,7 @@ public class ToolsInstallerPreference extends Preference {
Application.getAsyncWorker().supplyAsync(Application.getToolsInstaller()::install).whenComplete(this::onInstallResult);
}
- private void onInstallResult(final Integer result, final Throwable throwable) {
+ private void onInstallResult(final Integer result, @Nullable final Throwable throwable) {
if (throwable != null)
setState(State.FAILURE);
else if ((result & (ToolsInstaller.YES | ToolsInstaller.MAGISK)) == (ToolsInstaller.YES | ToolsInstaller.MAGISK))
@@ -73,7 +73,7 @@ public class ToolsInstallerPreference extends Preference {
setState(State.FAILURE);
}
- private void setState(@NonNull final State state) {
+ private void setState(final State state) {
if (this.state == state)
return;
this.state = state;
diff --git a/app/src/main/java/com/wireguard/android/preference/VersionPreference.java b/app/src/main/java/com/wireguard/android/preference/VersionPreference.java
index de34047d..525396bc 100644
--- a/app/src/main/java/com/wireguard/android/preference/VersionPreference.java
+++ b/app/src/main/java/com/wireguard/android/preference/VersionPreference.java
@@ -9,6 +9,7 @@ import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
+import android.support.annotation.Nullable;
import android.support.v7.preference.Preference;
import android.util.AttributeSet;
@@ -17,7 +18,7 @@ import com.wireguard.android.BuildConfig;
import com.wireguard.android.R;
public class VersionPreference extends Preference {
- private String versionSummary;
+ @Nullable private String versionSummary;
public VersionPreference(final Context context, final AttributeSet attrs) {
super(context, attrs);
@@ -33,7 +34,7 @@ public class VersionPreference extends Preference {
});
}
- @Override
+ @Override @Nullable
public CharSequence getSummary() {
return versionSummary;
}
diff --git a/app/src/main/java/com/wireguard/android/preference/ZipExporterPreference.java b/app/src/main/java/com/wireguard/android/preference/ZipExporterPreference.java
index 16094007..a1477214 100644
--- a/app/src/main/java/com/wireguard/android/preference/ZipExporterPreference.java
+++ b/app/src/main/java/com/wireguard/android/preference/ZipExporterPreference.java
@@ -10,6 +10,7 @@ import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Environment;
+import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar;
import android.support.v7.preference.Preference;
import android.util.AttributeSet;
@@ -40,7 +41,7 @@ import java9.util.concurrent.CompletableFuture;
public class ZipExporterPreference extends Preference {
private static final String TAG = "WireGuard/" + ZipExporterPreference.class.getSimpleName();
- private String exportedFilePath;
+ @Nullable private String exportedFilePath;
public ZipExporterPreference(final Context context, final AttributeSet attrs) {
super(context, attrs);
@@ -79,7 +80,7 @@ public class ZipExporterPreference extends Preference {
}).whenComplete(this::exportZipComplete));
}
- private void exportZipComplete(final String filePath, final Throwable throwable) {
+ private void exportZipComplete(@Nullable final String filePath, @Nullable final Throwable throwable) {
if (throwable != null) {
final String error = ExceptionLoggers.unwrapMessage(throwable);
final String message = getContext().getString(R.string.zip_export_error, error);
diff --git a/app/src/main/java/com/wireguard/android/util/ExceptionLoggers.java b/app/src/main/java/com/wireguard/android/util/ExceptionLoggers.java
index b8c0c4fa..70d97fb1 100644
--- a/app/src/main/java/com/wireguard/android/util/ExceptionLoggers.java
+++ b/app/src/main/java/com/wireguard/android/util/ExceptionLoggers.java
@@ -6,8 +6,9 @@
package com.wireguard.android.util;
-import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.util.Log;
+
import java9.util.concurrent.CompletionException;
import java9.util.function.BiConsumer;
@@ -34,7 +35,6 @@ public enum ExceptionLoggers implements BiConsumer<Object, Throwable> {
return throwable;
}
- @NonNull
public static String unwrapMessage(Throwable throwable) {
throwable = unwrap(throwable);
final String message = throwable.getMessage();
@@ -44,7 +44,7 @@ public enum ExceptionLoggers implements BiConsumer<Object, Throwable> {
}
@Override
- public void accept(final Object result, final Throwable throwable) {
+ public void accept(final Object result, @Nullable final Throwable throwable) {
if (throwable != null)
Log.println(Log.ERROR, TAG, Log.getStackTraceString(throwable));
else if (priority <= Log.DEBUG)
diff --git a/app/src/main/java/com/wireguard/android/util/ObservableKeyedArrayList.java b/app/src/main/java/com/wireguard/android/util/ObservableKeyedArrayList.java
index 1e064e42..0be3c005 100644
--- a/app/src/main/java/com/wireguard/android/util/ObservableKeyedArrayList.java
+++ b/app/src/main/java/com/wireguard/android/util/ObservableKeyedArrayList.java
@@ -7,7 +7,7 @@
package com.wireguard.android.util;
import android.databinding.ObservableArrayList;
-import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import com.wireguard.util.Keyed;
@@ -25,28 +25,28 @@ import java.util.Objects;
public class ObservableKeyedArrayList<K, E extends Keyed<? extends K>>
extends ObservableArrayList<E> implements ObservableKeyedList<K, E> {
@Override
- public boolean add(final E e) {
+ public boolean add(@Nullable final E e) {
if (e == null)
throw new NullPointerException("Trying to add a null element");
return super.add(e);
}
@Override
- public void add(final int index, final E e) {
+ public void add(final int index, @Nullable final E e) {
if (e == null)
throw new NullPointerException("Trying to add a null element");
super.add(index, e);
}
@Override
- public boolean addAll(@NonNull final Collection<? extends E> c) {
+ public boolean addAll(final Collection<? extends E> c) {
if (c.contains(null))
throw new NullPointerException("Trying to add a collection with null element(s)");
return super.addAll(c);
}
@Override
- public boolean addAll(final int index, @NonNull final Collection<? extends E> c) {
+ public boolean addAll(final int index, final Collection<? extends E> c) {
if (c.contains(null))
throw new NullPointerException("Trying to add a collection with null element(s)");
return super.addAll(index, c);
@@ -65,13 +65,13 @@ public class ObservableKeyedArrayList<K, E extends Keyed<? extends K>>
return indexOfKey(key) >= 0;
}
- @Override
+ @Override @Nullable
public E get(final K key) {
final int index = indexOfKey(key);
return index >= 0 ? get(index) : null;
}
- @Override
+ @Override @Nullable
public E getLast(final K key) {
final int index = lastIndexOfKey(key);
return index >= 0 ? get(index) : null;
@@ -100,7 +100,7 @@ public class ObservableKeyedArrayList<K, E extends Keyed<? extends K>>
}
@Override
- public E set(final int index, final E e) {
+ public E set(final int index, @Nullable final E e) {
if (e == null)
throw new NullPointerException("Trying to set a null key");
return super.set(index, e);
diff --git a/app/src/main/java/com/wireguard/android/util/ObservableSortedKeyedArrayList.java b/app/src/main/java/com/wireguard/android/util/ObservableSortedKeyedArrayList.java
index 4ff3a771..239520c4 100644
--- a/app/src/main/java/com/wireguard/android/util/ObservableSortedKeyedArrayList.java
+++ b/app/src/main/java/com/wireguard/android/util/ObservableSortedKeyedArrayList.java
@@ -6,7 +6,7 @@
package com.wireguard.android.util;
-import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import com.wireguard.util.Keyed;
import com.wireguard.util.SortedKeyedList;
@@ -29,6 +29,7 @@ import java.util.Spliterator;
public class ObservableSortedKeyedArrayList<K, E extends Keyed<? extends K>>
extends ObservableKeyedArrayList<K, E> implements ObservableSortedKeyedList<K, E> {
+ @Nullable
private final Comparator<? super K> comparator;
private final transient KeyList<K, E> keyList = new KeyList<>(this);
@@ -75,7 +76,7 @@ public class ObservableSortedKeyedArrayList<K, E extends Keyed<? extends K>>
}
@Override
- public boolean addAll(@NonNull final Collection<? extends E> c) {
+ public boolean addAll(final Collection<? extends E> c) {
boolean didChange = false;
for (final E e : c)
if (add(e))
@@ -84,12 +85,13 @@ public class ObservableSortedKeyedArrayList<K, E extends Keyed<? extends K>>
}
@Override
- public boolean addAll(int index, @NonNull final Collection<? extends E> c) {
+ public boolean addAll(int index, final Collection<? extends E> c) {
for (final E e : c)
add(index++, e);
return true;
}
+ @Nullable
@Override
public Comparator<? super K> comparator() {
return comparator;
@@ -128,7 +130,6 @@ public class ObservableSortedKeyedArrayList<K, E extends Keyed<? extends K>>
}
@Override
- @NonNull
public Set<K> keySet() {
return keyList;
}
@@ -168,7 +169,6 @@ public class ObservableSortedKeyedArrayList<K, E extends Keyed<? extends K>>
}
@Override
- @NonNull
public Collection<E> values() {
return this;
}
diff --git a/app/src/main/java/com/wireguard/android/util/RootShell.java b/app/src/main/java/com/wireguard/android/util/RootShell.java
index 9293dff9..18e04102 100644
--- a/app/src/main/java/com/wireguard/android/util/RootShell.java
+++ b/app/src/main/java/com/wireguard/android/util/RootShell.java
@@ -7,6 +7,7 @@
package com.wireguard.android.util;
import android.content.Context;
+import android.support.annotation.Nullable;
import android.util.Log;
import com.wireguard.android.R;
@@ -34,10 +35,10 @@ public class RootShell {
private final File localTemporaryDir;
private final Object lock = new Object();
private final String preamble;
- private Process process;
- private BufferedReader stderr;
- private OutputStreamWriter stdin;
- private BufferedReader stdout;
+ @Nullable private Process process;
+ @Nullable private BufferedReader stderr;
+ @Nullable private OutputStreamWriter stdin;
+ @Nullable private BufferedReader stdout;
public RootShell(final Context context) {
deviceNotRootedMessage = context.getString(R.string.error_root);
@@ -80,7 +81,7 @@ public class RootShell {
* @param command Command to run as root.
* @return The exit value of the command.
*/
- public int run(final Collection<String> output, final String command)
+ public int run(@Nullable final Collection<String> output, final String command)
throws IOException, NoRootException {
synchronized (lock) {
/* Start inside synchronized block to prevent a concurrent call to stop(). */
diff --git a/app/src/main/java/com/wireguard/android/util/SharedLibraryLoader.java b/app/src/main/java/com/wireguard/android/util/SharedLibraryLoader.java
index e0bb579d..997dd45c 100644
--- a/app/src/main/java/com/wireguard/android/util/SharedLibraryLoader.java
+++ b/app/src/main/java/com/wireguard/android/util/SharedLibraryLoader.java
@@ -19,8 +19,7 @@ import java.util.zip.ZipFile;
public final class SharedLibraryLoader {
private static final String TAG = "WireGuard/" + SharedLibraryLoader.class.getSimpleName();
- private SharedLibraryLoader() {
- }
+ private SharedLibraryLoader() { }
public static void loadSharedLibrary(final Context context, final String libName) {
Throwable noAbiException;
diff --git a/app/src/main/java/com/wireguard/android/util/ToolsInstaller.java b/app/src/main/java/com/wireguard/android/util/ToolsInstaller.java
index 9cdb6a59..16c906eb 100644
--- a/app/src/main/java/com/wireguard/android/util/ToolsInstaller.java
+++ b/app/src/main/java/com/wireguard/android/util/ToolsInstaller.java
@@ -7,6 +7,7 @@
package com.wireguard.android.util;
import android.content.Context;
+import android.support.annotation.Nullable;
import android.system.OsConstants;
import android.util.Log;
@@ -39,20 +40,21 @@ public final class ToolsInstaller {
new File("/system/xbin"),
new File("/system/bin"),
};
- private static final File INSTALL_DIR = getInstallDir();
+ @Nullable private static final File INSTALL_DIR = getInstallDir();
private static final String TAG = "WireGuard/" + ToolsInstaller.class.getSimpleName();
private final File localBinaryDir;
private final Object lock = new Object();
private final File nativeLibraryDir;
- private Boolean areToolsAvailable;
- private Boolean installAsMagiskModule;
+ @Nullable private Boolean areToolsAvailable;
+ @Nullable private Boolean installAsMagiskModule;
public ToolsInstaller(final Context context) {
localBinaryDir = new File(context.getCacheDir(), "bin");
nativeLibraryDir = new File(context.getApplicationInfo().nativeLibraryDir);
}
+ @Nullable
private static File getInstallDir() {
final String path = System.getenv("PATH");
if (path == null)
diff --git a/app/src/main/java/com/wireguard/android/widget/KeyInputFilter.java b/app/src/main/java/com/wireguard/android/widget/KeyInputFilter.java
index fff3bc22..a7c11717 100644
--- a/app/src/main/java/com/wireguard/android/widget/KeyInputFilter.java
+++ b/app/src/main/java/com/wireguard/android/widget/KeyInputFilter.java
@@ -6,6 +6,7 @@
package com.wireguard.android.widget;
+import android.support.annotation.Nullable;
import android.text.InputFilter;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
@@ -25,7 +26,7 @@ public class KeyInputFilter implements InputFilter {
return new KeyInputFilter();
}
- @Override
+ @Override @Nullable
public CharSequence filter(final CharSequence source,
final int sStart, final int sEnd,
final Spanned dest,
diff --git a/app/src/main/java/com/wireguard/android/widget/NameInputFilter.java b/app/src/main/java/com/wireguard/android/widget/NameInputFilter.java
index b31c9176..514b9f88 100644
--- a/app/src/main/java/com/wireguard/android/widget/NameInputFilter.java
+++ b/app/src/main/java/com/wireguard/android/widget/NameInputFilter.java
@@ -6,6 +6,7 @@
package com.wireguard.android.widget;
+import android.support.annotation.Nullable;
import android.text.InputFilter;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
@@ -25,7 +26,7 @@ public class NameInputFilter implements InputFilter {
return new NameInputFilter();
}
- @Override
+ @Override @Nullable
public CharSequence filter(final CharSequence source,
final int sStart, final int sEnd,
final Spanned dest,
diff --git a/app/src/main/java/com/wireguard/android/widget/SlashDrawable.java b/app/src/main/java/com/wireguard/android/widget/SlashDrawable.java
index 64fe7f73..53530e0a 100644
--- a/app/src/main/java/com/wireguard/android/widget/SlashDrawable.java
+++ b/app/src/main/java/com/wireguard/android/widget/SlashDrawable.java
@@ -25,11 +25,9 @@ import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.annotation.ColorInt;
import android.support.annotation.IntRange;
-import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.FloatProperty;
-
@TargetApi(Build.VERSION_CODES.N)
public class SlashDrawable extends Drawable {
@@ -53,26 +51,24 @@ public class SlashDrawable extends Drawable {
// Draw the slash washington-monument style; rotate to no-u-turn style
private static final float DEFAULT_ROTATION = -45f;
- private Drawable mDrawable;
+ private final Drawable mDrawable;
private final RectF mSlashRect = new RectF(0, 0, 0, 0);
private float mRotation;
private boolean mSlashed;
- private Mode mTintMode;
- private ColorStateList mTintList;
private boolean mAnimationEnabled = true;
public SlashDrawable(final Drawable d) {
- setDrawable(d);
+ mDrawable = d;
}
@Override
public int getIntrinsicHeight() {
- return mDrawable != null ? mDrawable.getIntrinsicHeight(): 0;
+ return mDrawable.getIntrinsicHeight();
}
@Override
public int getIntrinsicWidth() {
- return mDrawable != null ? mDrawable.getIntrinsicWidth(): 0;
+ return mDrawable.getIntrinsicWidth();
}
@Override
@@ -81,17 +77,6 @@ public class SlashDrawable extends Drawable {
mDrawable.setBounds(bounds);
}
- public void setDrawable(final Drawable d) {
- mDrawable = d;
- mDrawable.setCallback(getCallback());
- mDrawable.setBounds(getBounds());
- if (mTintMode != null)
- mDrawable.setTintMode(mTintMode);
- if (mTintList != null)
- mDrawable.setTintList(mTintList);
- invalidateSelf();
- }
-
public void setRotation(final float rotation) {
if (mRotation == rotation)
return;
@@ -139,7 +124,7 @@ public class SlashDrawable extends Drawable {
@SuppressWarnings("deprecation")
@Override
- public void draw(@NonNull final Canvas canvas) {
+ public void draw(final Canvas canvas) {
canvas.save();
final Matrix m = new Matrix();
final int width = getBounds().width();
@@ -201,7 +186,6 @@ public class SlashDrawable extends Drawable {
@Override
public void setTintList(@Nullable final ColorStateList tint) {
- mTintList = tint;
super.setTintList(tint);
setDrawableTintList(tint);
mPaint.setColor(tint == null ? 0 : tint.getDefaultColor());
@@ -213,8 +197,7 @@ public class SlashDrawable extends Drawable {
}
@Override
- public void setTintMode(@NonNull final Mode tintMode) {
- mTintMode = tintMode;
+ public void setTintMode(final Mode tintMode) {
super.setTintMode(tintMode);
mDrawable.setTintMode(tintMode);
}
diff --git a/app/src/main/java/com/wireguard/android/widget/ToggleSwitch.java b/app/src/main/java/com/wireguard/android/widget/ToggleSwitch.java
index b71ad447..b2928293 100644
--- a/app/src/main/java/com/wireguard/android/widget/ToggleSwitch.java
+++ b/app/src/main/java/com/wireguard/android/widget/ToggleSwitch.java
@@ -7,22 +7,23 @@ package com.wireguard.android.widget;
import android.content.Context;
import android.os.Parcelable;
+import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.widget.Switch;
public class ToggleSwitch extends Switch {
private boolean isRestoringState;
- private OnBeforeCheckedChangeListener listener;
-
- @SuppressWarnings({"SameParameterValue", "WeakerAccess"})
- public ToggleSwitch(final Context context, final AttributeSet attrs) {
- super(context, attrs);
- }
+ @Nullable private OnBeforeCheckedChangeListener listener;
public ToggleSwitch(final Context context) {
this(context, null);
}
+ @SuppressWarnings({"SameParameterValue", "WeakerAccess"})
+ public ToggleSwitch(final Context context, @Nullable final AttributeSet attrs) {
+ super(context, attrs);
+ }
+
@Override
public void onRestoreInstanceState(final Parcelable state) {
isRestoringState = true;
diff --git a/app/src/main/java/com/wireguard/android/widget/fab/FloatingActionsMenu.java b/app/src/main/java/com/wireguard/android/widget/fab/FloatingActionsMenu.java
index fb87b1e9..7ca6d976 100644
--- a/app/src/main/java/com/wireguard/android/widget/fab/FloatingActionsMenu.java
+++ b/app/src/main/java/com/wireguard/android/widget/fab/FloatingActionsMenu.java
@@ -20,7 +20,7 @@ import android.graphics.drawable.LayerDrawable;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.Keep;
-import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.content.res.ResourcesCompat;
import android.support.v7.widget.AppCompatTextView;
@@ -57,32 +57,32 @@ public class FloatingActionsMenu extends ViewGroup {
private boolean mExpanded;
private final AnimatorSet mExpandAnimation = new AnimatorSet().setDuration(ANIMATION_DURATION);
private final AnimatorSet mCollapseAnimation = new AnimatorSet().setDuration(ANIMATION_DURATION);
- private FloatingActionButton mAddButton;
- private RotatingDrawable mRotatingDrawable;
+ @Nullable private FloatingActionButton mAddButton;
+ @Nullable private RotatingDrawable mRotatingDrawable;
private int mMaxButtonWidth;
private int mMaxButtonHeight;
private int mLabelsStyle;
private int mLabelsPosition;
private int mButtonsCount;
- private TouchDelegateGroup mTouchDelegateGroup;
- private OnFloatingActionsMenuUpdateListener mListener;
+ @Nullable private TouchDelegateGroup mTouchDelegateGroup;
+ @Nullable private OnFloatingActionsMenuUpdateListener mListener;
private final Rect touchArea = new Rect(0, 0, 0, 0);
public FloatingActionsMenu(final Context context) {
this(context, null);
}
- public FloatingActionsMenu(final Context context, final AttributeSet attrs) {
+ public FloatingActionsMenu(final Context context, @Nullable final AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
- public FloatingActionsMenu(final Context context, final AttributeSet attrs, final int defStyle) {
+ public FloatingActionsMenu(final Context context, @Nullable final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
init(context, attrs);
}
- private void init(final Context context, final AttributeSet attributeSet) {
+ private void init(final Context context, @Nullable final AttributeSet attributeSet) {
mButtonSpacing = (int) (getResources().getDimension(R.dimen.fab_actions_spacing));
mLabelsMargin = getResources().getDimensionPixelSize(R.dimen.fab_labels_margin);
mLabelsVerticalOffset = getResources().getDimensionPixelSize(R.dimen.fab_shadow_offset);
@@ -530,7 +530,7 @@ public class FloatingActionsMenu extends ViewGroup {
}
@Override
- public void writeToParcel(@NonNull final Parcel out, final int flags) {
+ public void writeToParcel(final Parcel out, final int flags) {
super.writeToParcel(out, flags);
out.writeInt(mExpanded ? 1 : 0);
}
diff --git a/app/src/main/java/com/wireguard/android/widget/fab/LabeledFloatingActionButton.java b/app/src/main/java/com/wireguard/android/widget/fab/LabeledFloatingActionButton.java
index a203282e..cc6c97cc 100644
--- a/app/src/main/java/com/wireguard/android/widget/fab/LabeledFloatingActionButton.java
+++ b/app/src/main/java/com/wireguard/android/widget/fab/LabeledFloatingActionButton.java
@@ -8,6 +8,7 @@ package com.wireguard.android.widget.fab;
import android.content.Context;
import android.content.res.TypedArray;
+import android.support.annotation.Nullable;
import android.support.design.widget.FloatingActionButton;
import android.util.AttributeSet;
import android.widget.TextView;
@@ -16,17 +17,17 @@ import com.wireguard.android.R;
public class LabeledFloatingActionButton extends FloatingActionButton {
- private final String title;
+ @Nullable private final String title;
public LabeledFloatingActionButton(final Context context) {
this(context, null);
}
- public LabeledFloatingActionButton(final Context context, final AttributeSet attrs) {
+ public LabeledFloatingActionButton(final Context context, @Nullable final AttributeSet attrs) {
this(context, attrs, 0);
}
- public LabeledFloatingActionButton(final Context context, final AttributeSet attrs, final int defStyle) {
+ public LabeledFloatingActionButton(final Context context, @Nullable final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
final TypedArray attr = context.obtainStyledAttributes(attrs, R.styleable.LabeledFloatingActionButton, 0, 0);
@@ -34,10 +35,12 @@ public class LabeledFloatingActionButton extends FloatingActionButton {
attr.recycle();
}
+ @Nullable
TextView getLabelView() {
return (TextView) getTag(R.id.fab_label);
}
+ @Nullable
public String getTitle() {
return title;
}
diff --git a/app/src/main/java/com/wireguard/android/widget/fab/TouchDelegateGroup.java b/app/src/main/java/com/wireguard/android/widget/fab/TouchDelegateGroup.java
index f6152934..6812f885 100644
--- a/app/src/main/java/com/wireguard/android/widget/fab/TouchDelegateGroup.java
+++ b/app/src/main/java/com/wireguard/android/widget/fab/TouchDelegateGroup.java
@@ -7,7 +7,7 @@
package com.wireguard.android.widget.fab;
import android.graphics.Rect;
-import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.view.MotionEvent;
import android.view.TouchDelegate;
import android.view.View;
@@ -18,14 +18,14 @@ import java.util.Collection;
public class TouchDelegateGroup extends TouchDelegate {
private static final Rect USELESS_HACKY_RECT = new Rect();
private final Collection<TouchDelegate> mTouchDelegates = new ArrayList<>();
- private TouchDelegate mCurrentTouchDelegate;
+ @Nullable private TouchDelegate mCurrentTouchDelegate;
private boolean mEnabled;
public TouchDelegateGroup(final View uselessHackyView) {
super(USELESS_HACKY_RECT, uselessHackyView);
}
- public void addTouchDelegate(@NonNull final TouchDelegate touchDelegate) {
+ public void addTouchDelegate(final TouchDelegate touchDelegate) {
mTouchDelegates.add(touchDelegate);
}
@@ -42,7 +42,7 @@ public class TouchDelegateGroup extends TouchDelegate {
}
@Override
- public boolean onTouchEvent(@NonNull final MotionEvent event) {
+ public boolean onTouchEvent(final MotionEvent event) {
if (!mEnabled)
return false;
diff --git a/app/src/main/java/com/wireguard/config/Attribute.java b/app/src/main/java/com/wireguard/config/Attribute.java
index bd9fa05d..e8b731b5 100644
--- a/app/src/main/java/com/wireguard/config/Attribute.java
+++ b/app/src/main/java/com/wireguard/config/Attribute.java
@@ -6,6 +6,7 @@
package com.wireguard.config;
+import android.support.annotation.Nullable;
import android.text.TextUtils;
import java.util.HashMap;
@@ -59,13 +60,13 @@ public enum Attribute {
return KEY_MAP.get(SEPARATOR_PATTERN.split(line)[0].toLowerCase());
}
- public static String[] stringToList(final String string) {
+ public static String[] stringToList(@Nullable final String string) {
if (TextUtils.isEmpty(string))
return EMPTY_LIST;
return LIST_SEPARATOR_PATTERN.split(string.trim());
}
- public String composeWith(final Object value) {
+ public String composeWith(@Nullable final Object value) {
return String.format("%s = %s%n", token, value);
}
@@ -77,11 +78,13 @@ public enum Attribute {
return String.format("%s = %s%n", token, iterableToString(value));
}
+ @Nullable
public String parse(final CharSequence line) {
final Matcher matcher = pattern.matcher(line);
return matcher.matches() ? matcher.group(1) : null;
}
+ @Nullable
public String[] parseList(final CharSequence line) {
final Matcher matcher = pattern.matcher(line);
return matcher.matches() ? stringToList(matcher.group(1)) : null;
diff --git a/app/src/main/java/com/wireguard/config/Config.java b/app/src/main/java/com/wireguard/config/Config.java
index 62ba252c..0599dec3 100644
--- a/app/src/main/java/com/wireguard/config/Config.java
+++ b/app/src/main/java/com/wireguard/config/Config.java
@@ -12,6 +12,7 @@ import android.databinding.ObservableArrayList;
import android.databinding.ObservableList;
import android.os.Parcel;
import android.os.Parcelable;
+import android.support.annotation.Nullable;
import com.android.databinding.library.baseAdapters.BR;
@@ -96,13 +97,19 @@ public class Config {
return new Observable[size];
}
};
- private String name;
- private Interface.Observable observableInterface;
- private ObservableList<Peer.Observable> observablePeers;
+ @Nullable private String name;
+ private final Interface.Observable observableInterface;
+ private final ObservableList<Peer.Observable> observablePeers;
- public Observable(final Config parent, final String name) {
+ public Observable(@Nullable final Config parent, @Nullable final String name) {
this.name = name;
- loadData(parent);
+
+ observableInterface = new Interface.Observable(parent == null ? null : parent.interfaceSection);
+ observablePeers = new ObservableArrayList<>();
+ if (parent != null) {
+ for (final Peer peer : parent.getPeers())
+ observablePeers.add(new Peer.Observable(peer));
+ }
}
private Observable(final Parcel in) {
@@ -144,15 +151,6 @@ public class Config {
return observablePeers;
}
- protected void loadData(final Config parent) {
- observableInterface = new Interface.Observable(parent == null ? null : parent.interfaceSection);
- observablePeers = new ObservableArrayList<>();
- if (parent != null) {
- for (final Peer peer : parent.getPeers())
- observablePeers.add(new Peer.Observable(peer));
- }
- }
-
public void setName(final String name) {
this.name = name;
notifyPropertyChanged(BR.name);
diff --git a/app/src/main/java/com/wireguard/config/InetAddresses.java b/app/src/main/java/com/wireguard/config/InetAddresses.java
index b943f03e..3cc84b01 100644
--- a/app/src/main/java/com/wireguard/config/InetAddresses.java
+++ b/app/src/main/java/com/wireguard/config/InetAddresses.java
@@ -6,7 +6,6 @@
package com.wireguard.config;
-import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import java.lang.reflect.InvocationTargetException;
@@ -29,7 +28,6 @@ public final class InetAddresses {
// Prevent instantiation.
}
- @NonNull
public static InetAddress parse(@Nullable final String address) {
if (address == null || address.isEmpty())
throw new IllegalArgumentException("Empty address");
diff --git a/app/src/main/java/com/wireguard/config/InetNetwork.java b/app/src/main/java/com/wireguard/config/InetNetwork.java
index 6f1be914..8f434753 100644
--- a/app/src/main/java/com/wireguard/config/InetNetwork.java
+++ b/app/src/main/java/com/wireguard/config/InetNetwork.java
@@ -6,8 +6,6 @@
package com.wireguard.config;
-import android.support.annotation.NonNull;
-
import java.net.Inet4Address;
import java.net.InetAddress;
import java.util.Objects;
@@ -16,7 +14,7 @@ public class InetNetwork {
private final InetAddress address;
private final int mask;
- public InetNetwork(@NonNull final String input) {
+ public InetNetwork(final String input) {
final int slash = input.lastIndexOf('/');
final int rawMask;
final String rawAddress;
@@ -40,7 +38,6 @@ public class InetNetwork {
return Objects.equals(address, other.address) && mask == other.mask;
}
- @NonNull
public InetAddress getAddress() {
return address;
}
diff --git a/app/src/main/java/com/wireguard/config/Interface.java b/app/src/main/java/com/wireguard/config/Interface.java
index 3f72e812..99336ae4 100644
--- a/app/src/main/java/com/wireguard/config/Interface.java
+++ b/app/src/main/java/com/wireguard/config/Interface.java
@@ -10,6 +10,7 @@ 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.BR;
import com.wireguard.crypto.Keypair;
@@ -27,7 +28,7 @@ public class Interface {
private final List<InetNetwork> addressList;
private final List<InetAddress> dnsList;
private final List<String> excludedApplications;
- private Keypair keypair;
+ @Nullable private Keypair keypair;
private int listenPort;
private int mtu;
@@ -37,7 +38,7 @@ public class Interface {
excludedApplications = new ArrayList<>();
}
- private void addAddresses(final String[] addresses) {
+ private void addAddresses(@Nullable final String[] addresses) {
if (addresses != null && addresses.length > 0) {
for (final String addr : addresses) {
if (addr.isEmpty())
@@ -47,7 +48,7 @@ public class Interface {
}
}
- private void addDnses(final String[] dnses) {
+ private void addDnses(@Nullable final String[] dnses) {
if (dnses != null && dnses.length > 0) {
for (final String dns : dnses) {
dnsList.add(InetAddresses.parse(dns));
@@ -55,12 +56,13 @@ public class Interface {
}
}
- private void addExcludedApplications(final String[] applications) {
+ private void addExcludedApplications(@Nullable final String[] applications) {
if (applications != null && applications.length > 0) {
excludedApplications.addAll(Arrays.asList(applications));
}
}
+ @Nullable
private String getAddressString() {
if (addressList.isEmpty())
return null;
@@ -71,6 +73,7 @@ public class Interface {
return addressList.toArray(new InetNetwork[addressList.size()]);
}
+ @Nullable
private String getDnsString() {
if (dnsList.isEmpty())
return null;
@@ -88,6 +91,7 @@ public class Interface {
return dnsList.toArray(new InetAddress[dnsList.size()]);
}
+ @Nullable
private String getExcludedApplicationsString() {
if (excludedApplications.isEmpty())
return null;
@@ -102,6 +106,7 @@ public class Interface {
return listenPort;
}
+ @Nullable
private String getListenPortString() {
if (listenPort == 0)
return null;
@@ -112,18 +117,21 @@ public class Interface {
return mtu;
}
+ @Nullable
private String getMtuString() {
if (mtu == 0)
return null;
return Integer.toString(mtu);
}
+ @Nullable
public String getPrivateKey() {
if (keypair == null)
return null;
return keypair.getPrivateKey();
}
+ @Nullable
public String getPublicKey() {
if (keypair == null)
return null;
@@ -156,17 +164,17 @@ public class Interface {
}
}
- private void setAddressString(final String addressString) {
+ private void setAddressString(@Nullable final String addressString) {
addressList.clear();
addAddresses(Attribute.stringToList(addressString));
}
- private void setDnsString(final String dnsString) {
+ private void setDnsString(@Nullable final String dnsString) {
dnsList.clear();
addDnses(Attribute.stringToList(dnsString));
}
- private void setExcludedApplicationsString(final String applicationsString) {
+ private void setExcludedApplicationsString(@Nullable final String applicationsString) {
excludedApplications.clear();
addExcludedApplications(Attribute.stringToList(applicationsString));
}
@@ -175,7 +183,7 @@ public class Interface {
this.listenPort = listenPort;
}
- private void setListenPortString(final String port) {
+ private void setListenPortString(@Nullable final String port) {
if (port != null && !port.isEmpty())
setListenPort(Integer.parseInt(port, 10));
else
@@ -186,14 +194,14 @@ public class Interface {
this.mtu = mtu;
}
- private void setMtuString(final String mtu) {
+ private void setMtuString(@Nullable final String mtu) {
if (mtu != null && !mtu.isEmpty())
setMtu(Integer.parseInt(mtu, 10));
else
setMtu(0);
}
- private void setPrivateKey(String privateKey) {
+ private void setPrivateKey(@Nullable String privateKey) {
if (privateKey != null && privateKey.isEmpty())
privateKey = null;
keypair = privateKey == null ? null : new Keypair(privateKey);
@@ -229,15 +237,15 @@ public class Interface {
return new Observable[size];
}
};
- private String addresses;
- private String dnses;
- private String excludedApplications;
- private String listenPort;
- private String mtu;
- private String privateKey;
- private String publicKey;
-
- public Observable(final Interface parent) {
+ @Nullable private String addresses;
+ @Nullable private String dnses;
+ @Nullable private String excludedApplications;
+ @Nullable private String listenPort;
+ @Nullable private String mtu;
+ @Nullable private String privateKey;
+ @Nullable private String publicKey;
+
+ public Observable(@Nullable final Interface parent) {
if (parent != null)
loadData(parent);
}
@@ -276,16 +284,19 @@ public class Interface {
notifyPropertyChanged(BR.publicKey);
}
+ @Nullable
@Bindable
public String getAddresses() {
return addresses;
}
+ @Nullable
@Bindable
public String getDnses() {
return dnses;
}
+ @Nullable
@Bindable
public String getExcludedApplications() {
return excludedApplications;
@@ -296,21 +307,25 @@ public class Interface {
return Attribute.stringToList(excludedApplications).length;
}
+ @Nullable
@Bindable
public String getListenPort() {
return listenPort;
}
+ @Nullable
@Bindable
public String getMtu() {
return mtu;
}
+ @Nullable
@Bindable
public String getPrivateKey() {
return privateKey;
}
+ @Nullable
@Bindable
public String getPublicKey() {
return publicKey;
diff --git a/app/src/main/java/com/wireguard/config/Peer.java b/app/src/main/java/com/wireguard/config/Peer.java
index 371072de..60fe5c82 100644
--- a/app/src/main/java/com/wireguard/config/Peer.java
+++ b/app/src/main/java/com/wireguard/config/Peer.java
@@ -10,6 +10,7 @@ import android.databinding.BaseObservable;
import android.databinding.Bindable;
import android.os.Parcel;
import android.os.Parcelable;
+import android.support.annotation.Nullable;
import com.android.databinding.library.baseAdapters.BR;
import com.wireguard.crypto.KeyEncoding;
@@ -34,16 +35,16 @@ import java9.lang.Iterables;
public class Peer {
private final List<InetNetwork> allowedIPsList;
- private InetSocketAddress endpoint;
+ @Nullable private InetSocketAddress endpoint;
private int persistentKeepalive;
- private String preSharedKey;
- private String publicKey;
+ @Nullable private String preSharedKey;
+ @Nullable private String publicKey;
public Peer() {
allowedIPsList = new ArrayList<>();
}
- private void addAllowedIPs(final String[] allowedIPs) {
+ private void addAllowedIPs(@Nullable final String[] allowedIPs) {
if (allowedIPs != null && allowedIPs.length > 0) {
for (final String allowedIP : allowedIPs) {
allowedIPsList.add(new InetNetwork(allowedIP));
@@ -55,16 +56,19 @@ public class Peer {
return allowedIPsList.toArray(new InetNetwork[allowedIPsList.size()]);
}
+ @Nullable
private String getAllowedIPsString() {
if (allowedIPsList.isEmpty())
return null;
return Attribute.iterableToString(allowedIPsList);
}
+ @Nullable
public InetSocketAddress getEndpoint() {
return endpoint;
}
+ @Nullable
private String getEndpointString() {
if (endpoint == null)
return null;
@@ -75,16 +79,19 @@ public class Peer {
return persistentKeepalive;
}
+ @Nullable
private String getPersistentKeepaliveString() {
if (persistentKeepalive == 0)
return null;
return Integer.valueOf(persistentKeepalive).toString();
}
+ @Nullable
public String getPreSharedKey() {
return preSharedKey;
}
+ @Nullable
public String getPublicKey() {
return publicKey;
}
@@ -130,16 +137,16 @@ public class Peer {
}
}
- private void setAllowedIPsString(final String allowedIPsString) {
+ private void setAllowedIPsString(@Nullable final String allowedIPsString) {
allowedIPsList.clear();
addAllowedIPs(Attribute.stringToList(allowedIPsString));
}
- private void setEndpoint(final InetSocketAddress endpoint) {
+ private void setEndpoint(@Nullable final InetSocketAddress endpoint) {
this.endpoint = endpoint;
}
- private void setEndpointString(final String 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)
@@ -160,14 +167,14 @@ public class Peer {
this.persistentKeepalive = persistentKeepalive;
}
- private void setPersistentKeepaliveString(final String persistentKeepalive) {
+ private void setPersistentKeepaliveString(@Nullable final String persistentKeepalive) {
if (persistentKeepalive != null && !persistentKeepalive.isEmpty())
setPersistentKeepalive(Integer.parseInt(persistentKeepalive, 10));
else
setPersistentKeepalive(0);
}
- private void setPreSharedKey(String preSharedKey) {
+ private void setPreSharedKey(@Nullable String preSharedKey) {
if (preSharedKey != null && preSharedKey.isEmpty())
preSharedKey = null;
if (preSharedKey != null)
@@ -175,7 +182,7 @@ public class Peer {
this.preSharedKey = preSharedKey;
}
- private void setPublicKey(String publicKey) {
+ private void setPublicKey(@Nullable String publicKey) {
if (publicKey != null && publicKey.isEmpty())
publicKey = null;
if (publicKey != null)
@@ -211,12 +218,12 @@ public class Peer {
return new Observable[size];
}
};
- private String allowedIPs;
- private String endpoint;
- private String persistentKeepalive;
- private String preSharedKey;
- private String publicKey;
- private List<String> interfaceDNSRoutes;
+ @Nullable private String allowedIPs;
+ @Nullable private String endpoint;
+ @Nullable private String persistentKeepalive;
+ @Nullable private String preSharedKey;
+ @Nullable private String publicKey;
+ private final List<String> interfaceDNSRoutes = new ArrayList<>();
private int numSiblings;
public Observable(final Peer parent) {
@@ -230,7 +237,6 @@ public class Peer {
preSharedKey = in.readString();
publicKey = in.readString();
numSiblings = in.readInt();
- interfaceDNSRoutes = new ArrayList<>();
in.readStringList(interfaceDNSRoutes);
}
@@ -284,27 +290,27 @@ public class Peer {
return numSiblings == 0 && Arrays.asList(Attribute.stringToList(allowedIPs)).containsAll(DEFAULT_ROUTE_MOD_RFC1918_V4);
}
- @Bindable
+ @Bindable @Nullable
public String getAllowedIPs() {
return allowedIPs;
}
- @Bindable
+ @Bindable @Nullable
public String getEndpoint() {
return endpoint;
}
- @Bindable
+ @Bindable @Nullable
public String getPersistentKeepalive() {
return persistentKeepalive;
}
- @Bindable
+ @Bindable @Nullable
public String getPreSharedKey() {
return preSharedKey;
}
- @Bindable
+ @Bindable @Nullable
public String getPublicKey() {
return publicKey;
}
@@ -315,7 +321,6 @@ public class Peer {
persistentKeepalive = parent.getPersistentKeepaliveString();
preSharedKey = parent.getPreSharedKey();
publicKey = parent.getPublicKey();
- interfaceDNSRoutes = new ArrayList<>();
}
public void setAllowedIPs(final String allowedIPs) {
diff --git a/app/src/main/java/com/wireguard/crypto/Curve25519.java b/app/src/main/java/com/wireguard/crypto/Curve25519.java
index a47db7de..d279f2ae 100644
--- a/app/src/main/java/com/wireguard/crypto/Curve25519.java
+++ b/app/src/main/java/com/wireguard/crypto/Curve25519.java
@@ -5,6 +5,8 @@
package com.wireguard.crypto;
+import android.support.annotation.Nullable;
+
import java.util.Arrays;
/**
@@ -93,7 +95,7 @@ public final class Curve25519 {
* if the base point of the curve should be used.
*/
public static void eval(final byte[] result, final int offset,
- final byte[] privateKey, final byte[] publicKey) {
+ final byte[] privateKey, @Nullable final byte[] publicKey) {
final Curve25519 state = new Curve25519();
try {
// Unpack the public key value. If null, use 9 as the base point.
diff --git a/app/src/main/java/com/wireguard/util/NonNullForAll.java b/app/src/main/java/com/wireguard/util/NonNullForAll.java
new file mode 100644
index 00000000..f74cb616
--- /dev/null
+++ b/app/src/main/java/com/wireguard/util/NonNullForAll.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright © 2018 Eric Kuck <eric@bluelinelabs.com>.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.wireguard.util;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+import javax.annotation.Nonnull;
+import javax.annotation.meta.TypeQualifierDefault;
+
+/**
+ * This annotation can be applied to a package, class or method to indicate that all
+ * class fields and method parameters and return values in that element are nonnull
+ * by default unless overridden.
+ */
+@Documented
+@Nonnull
+@TypeQualifierDefault({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface NonNullForAll { }