Replace OpenPgpKeyPreference with compat version

This commit is contained in:
cketti 2018-05-21 04:05:41 +02:00
parent 6863c4ca27
commit 34e317a539
4 changed files with 24 additions and 344 deletions

View file

@ -25,7 +25,7 @@ import com.fsck.k9.ui.observe
import org.koin.android.architecture.ext.sharedViewModel
import org.koin.android.ext.android.inject
import org.openintents.openpgp.OpenPgpApiManager
import org.openintents.openpgp.util.OpenPgpKeyPreferenceCompat
import org.openintents.openpgp.util.OpenPgpKeyPreference
import org.openintents.openpgp.util.OpenPgpProviderUtil
class AccountSettingsFragment : PreferenceFragmentCompat() {
@ -201,7 +201,7 @@ class AccountSettingsFragment : PreferenceFragmentCompat() {
}
private fun configurePgpKey(account: Account, pgpProvider: String?) {
(findPreference(PREFERENCE_OPENPGP_KEY) as OpenPgpKeyPreferenceCompat).apply {
(findPreference(PREFERENCE_OPENPGP_KEY) as OpenPgpKeyPreference).apply {
setOpenPgpProvider(openPgpApiManager, pgpProvider)
setIntentSenderFragment(this@AccountSettingsFragment)
setDefaultUserId(OpenPgpApiHelper.buildUserId(account.getIdentity(0)))
@ -241,7 +241,7 @@ class AccountSettingsFragment : PreferenceFragmentCompat() {
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
val openPgpKeyPreference = findPreference(PREFERENCE_OPENPGP_KEY) as? OpenPgpKeyPreferenceCompat
val openPgpKeyPreference = findPreference(PREFERENCE_OPENPGP_KEY) as? OpenPgpKeyPreference
if (openPgpKeyPreference?.handleOnActivityResult(requestCode, resultCode, data) == true) {
return
}

View file

@ -416,7 +416,7 @@
android:key="openpgp_provider"
android:title="@string/account_settings_crypto_app" />
<org.openintents.openpgp.util.OpenPgpKeyPreferenceCompat
<org.openintents.openpgp.util.OpenPgpKeyPreference
android:dependency="openpgp_provider"
android:key="openpgp_key"
android:title="@string/account_settings_crypto_key" />

View file

@ -1,4 +1,5 @@
/*
* Copyright (C) 2018 The K-9 Dog Walkers
* Copyright (C) 2015 Dominik Schürmann <dominik@dominikschuermann.de>
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -23,7 +24,8 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.content.res.TypedArray;
import android.preference.Preference;
import android.support.v4.app.Fragment;
import android.support.v7.preference.Preference;
import android.text.format.DateUtils;
import android.util.AttributeSet;
@ -44,6 +46,7 @@ public class OpenPgpKeyPreference extends Preference implements OpenPgpApiManage
private boolean showAutocryptHint;
private OpenPgpApiManager openPgpApiManager;
private Intent cachedActivityResultData;
private Fragment intentSenderFragment;
private PendingIntent pendingIntentSelectKey;
private boolean pendingIntentRunImmediately;
@ -66,6 +69,10 @@ public class OpenPgpKeyPreference extends Preference implements OpenPgpApiManage
refreshTitleAndSummary();
}
public void setIntentSenderFragment(Fragment fragment) {
intentSenderFragment = fragment;
}
public void setDefaultUserId(String userId) {
defaultUserId = userId;
}
@ -132,7 +139,7 @@ public class OpenPgpKeyPreference extends Preference implements OpenPgpApiManage
api.executeApiAsync(data, null, null, openPgpCallback);
}
private IOpenPgpCallback openPgpCallback = new OpenPgpApi.IOpenPgpCallback() {
private IOpenPgpCallback openPgpCallback = new IOpenPgpCallback() {
@Override
public void onReturn(Intent result) {
int resultCode = result.getIntExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
@ -180,9 +187,9 @@ public class OpenPgpKeyPreference extends Preference implements OpenPgpApiManage
}
try {
Activity act = (Activity) getContext();
act.startIntentSenderFromChild(act, pendingIntentSelectKey.getIntentSender(),
REQUEST_CODE_KEY_PREFERENCE, null, 0, 0, 0);
intentSenderFragment
.startIntentSenderForResult(pendingIntentSelectKey.getIntentSender(), REQUEST_CODE_KEY_PREFERENCE,
null, 0, 0, 0, null);
} catch (IntentSender.SendIntentException e) {
Timber.e(e,"Error launching pending intent");
} finally {
@ -271,6 +278,7 @@ public class OpenPgpKeyPreference extends Preference implements OpenPgpApiManage
private void setAndPersist(long newValue) {
keyId = newValue;
notifyDependencyChange(shouldDisableDependents());
// Save to persistent storage (this method will make sure this
// preference should be persistent, along with other useful checks)
@ -289,6 +297,7 @@ public class OpenPgpKeyPreference extends Preference implements OpenPgpApiManage
if (restoreValue) {
// Restore state
keyId = getPersistedLong(keyId);
notifyDependencyChange(shouldDisableDependents());
} else {
// Set state
long value = (Long) defaultValue;
@ -296,6 +305,11 @@ public class OpenPgpKeyPreference extends Preference implements OpenPgpApiManage
}
}
@Override
public boolean shouldDisableDependents() {
return keyId == NO_KEY || super.shouldDisableDependents();
}
public boolean handleOnActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUEST_CODE_API_MANAGER:
@ -317,4 +331,4 @@ public class OpenPgpKeyPreference extends Preference implements OpenPgpApiManage
return false;
}
}
}

View file

@ -1,334 +0,0 @@
/*
* Copyright (C) 2018 The K-9 Dog Walkers
* Copyright (C) 2015 Dominik Schürmann <dominik@dominikschuermann.de>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openintents.openpgp.util;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.content.res.TypedArray;
import android.support.v4.app.Fragment;
import android.support.v7.preference.Preference;
import android.text.format.DateUtils;
import android.util.AttributeSet;
import org.openintents.openpgp.OpenPgpApiManager;
import org.openintents.openpgp.OpenPgpApiManager.OpenPgpApiManagerCallback;
import org.openintents.openpgp.OpenPgpApiManager.OpenPgpProviderError;
import org.openintents.openpgp.OpenPgpApiManager.OpenPgpProviderState;
import org.openintents.openpgp.OpenPgpError;
import org.openintents.openpgp.R;
import org.openintents.openpgp.util.OpenPgpApi.IOpenPgpCallback;
import org.openintents.openpgp.util.OpenPgpUtils.UserId;
import timber.log.Timber;
public class OpenPgpKeyPreferenceCompat extends Preference implements OpenPgpApiManagerCallback {
private long keyId;
private String defaultUserId;
private boolean showAutocryptHint;
private OpenPgpApiManager openPgpApiManager;
private Intent cachedActivityResultData;
private Fragment intentSenderFragment;
private PendingIntent pendingIntentSelectKey;
private boolean pendingIntentRunImmediately;
private String keyPrimaryUserId;
private long keyCreationTime;
private static final int REQUEST_CODE_API_MANAGER = 9998;
private static final int REQUEST_CODE_KEY_PREFERENCE = 9999;
private static final int NO_KEY = 0;
public OpenPgpKeyPreferenceCompat(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setOpenPgpProvider(OpenPgpApiManager openPgpApiManager, String openPgpProvider) {
this.openPgpApiManager = openPgpApiManager;
this.openPgpApiManager.setOpenPgpProvider(openPgpProvider, this);
refreshTitleAndSummary();
}
public void setIntentSenderFragment(Fragment fragment) {
intentSenderFragment = fragment;
}
public void setDefaultUserId(String userId) {
defaultUserId = userId;
}
public void setShowAutocryptHint(boolean showAutocryptHint) {
this.showAutocryptHint = showAutocryptHint;
}
@Override
protected void onClick() {
switch (openPgpApiManager.getOpenPgpProviderState()) {
// The GET_SIGN_KEY action is special, in that it can be used as an implicit registration
// to the API. Therefore, we can ignore the UI_REQUIRED here. If it comes up regardless,
// it will also work as a regular pending intent.
case UI_REQUIRED:
case OK: {
apiGetOrStartPendingIntent();
break;
}
default: {
refreshTitleAndSummary();
openPgpApiManager.refreshConnection();
break;
}
}
}
@Override
public void onOpenPgpProviderStatusChanged() {
if (openPgpApiManager.getOpenPgpProviderState() == OpenPgpProviderState.OK) {
apiRetrievePendingIntentAndKeyInfo();
} else {
pendingIntentSelectKey = null;
pendingIntentRunImmediately = false;
cachedActivityResultData = null;
refreshTitleAndSummary();
}
}
@Override
public void onOpenPgpProviderError(OpenPgpProviderError error) {
if (error == OpenPgpProviderError.ConnectionLost) {
openPgpApiManager.refreshConnection();
}
}
private void apiRetrievePendingIntentAndKeyInfo() {
Intent data;
if (cachedActivityResultData != null) {
data = cachedActivityResultData;
cachedActivityResultData = null;
} else {
data = new Intent();
}
apiRetrievePendingIntentAndKeyInfo(data);
}
private void apiRetrievePendingIntentAndKeyInfo(Intent data) {
data.setAction(OpenPgpApi.ACTION_GET_SIGN_KEY_ID);
data.putExtra(OpenPgpApi.EXTRA_USER_ID, defaultUserId);
data.putExtra(OpenPgpApi.EXTRA_PRESELECT_KEY_ID, keyId);
data.putExtra(OpenPgpApi.EXTRA_SHOW_AUTOCRYPT_HINT, showAutocryptHint);
OpenPgpApi api = openPgpApiManager.getOpenPgpApi();
api.executeApiAsync(data, null, null, openPgpCallback);
}
private IOpenPgpCallback openPgpCallback = new IOpenPgpCallback() {
@Override
public void onReturn(Intent result) {
int resultCode = result.getIntExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
switch (resultCode) {
case OpenPgpApi.RESULT_CODE_SUCCESS:
case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: {
PendingIntent pendingIntentSelectKey = result.getParcelableExtra(OpenPgpApi.RESULT_INTENT);
if (result.hasExtra(OpenPgpApi.EXTRA_SIGN_KEY_ID)) {
long keyId = result.getLongExtra(OpenPgpApi.EXTRA_SIGN_KEY_ID, NO_KEY);
long keyCreationTime = result.getLongExtra("key_creation_time", 0);
String primaryUserId = result.getStringExtra("primary_user_id");
updateWidgetData(keyId, primaryUserId, keyCreationTime, pendingIntentSelectKey);
} else {
updateWidgetData(pendingIntentSelectKey);
}
break;
}
case OpenPgpApi.RESULT_CODE_ERROR: {
OpenPgpError error = result.getParcelableExtra(OpenPgpApi.RESULT_ERROR);
Timber.e("RESULT_CODE_ERROR: %s", error.getMessage());
break;
}
}
}
};
private void apiGetOrStartPendingIntent() {
if (pendingIntentSelectKey != null) {
apiStartPendingIntent();
return;
}
pendingIntentRunImmediately = true;
apiRetrievePendingIntentAndKeyInfo();
}
private void apiStartPendingIntent() {
if (pendingIntentSelectKey == null) {
Timber.e("Tried to launch pending intent but didn't have any?");
return;
}
try {
intentSenderFragment
.startIntentSenderForResult(pendingIntentSelectKey.getIntentSender(), REQUEST_CODE_KEY_PREFERENCE,
null, 0, 0, 0, null);
} catch (IntentSender.SendIntentException e) {
Timber.e(e,"Error launching pending intent");
} finally {
pendingIntentSelectKey = null;
}
}
private void updateWidgetData(PendingIntent pendingIntentSelectKey) {
this.keyPrimaryUserId = null;
this.keyCreationTime = 0;
this.pendingIntentSelectKey = pendingIntentSelectKey;
maybeRunPendingIntentImmediately();
refreshTitleAndSummary();
}
private void updateWidgetData(long keyId, String primaryUserId, long keyCreationTime,
PendingIntent pendingIntentSelectKey) {
setAndPersist(keyId);
this.keyPrimaryUserId = primaryUserId;
this.keyCreationTime = keyCreationTime;
this.pendingIntentSelectKey = pendingIntentSelectKey;
callChangeListener(keyId);
maybeRunPendingIntentImmediately();
refreshTitleAndSummary();
}
private void maybeRunPendingIntentImmediately() {
if (!pendingIntentRunImmediately) {
return;
}
pendingIntentRunImmediately = false;
apiStartPendingIntent();
}
private void refreshTitleAndSummary() {
boolean isConfigured = openPgpApiManager != null &&
openPgpApiManager.getOpenPgpProviderState() != OpenPgpProviderState.UNCONFIGURED;
setEnabled(isConfigured);
if (this.keyId == NO_KEY) {
setTitle(R.string.openpgp_key_title);
setSummary(R.string.openpgp_no_key_selected);
return;
}
if (this.keyPrimaryUserId != null && this.keyCreationTime != 0) {
Context context = getContext();
UserId userId = OpenPgpUtils.splitUserId(keyPrimaryUserId);
if (userId.email != null) {
setTitle(context.getString(R.string.openpgp_key_using, userId.email));
} else if (userId.name != null) {
setTitle(context.getString(R.string.openpgp_key_using, userId.name));
} else {
setTitle(R.string.openpgp_key_using_no_name);
}
String creationTimeStr = DateUtils.formatDateTime(context, keyCreationTime,
DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_TIME |
DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_ABBREV_MONTH);
setSummary(context.getString(R.string.openpgp_key_created, creationTimeStr));
} else {
setTitle(R.string.openpgp_key_title);
setSummary(R.string.openpgp_key_selected);
}
}
/**
* Public API
*/
public void setValue(long keyId) {
setAndPersist(keyId);
refreshTitleAndSummary();
}
/**
* Public API
*/
public long getValue() {
return keyId;
}
private void setAndPersist(long newValue) {
keyId = newValue;
notifyDependencyChange(shouldDisableDependents());
// Save to persistent storage (this method will make sure this
// preference should be persistent, along with other useful checks)
persistLong(keyId);
}
@Override
protected Object onGetDefaultValue(TypedArray a, int index) {
// This preference type's value type is Long, so we read the default
// value from the attributes as an Integer.
return (long) a.getInteger(index, NO_KEY);
}
@Override
protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
if (restoreValue) {
// Restore state
keyId = getPersistedLong(keyId);
notifyDependencyChange(shouldDisableDependents());
} else {
// Set state
long value = (Long) defaultValue;
setAndPersist(value);
}
}
@Override
public boolean shouldDisableDependents() {
return keyId == NO_KEY || super.shouldDisableDependents();
}
public boolean handleOnActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUEST_CODE_API_MANAGER:
openPgpApiManager.onUserInteractionResult();
return true;
case REQUEST_CODE_KEY_PREFERENCE:
if (resultCode == Activity.RESULT_OK) {
cachedActivityResultData = data;
// this might happen early in the lifecycle (e.g. before onResume). if the provider isn't connected
// here, apiRetrievePendingIntentAndKeyInfo() will be called as soon as it is.
OpenPgpProviderState openPgpProviderState = openPgpApiManager.getOpenPgpProviderState();
if (openPgpProviderState == OpenPgpProviderState.OK ||
openPgpProviderState == OpenPgpProviderState.UI_REQUIRED) {
apiRetrievePendingIntentAndKeyInfo();
}
}
return true;
}
return false;
}
}