From 9a564ff35ecbfab4724a7fe73649e73095e0bb05 Mon Sep 17 00:00:00 2001 From: Maarten Billemont Date: Sun, 10 Jun 2018 15:22:37 -0400 Subject: [PATCH] JDK 8 support for Android platform. --- gradle/.idea/misc.xml | 5 + gradle/build.gradle | 9 +- gradle/settings.gradle | 5 +- platform-android/build.gradle | 11 +- .../masterpassword/EmergencyActivity.java | 13 +- .../lyndir/masterpassword/MPConstants.java | 27 +++ .../lyndir/masterpassword/TestActivity.java | 168 ------------------ .../main/res/layout/activity_emergency.xml | 9 - .../src/main/res/layout/activity_test.xml | 77 -------- .../java/algorithm/build.gradle | 2 +- platform-independent/java/gui/build.gradle | 2 +- .../com/lyndir/masterpassword/gui/Config.java | 4 +- platform-independent/java/model/build.gradle | 2 +- .../{MPConstant.java => MPConstants.java} | 4 +- .../model/impl/MPFileUserManager.java | 2 +- .../model/impl/MPFlatMarshaller.java | 6 +- .../model/impl/MPFlatUnmarshaller.java | 6 +- .../masterpassword/model/impl/MPJSONFile.java | 12 +- platform-independent/java/tests/build.gradle | 2 +- 19 files changed, 67 insertions(+), 299 deletions(-) create mode 100644 platform-android/src/main/java/com/lyndir/masterpassword/MPConstants.java delete mode 100644 platform-android/src/main/java/com/lyndir/masterpassword/TestActivity.java delete mode 100644 platform-android/src/main/res/layout/activity_test.xml rename platform-independent/java/model/src/main/java/com/lyndir/masterpassword/model/{MPConstant.java => MPConstants.java} (95%) diff --git a/gradle/.idea/misc.xml b/gradle/.idea/misc.xml index b1631feb..2e7d1a63 100644 --- a/gradle/.idea/misc.xml +++ b/gradle/.idea/misc.xml @@ -1,9 +1,14 @@ + + + + diff --git a/gradle/build.gradle b/gradle/build.gradle index e5b23dcd..a7308505 100644 --- a/gradle/build.gradle +++ b/gradle/build.gradle @@ -4,11 +4,11 @@ allprojects { group = 'com.lyndir.masterpassword' version = 'GIT-SNAPSHOT' - tasks.withType(JavaCompile) { + tasks.withType( JavaCompile ) { sourceCompatibility = '1.8' targetCompatibility = '1.8' } - tasks.withType(FindBugs) { + tasks.withType( FindBugs ) { reports { xml.enabled false html.enabled true @@ -18,16 +18,19 @@ allprojects { buildscript { repositories { + google() jcenter() } dependencies { - classpath group: 'com.android.tools.build', name: 'gradle', version: '2.3.2' + classpath group: 'com.android.tools.build', name: 'gradle', version: '3.1.0' } } subprojects { repositories { + google() + jcenter() mavenCentral() maven { url 'http://maven.lyndir.com' } } diff --git a/gradle/settings.gradle b/gradle/settings.gradle index 0af73456..9b1008b8 100644 --- a/gradle/settings.gradle +++ b/gradle/settings.gradle @@ -19,12 +19,11 @@ include 'masterpassword-tests' project(':masterpassword-tests').projectDir = new File( '../platform-independent/java/tests' ) include 'masterpassword-gui' -project(':masterpassword-gui').projectDir = new File( '../platform-independent/gui-java' ) +project(':masterpassword-gui').projectDir = new File( '../platform-independent/java/gui' ) -/* if (local.containsKey('sdk.dir')) { include 'masterpassword-android' project(':masterpassword-android').projectDir = new File( '../platform-android' ) } else { logger.warn( "Skipping masterpassword-android since sdk.dir is not defined in local.properties." ) -}*/ +} diff --git a/platform-android/build.gradle b/platform-android/build.gradle index e814e3f8..b2b84e08 100644 --- a/platform-android/build.gradle +++ b/platform-android/build.gradle @@ -2,7 +2,7 @@ apply plugin: 'com.android.application' android { compileSdkVersion 25 - buildToolsVersion '25.0.3' + buildToolsVersion '27.0.3' compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 @@ -15,7 +15,6 @@ android { targetSdkVersion 25 versionCode 20501 versionName '2.5.1' - jackOptions.enabled true } // release with: STORE_PW=$(mpw masterpassword.keystore) KEY_PW_ANDROID=$(mpw masterpassword-android) gradle masterpassword-android:assembleRelease @@ -37,10 +36,10 @@ android { } dependencies { - compile project( ':masterpassword-algorithm' ) - compile project( ':masterpassword-tests' ) + api project( ':masterpassword-algorithm' ) + implementation group: 'com.lyndir.lhunath.opal', name: 'opal-system', version: '1.7-p2' - compile group: 'org.slf4j', name: 'slf4j-android', version: '1.7.13-underscore' - compile group: 'com.jakewharton', name: 'butterknife', version: '8.5.1' + implementation group: 'org.slf4j', name: 'slf4j-android', version: '1.7.13-underscore' + implementation group: 'com.jakewharton', name: 'butterknife', version: '8.5.1' annotationProcessor group: 'com.jakewharton', name: 'butterknife-compiler', version: '8.5.1' } diff --git a/platform-android/src/main/java/com/lyndir/masterpassword/EmergencyActivity.java b/platform-android/src/main/java/com/lyndir/masterpassword/EmergencyActivity.java index d88f5f09..a66a19c7 100644 --- a/platform-android/src/main/java/com/lyndir/masterpassword/EmergencyActivity.java +++ b/platform-android/src/main/java/com/lyndir/masterpassword/EmergencyActivity.java @@ -38,7 +38,6 @@ import com.google.common.primitives.UnsignedInteger; import com.google.common.util.concurrent.ListeningExecutorService; import com.google.common.util.concurrent.MoreExecutors; import com.lyndir.lhunath.opal.system.logging.Logger; -import com.lyndir.masterpassword.model.MPConstant; import java.text.MessageFormat; import java.util.*; import java.util.concurrent.Executors; @@ -51,7 +50,7 @@ public class EmergencyActivity extends Activity { private static final Logger logger = Logger.get( EmergencyActivity.class ); private static final ClipData EMPTY_CLIP = new ClipData( new ClipDescription( "", new String[0] ), new ClipData.Item( "" ) ); private static final int PASSWORD_NOTIFICATION = 0; - private static final int CLIPBOARD_CLEAR_DELAY = 20 /* s */ * MPConstant.MS_PER_S; + private static final int CLIPBOARD_CLEAR_DELAY = 20 /* s */ * MPConstants.MS_PER_S; private final Preferences preferences = Preferences.get( this ); private final ListeningExecutorService executor = MoreExecutors.listeningDecorator( @@ -321,23 +320,15 @@ public class EmergencyActivity extends Activity { sitePasswordField.setText( "" ); progressView.setVisibility( View.INVISIBLE ); } - catch (final RuntimeException e) { + catch (final MPAlgorithmException e) { sitePasswordField.setText( "" ); progressView.setVisibility( View.INVISIBLE ); logger.err( e, "While generating site password." ); - throw e; } } } ); } - public void integrityTests(final View view) { - if (masterKey != null) - masterKey = null; - - TestActivity.startNoSkip( this ); - } - public void copySitePassword(final View view) { final String currentSitePassword = sitePassword; if (TextUtils.isEmpty( currentSitePassword )) diff --git a/platform-android/src/main/java/com/lyndir/masterpassword/MPConstants.java b/platform-android/src/main/java/com/lyndir/masterpassword/MPConstants.java new file mode 100644 index 00000000..a7f5e4a1 --- /dev/null +++ b/platform-android/src/main/java/com/lyndir/masterpassword/MPConstants.java @@ -0,0 +1,27 @@ +//============================================================================== +// This file is part of Master Password. +// Copyright (c) 2011-2017, Maarten Billemont. +// +// Master Password is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Master Password is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You can find a copy of the GNU General Public License in the +// LICENSE file. Alternatively, see . +//============================================================================== + +package com.lyndir.masterpassword; + +/** + * @author lhunath, 2018-06-10 + */ +public class MPConstants { + + public static final int MS_PER_S = 1000; +} diff --git a/platform-android/src/main/java/com/lyndir/masterpassword/TestActivity.java b/platform-android/src/main/java/com/lyndir/masterpassword/TestActivity.java deleted file mode 100644 index 8283441f..00000000 --- a/platform-android/src/main/java/com/lyndir/masterpassword/TestActivity.java +++ /dev/null @@ -1,168 +0,0 @@ -//============================================================================== -// This file is part of Master Password. -// Copyright (c) 2011-2017, Maarten Billemont. -// -// Master Password is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Master Password is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You can find a copy of the GNU General Public License in the -// LICENSE file. Alternatively, see . -//============================================================================== - -package com.lyndir.masterpassword; - -import static com.lyndir.lhunath.opal.system.util.StringUtils.*; - -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.os.Bundle; -import android.view.View; -import android.widget.*; -import butterknife.BindView; -import butterknife.ButterKnife; -import com.google.common.util.concurrent.*; -import com.lyndir.lhunath.opal.system.logging.Logger; -import java.util.Objects; -import java.util.Set; -import java.util.concurrent.Executors; -import java.util.stream.Collectors; -import javax.annotation.Nullable; - - -@SuppressWarnings("PublicMethodNotExposedInInterface" /* IDEA-191044 */) -public class TestActivity extends Activity implements MPTestSuite.Listener { - - @SuppressWarnings("UnusedDeclaration") - private static final Logger logger = Logger.get( TestActivity.class ); - - private final Preferences preferences = Preferences.get( this ); - private final ListeningExecutorService backgroundExecutor = MoreExecutors.listeningDecorator( Executors.newSingleThreadExecutor() ); - private final ListeningExecutorService mainExecutor = MoreExecutors.listeningDecorator( new MainThreadExecutor() ); - - @BindView(R.id.progressView) - ProgressBar progressView; - - @BindView(R.id.statusView) - TextView statusView; - - @BindView(R.id.logView) - TextView logView; - - @BindView(R.id.actionButton) - Button actionButton; - - @BindView(R.id.nativeKDFField) - CheckBox nativeKDFField; - - private MPTestSuite testSuite; - private ListenableFuture testFuture; - @Nullable - private Runnable action; - private Set testNames; - - public static void startNoSkip(final Context context) { - context.startActivity( new Intent( context, TestActivity.class ) ); - } - - @Override - public void onCreate(@Nullable final Bundle savedInstanceState) { - super.onCreate( savedInstanceState ); - - setContentView( R.layout.activity_test ); - ButterKnife.bind( this ); - - nativeKDFField.setOnCheckedChangeListener( (buttonView, isChecked) -> { - preferences.setNativeKDFEnabled( isChecked ); - // TODO: MasterKey.setAllowNativeByDefault( isChecked ); - } ); - - try { - setStatus( 0, 0, null ); - testSuite = new MPTestSuite(); - testSuite.setListener( this ); - testNames = testSuite.getTests().getCases().stream() - .map( input -> (input == null)? null: input.identifier ) - .filter( Objects::nonNull ).collect( Collectors.toSet() ); - } - catch (final MPTestSuite.UnavailableException e) { - logger.err( e, "While loading test suite" ); - setStatus( R.string.tests_unavailable, R.string.tests_btn_unavailable, this::finish ); - } - } - - @Override - protected void onResume() { - super.onResume(); - - nativeKDFField.setChecked( preferences.isAllowNativeKDF() ); - - if (testFuture == null) - startTestSuite(); - } - - private void startTestSuite() { - if (testFuture != null) - testFuture.cancel( true ); - - // TODO: MasterKey.setAllowNativeByDefault( preferences.isAllowNativeKDF() ); - - setStatus( R.string.tests_testing, R.string.tests_btn_testing, null ); - Futures.addCallback( testFuture = backgroundExecutor.submit( testSuite ), new FutureCallback() { - @Override - public void onSuccess(@Nullable final Boolean result) { - if ((result != null) && result) - setStatus( R.string.tests_passed, R.string.tests_btn_passed, () -> { - preferences.setTestsPassed( testNames ); - finish(); - } ); - else - setStatus( R.string.tests_failed, R.string.tests_btn_failed, () -> startTestSuite() ); - } - - @Override - public void onFailure(final Throwable t) { - logger.err( t, "While running test suite" ); - setStatus( R.string.tests_failed, R.string.tests_btn_failed, () -> finish() ); - } - }, mainExecutor ); - } - - public void onAction(final View v) { - if (action != null) - action.run(); - } - - private void setStatus(final int statusId, final int buttonId, @Nullable final Runnable action) { - this.action = action; - - if (statusId == 0) - statusView.setText( null ); - else - statusView.setText( statusId ); - - if (buttonId == 0) - actionButton.setText( null ); - else - actionButton.setText( buttonId ); - actionButton.setEnabled( action != null ); - } - - @Override - public void progress(final int current, final int max, final String messageFormat, final Object... args) { - runOnUiThread( () -> { - logView.append( strf( "%n" + messageFormat, args ) ); - - progressView.setMax( max ); - progressView.setProgress( current ); - } ); - } -} - diff --git a/platform-android/src/main/res/layout/activity_emergency.xml b/platform-android/src/main/res/layout/activity_emergency.xml index 2c0fb79b..27209e88 100644 --- a/platform-android/src/main/res/layout/activity_emergency.xml +++ b/platform-android/src/main/res/layout/activity_emergency.xml @@ -253,15 +253,6 @@ -