JDK 8 support for Android platform.
This commit is contained in:
		
							
								
								
									
										5
									
								
								gradle/.idea/misc.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										5
									
								
								gradle/.idea/misc.xml
									
									
									
										generated
									
									
									
								
							@@ -1,9 +1,14 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<project version="4">
 | 
			
		||||
  <component name="FrameworkDetectionExcludesConfiguration">
 | 
			
		||||
    <type id="jpa" />
 | 
			
		||||
    <type id="web" />
 | 
			
		||||
  </component>
 | 
			
		||||
  <component name="MavenProjectsManager">
 | 
			
		||||
    <option name="originalFiles">
 | 
			
		||||
      <list>
 | 
			
		||||
        <option value="$PROJECT_DIR$/../../opal/pom.xml" />
 | 
			
		||||
        <option value="$PROJECT_DIR$/../../pom.xml" />
 | 
			
		||||
      </list>
 | 
			
		||||
    </option>
 | 
			
		||||
  </component>
 | 
			
		||||
 
 | 
			
		||||
@@ -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' }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -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." )
 | 
			
		||||
}*/
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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'
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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 ))
 | 
			
		||||
 
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
//==============================================================================
 | 
			
		||||
 | 
			
		||||
package com.lyndir.masterpassword;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author lhunath, 2018-06-10
 | 
			
		||||
 */
 | 
			
		||||
public class MPConstants {
 | 
			
		||||
 | 
			
		||||
    public static final int MS_PER_S = 1000;
 | 
			
		||||
}
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
//==============================================================================
 | 
			
		||||
 | 
			
		||||
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<Boolean> testFuture;
 | 
			
		||||
    @Nullable
 | 
			
		||||
    private Runnable                  action;
 | 
			
		||||
    private Set<String>               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<Boolean>() {
 | 
			
		||||
            @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 );
 | 
			
		||||
        } );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -253,15 +253,6 @@
 | 
			
		||||
            </LinearLayout>
 | 
			
		||||
        </LinearLayout>
 | 
			
		||||
 | 
			
		||||
        <Button
 | 
			
		||||
                android:layout_width="match_parent"
 | 
			
		||||
                android:layout_height="wrap_content"
 | 
			
		||||
                android:layout_marginTop="8dp"
 | 
			
		||||
                android:textSize="16sp"
 | 
			
		||||
                android:text="@string/btn_tests"
 | 
			
		||||
                android:onClick="integrityTests"
 | 
			
		||||
                android:background="@android:color/transparent" />
 | 
			
		||||
 | 
			
		||||
        <View
 | 
			
		||||
                android:layout_width="1dp"
 | 
			
		||||
                android:layout_height="0dp"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,77 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
            xmlns:tools="http://schemas.android.com/tools"
 | 
			
		||||
            android:layout_width="match_parent"
 | 
			
		||||
            android:layout_height="match_parent"
 | 
			
		||||
            android:fillViewport="true">
 | 
			
		||||
 | 
			
		||||
    <LinearLayout
 | 
			
		||||
            android:layout_width="match_parent"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            android:padding="20dp"
 | 
			
		||||
            android:orientation="vertical"
 | 
			
		||||
            android:gravity="center">
 | 
			
		||||
 | 
			
		||||
        <View
 | 
			
		||||
                android:layout_width="1dp"
 | 
			
		||||
                android:layout_height="0dp"
 | 
			
		||||
                android:layout_weight="1" />
 | 
			
		||||
 | 
			
		||||
        <ImageView
 | 
			
		||||
                android:layout_width="wrap_content"
 | 
			
		||||
                android:layout_height="wrap_content"
 | 
			
		||||
                android:importantForAccessibility="no"
 | 
			
		||||
                android:src="@drawable/img_stats" />
 | 
			
		||||
 | 
			
		||||
        <ProgressBar
 | 
			
		||||
                android:id="@+id/progressView"
 | 
			
		||||
                android:layout_width="match_parent"
 | 
			
		||||
                android:layout_height="wrap_content"
 | 
			
		||||
                android:layout_gravity="center"
 | 
			
		||||
                android:layout_margin="8dp"
 | 
			
		||||
                tools:max="100"
 | 
			
		||||
                tools:progress="80"
 | 
			
		||||
                style="?android:progressBarStyleHorizontal" />
 | 
			
		||||
 | 
			
		||||
        <TextView
 | 
			
		||||
                android:id="@+id/statusView"
 | 
			
		||||
                android:layout_width="match_parent"
 | 
			
		||||
                android:layout_height="wrap_content"
 | 
			
		||||
                android:labelFor="@id/sitePasswordField"
 | 
			
		||||
                android:gravity="center"
 | 
			
		||||
                android:background="@android:color/transparent"
 | 
			
		||||
                android:textSize="12sp"
 | 
			
		||||
                android:textColor="@android:color/tertiary_text_dark"
 | 
			
		||||
                android:text="@string/tests_testing" />
 | 
			
		||||
 | 
			
		||||
        <TextView
 | 
			
		||||
                android:id="@+id/logView"
 | 
			
		||||
                android:layout_width="match_parent"
 | 
			
		||||
                android:layout_height="0dp"
 | 
			
		||||
                android:layout_weight="1"
 | 
			
		||||
                android:layout_marginTop="20dp"
 | 
			
		||||
                android:gravity="bottom"
 | 
			
		||||
                android:background="@android:color/transparent"
 | 
			
		||||
                android:textIsSelectable="true"
 | 
			
		||||
                android:textSize="9sp"
 | 
			
		||||
                android:textColor="@android:color/tertiary_text_dark" />
 | 
			
		||||
 | 
			
		||||
        <Button
 | 
			
		||||
                android:id="@+id/actionButton"
 | 
			
		||||
                android:layout_width="match_parent"
 | 
			
		||||
                android:layout_height="wrap_content"
 | 
			
		||||
                android:layout_marginTop="8dp"
 | 
			
		||||
                android:enabled="false"
 | 
			
		||||
                android:text="@string/tests_btn_testing"
 | 
			
		||||
                android:onClick="onAction" />
 | 
			
		||||
 | 
			
		||||
        <CheckBox
 | 
			
		||||
                android:id="@+id/nativeKDFField"
 | 
			
		||||
                android:layout_width="match_parent"
 | 
			
		||||
                android:layout_height="wrap_content"
 | 
			
		||||
                android:textSize="12sp"
 | 
			
		||||
                android:textColor="@android:color/tertiary_text_dark"
 | 
			
		||||
                android:text="@string/nativeKDF" />
 | 
			
		||||
    </LinearLayout>
 | 
			
		||||
 | 
			
		||||
</ScrollView>
 | 
			
		||||
@@ -9,7 +9,7 @@ configurations {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dependencies {
 | 
			
		||||
    implementation group: 'com.lyndir.lhunath.opal', name: 'opal-system', version: '1.7-p1'
 | 
			
		||||
    implementation group: 'com.lyndir.lhunath.opal', name: 'opal-system', version: '1.7-p2'
 | 
			
		||||
 | 
			
		||||
    api group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: '2.9.5'
 | 
			
		||||
    api group: 'org.jetbrains', name: 'annotations', version: '13.0'
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@ description = 'Master Password GUI'
 | 
			
		||||
mainClassName = 'com.lyndir.masterpassword.gui.GUI'
 | 
			
		||||
 | 
			
		||||
dependencies {
 | 
			
		||||
    implementation group: 'com.lyndir.lhunath.opal', name: 'opal-system', version: '1.7-p1'
 | 
			
		||||
    implementation group: 'com.lyndir.lhunath.opal', name: 'opal-system', version: '1.7-p2'
 | 
			
		||||
    implementation group: 'ch.qos.logback', name: 'logback-classic', version: '1.1.2'
 | 
			
		||||
    implementation group: 'com.yuvimasory', name: 'orange-extensions', version: '1.3.0'
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,7 @@
 | 
			
		||||
package com.lyndir.masterpassword.gui;
 | 
			
		||||
 | 
			
		||||
import com.lyndir.lhunath.opal.system.util.ConversionUtils;
 | 
			
		||||
import com.lyndir.masterpassword.model.MPConstant;
 | 
			
		||||
import com.lyndir.masterpassword.model.MPConstants;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -35,6 +35,6 @@ public class Config {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean checkForUpdates() {
 | 
			
		||||
        return ConversionUtils.toBoolean( System.getenv( MPConstant.env_checkUpdates ) ).orElse( true );
 | 
			
		||||
        return ConversionUtils.toBoolean( System.getenv( MPConstants.env_checkUpdates ) ).orElse( true );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@ plugins {
 | 
			
		||||
description = 'Master Password Site Model'
 | 
			
		||||
 | 
			
		||||
dependencies {
 | 
			
		||||
    implementation group: 'com.lyndir.lhunath.opal', name: 'opal-system', version: '1.7-p1'
 | 
			
		||||
    implementation group: 'com.lyndir.lhunath.opal', name: 'opal-system', version: '1.7-p2'
 | 
			
		||||
    implementation group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.9.5'
 | 
			
		||||
 | 
			
		||||
    api project( ':masterpassword-algorithm' )
 | 
			
		||||
 
 | 
			
		||||
@@ -25,7 +25,7 @@ import org.joda.time.format.ISODateTimeFormat;
 | 
			
		||||
/**
 | 
			
		||||
 * @author lhunath, 2016-10-29
 | 
			
		||||
 */
 | 
			
		||||
public final class MPConstant {
 | 
			
		||||
public final class MPConstants {
 | 
			
		||||
 | 
			
		||||
    /* Environment */
 | 
			
		||||
 | 
			
		||||
@@ -40,7 +40,5 @@ public final class MPConstant {
 | 
			
		||||
 | 
			
		||||
    /* Algorithm */
 | 
			
		||||
 | 
			
		||||
    public static final int MS_PER_S = 1000;
 | 
			
		||||
 | 
			
		||||
    public static final DateTimeFormatter dateTimeFormatter = ISODateTimeFormat.dateTimeNoMillis().withZoneUTC();
 | 
			
		||||
}
 | 
			
		||||
@@ -45,7 +45,7 @@ public class MPFileUserManager extends MPUserManager<MPFileUser> {
 | 
			
		||||
    private static final MPFileUserManager instance;
 | 
			
		||||
 | 
			
		||||
    static {
 | 
			
		||||
        String rcDir = System.getenv( MPConstant.env_rcDir );
 | 
			
		||||
        String rcDir = System.getenv( MPConstants.env_rcDir );
 | 
			
		||||
        if (rcDir != null)
 | 
			
		||||
            instance = create( new File( rcDir ) );
 | 
			
		||||
        else
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,7 @@ import static com.lyndir.lhunath.opal.system.util.StringUtils.*;
 | 
			
		||||
 | 
			
		||||
import com.lyndir.masterpassword.MPAlgorithmException;
 | 
			
		||||
import com.lyndir.masterpassword.MPKeyUnavailableException;
 | 
			
		||||
import com.lyndir.masterpassword.model.MPConstant;
 | 
			
		||||
import com.lyndir.masterpassword.model.MPConstants;
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import org.joda.time.Instant;
 | 
			
		||||
 | 
			
		||||
@@ -46,7 +46,7 @@ public class MPFlatMarshaller implements MPMarshaller {
 | 
			
		||||
        content.append( "# \n" );
 | 
			
		||||
        content.append( "##\n" );
 | 
			
		||||
        content.append( "# Format: " ).append( FORMAT ).append( '\n' );
 | 
			
		||||
        content.append( "# Date: " ).append( MPConstant.dateTimeFormatter.print( new Instant() ) ).append( '\n' );
 | 
			
		||||
        content.append( "# Date: " ).append( MPConstants.dateTimeFormatter.print( new Instant() ) ).append( '\n' );
 | 
			
		||||
        content.append( "# User Name: " ).append( user.getFullName() ).append( '\n' );
 | 
			
		||||
        content.append( "# Full Name: " ).append( user.getFullName() ).append( '\n' );
 | 
			
		||||
        content.append( "# Avatar: " ).append( user.getAvatar() ).append( '\n' );
 | 
			
		||||
@@ -68,7 +68,7 @@ public class MPFlatMarshaller implements MPMarshaller {
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            content.append( strf( "%s  %8d  %8s  %25s\t%25s\t%s\n", //
 | 
			
		||||
                                  MPConstant.dateTimeFormatter.print( site.getLastUsed() ), // lastUsed
 | 
			
		||||
                                  MPConstants.dateTimeFormatter.print( site.getLastUsed() ), // lastUsed
 | 
			
		||||
                                  site.getUses(), // uses
 | 
			
		||||
                                  strf( "%d:%d:%d", //
 | 
			
		||||
                                        site.getResultType().getType(), // type
 | 
			
		||||
 
 | 
			
		||||
@@ -25,7 +25,7 @@ import com.lyndir.lhunath.opal.system.CodeUtils;
 | 
			
		||||
import com.lyndir.lhunath.opal.system.logging.Logger;
 | 
			
		||||
import com.lyndir.lhunath.opal.system.util.ConversionUtils;
 | 
			
		||||
import com.lyndir.masterpassword.*;
 | 
			
		||||
import com.lyndir.masterpassword.model.MPConstant;
 | 
			
		||||
import com.lyndir.masterpassword.model.MPConstants;
 | 
			
		||||
import com.lyndir.masterpassword.model.MPIncorrectMasterPasswordException;
 | 
			
		||||
import java.io.*;
 | 
			
		||||
import java.util.regex.Matcher;
 | 
			
		||||
@@ -123,7 +123,7 @@ public class MPFlatUnmarshaller implements MPUnmarshaller {
 | 
			
		||||
                                               MPResultType.forType( ConversionUtils.toIntegerNN( siteMatcher.group( 3 ) ) ),
 | 
			
		||||
                                               clearContent? null: siteMatcher.group( 6 ),
 | 
			
		||||
                                               null, null, null, ConversionUtils.toIntegerNN( siteMatcher.group( 2 ) ),
 | 
			
		||||
                                               MPConstant.dateTimeFormatter.parseDateTime( siteMatcher.group( 1 ) ).toInstant() );
 | 
			
		||||
                                               MPConstants.dateTimeFormatter.parseDateTime( siteMatcher.group( 1 ) ).toInstant() );
 | 
			
		||||
                        if (clearContent)
 | 
			
		||||
                            site.setSitePassword( site.getResultType(), siteMatcher.group( 6 ) );
 | 
			
		||||
                        break;
 | 
			
		||||
@@ -137,7 +137,7 @@ public class MPFlatUnmarshaller implements MPUnmarshaller {
 | 
			
		||||
                                               clearContent? null: siteMatcher.group( 8 ),
 | 
			
		||||
                                               MPResultType.GeneratedName, clearContent? null: siteMatcher.group( 6 ), null,
 | 
			
		||||
                                               ConversionUtils.toIntegerNN( siteMatcher.group( 2 ) ),
 | 
			
		||||
                                               MPConstant.dateTimeFormatter.parseDateTime( siteMatcher.group( 1 ) ).toInstant() );
 | 
			
		||||
                                               MPConstants.dateTimeFormatter.parseDateTime( siteMatcher.group( 1 ) ).toInstant() );
 | 
			
		||||
                        if (clearContent) {
 | 
			
		||||
                            site.setSitePassword( site.getResultType(), siteMatcher.group( 8 ) );
 | 
			
		||||
                            site.setLoginName( MPResultType.StoredPersonal, siteMatcher.group( 6 ) );
 | 
			
		||||
 
 | 
			
		||||
@@ -25,7 +25,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 | 
			
		||||
import com.google.common.primitives.UnsignedInteger;
 | 
			
		||||
import com.lyndir.lhunath.opal.system.CodeUtils;
 | 
			
		||||
import com.lyndir.masterpassword.*;
 | 
			
		||||
import com.lyndir.masterpassword.model.MPConstant;
 | 
			
		||||
import com.lyndir.masterpassword.model.MPConstants;
 | 
			
		||||
import com.lyndir.masterpassword.model.MPIncorrectMasterPasswordException;
 | 
			
		||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 | 
			
		||||
import java.util.LinkedHashMap;
 | 
			
		||||
@@ -54,14 +54,14 @@ public class MPJSONFile extends MPJSONAnyObject {
 | 
			
		||||
            export = new Export();
 | 
			
		||||
        export.format = 1;
 | 
			
		||||
        export.redacted = modelUser.getContentMode().isRedacted();
 | 
			
		||||
        export.date = MPConstant.dateTimeFormatter.print( new Instant() );
 | 
			
		||||
        export.date = MPConstants.dateTimeFormatter.print( new Instant() );
 | 
			
		||||
 | 
			
		||||
        // Section: "user"
 | 
			
		||||
        if (user == null)
 | 
			
		||||
            user = new User();
 | 
			
		||||
        user.avatar = modelUser.getAvatar();
 | 
			
		||||
        user.full_name = modelUser.getFullName();
 | 
			
		||||
        user.last_used = MPConstant.dateTimeFormatter.print( modelUser.getLastUsed() );
 | 
			
		||||
        user.last_used = MPConstants.dateTimeFormatter.print( modelUser.getLastUsed() );
 | 
			
		||||
        user.key_id = modelUser.exportKeyID();
 | 
			
		||||
        user.algorithm = modelUser.getAlgorithm().version();
 | 
			
		||||
        user.default_type = modelUser.getDefaultType();
 | 
			
		||||
@@ -96,7 +96,7 @@ public class MPJSONFile extends MPJSONAnyObject {
 | 
			
		||||
            site.login_type = modelSite.getLoginType();
 | 
			
		||||
 | 
			
		||||
            site.uses = modelSite.getUses();
 | 
			
		||||
            site.last_used = MPConstant.dateTimeFormatter.print( modelSite.getLastUsed() );
 | 
			
		||||
            site.last_used = MPConstants.dateTimeFormatter.print( modelSite.getLastUsed() );
 | 
			
		||||
 | 
			
		||||
            if (site._ext_mpw == null)
 | 
			
		||||
                site._ext_mpw = new Site.Ext();
 | 
			
		||||
@@ -141,7 +141,7 @@ public class MPJSONFile extends MPJSONAnyObject {
 | 
			
		||||
        MPFileUser model = new MPFileUser(
 | 
			
		||||
                user.full_name, CodeUtils.decodeHex( user.key_id ), algorithm, user.avatar,
 | 
			
		||||
                (user.default_type != null)? user.default_type: algorithm.mpw_default_result_type(),
 | 
			
		||||
                (user.last_used != null)? MPConstant.dateTimeFormatter.parseDateTime( user.last_used ): new Instant(),
 | 
			
		||||
                (user.last_used != null)? MPConstants.dateTimeFormatter.parseDateTime( user.last_used ): new Instant(),
 | 
			
		||||
                MPMarshalFormat.JSON, export.redacted? MPMarshaller.ContentMode.PROTECTED: MPMarshaller.ContentMode.VISIBLE );
 | 
			
		||||
        model.setJSON( this );
 | 
			
		||||
        if (masterPassword != null)
 | 
			
		||||
@@ -155,7 +155,7 @@ public class MPJSONFile extends MPJSONAnyObject {
 | 
			
		||||
                    export.redacted? fileSite.password: null,
 | 
			
		||||
                    fileSite.login_type, export.redacted? fileSite.login_name: null,
 | 
			
		||||
                    (fileSite._ext_mpw != null)? fileSite._ext_mpw.url: null, fileSite.uses,
 | 
			
		||||
                    (fileSite.last_used != null)? MPConstant.dateTimeFormatter.parseDateTime( fileSite.last_used ): new Instant() );
 | 
			
		||||
                    (fileSite.last_used != null)? MPConstants.dateTimeFormatter.parseDateTime( fileSite.last_used ): new Instant() );
 | 
			
		||||
 | 
			
		||||
            if (!export.redacted) {
 | 
			
		||||
                if (fileSite.password != null)
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@ plugins {
 | 
			
		||||
description = 'Master Password Test Suite'
 | 
			
		||||
 | 
			
		||||
dependencies {
 | 
			
		||||
    implementation group: 'com.lyndir.lhunath.opal', name: 'opal-system', version: '1.7-p1'
 | 
			
		||||
    implementation group: 'com.lyndir.lhunath.opal', name: 'opal-system', version: '1.7-p2'
 | 
			
		||||
 | 
			
		||||
    compile project( ':masterpassword-algorithm' )
 | 
			
		||||
    compile project( ':masterpassword-model' )
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user