diff options
| -rw-r--r-- | src/main/java/org/openintents/openpgp/util/OpenPgpAppPreference.java (renamed from src/main/java/org/openintents/openpgp/util/OpenPgpListPreference.java) | 72 | ||||
| -rw-r--r-- | src/main/java/org/openintents/openpgp/util/OpenPgpKeyPreference.java | 268 | ||||
| -rw-r--r-- | src/main/res/values/strings.xml | 2 | 
3 files changed, 319 insertions, 23 deletions
diff --git a/src/main/java/org/openintents/openpgp/util/OpenPgpListPreference.java b/src/main/java/org/openintents/openpgp/util/OpenPgpAppPreference.java index 4bad35a..a69bd31 100644 --- a/src/main/java/org/openintents/openpgp/util/OpenPgpListPreference.java +++ b/src/main/java/org/openintents/openpgp/util/OpenPgpAppPreference.java @@ -26,11 +26,13 @@ import android.graphics.drawable.Drawable;  import android.net.Uri;  import android.preference.DialogPreference;  import android.util.AttributeSet; +import android.util.Log;  import android.view.View;  import android.view.ViewGroup;  import android.widget.ArrayAdapter;  import android.widget.ListAdapter;  import android.widget.TextView; +  import org.openintents.openpgp.R;  import java.util.ArrayList; @@ -40,7 +42,7 @@ import java.util.List;   * Does not extend ListPreference, but is very similar to it!   * http://grepcode.com/file_/repository.grepcode.com/java/ext/com.google.android/android/4.4_r1/android/preference/ListPreference.java/?v=source   */ -public class OpenPgpListPreference extends DialogPreference { +public class OpenPgpAppPreference extends DialogPreference {      private static final String OPENKEYCHAIN_PACKAGE = "org.sufficientlysecure.keychain";      private static final String MARKET_INTENT_URI_BASE = "market://details?id=%s";      private static final Intent MARKET_INTENT = new Intent(Intent.ACTION_VIEW, Uri.parse( @@ -53,17 +55,17 @@ public class OpenPgpListPreference extends DialogPreference {          PROVIDER_BLACKLIST.add("org.thialfihar.android.apg");      } -    private ArrayList<OpenPgpProviderEntry> mLegacyList = new ArrayList<OpenPgpProviderEntry>(); -    private ArrayList<OpenPgpProviderEntry> mList = new ArrayList<OpenPgpProviderEntry>(); +    private ArrayList<OpenPgpProviderEntry> mLegacyList = new ArrayList<>(); +    private ArrayList<OpenPgpProviderEntry> mList = new ArrayList<>();      private String mSelectedPackage; -    public OpenPgpListPreference(Context context, AttributeSet attrs) { +    public OpenPgpAppPreference(Context context, AttributeSet attrs) {          super(context, attrs); -        populateExistingProviderList(); +        populateAppList();      } -    public OpenPgpListPreference(Context context) { +    public OpenPgpAppPreference(Context context) {          this(context, null);      } @@ -81,7 +83,8 @@ public class OpenPgpListPreference extends DialogPreference {      @Override      protected void onPrepareDialogBuilder(Builder builder) { -        populateExistingProviderList(); +        // do again, maybe an app has now been installed +        populateAppList();          // Init ArrayAdapter with OpenPGP Providers          ListAdapter adapter = new ArrayAdapter<OpenPgpProviderEntry>(getContext(), @@ -103,7 +106,7 @@ public class OpenPgpListPreference extends DialogPreference {              }          }; -        builder.setSingleChoiceItems(adapter, getIndexOfProviderList(getValue()), +        builder.setSingleChoiceItems(adapter, getIndexOfProviderList(mSelectedPackage),                  new DialogInterface.OnClickListener() {                      @Override @@ -121,6 +124,7 @@ public class OpenPgpListPreference extends DialogPreference {                               * as the user might remove the currently used OpenPGP app.                               */                              getContext().startActivity(entry.intent); +                            return;                          }                          mSelectedPackage = entry.packageName; @@ -129,7 +133,7 @@ public class OpenPgpListPreference extends DialogPreference {                           * Clicking on an item simulates the positive button click, and dismisses                           * the dialog.                           */ -                        OpenPgpListPreference.this.onClick(dialog, DialogInterface.BUTTON_POSITIVE); +                        OpenPgpAppPreference.this.onClick(dialog, DialogInterface.BUTTON_POSITIVE);                          dialog.dismiss();                      }                  }); @@ -146,10 +150,27 @@ public class OpenPgpListPreference extends DialogPreference {          super.onDialogClosed(positiveResult);          if (positiveResult && (mSelectedPackage != null)) { -            if (callChangeListener(mSelectedPackage)) { -                setValue(mSelectedPackage); -            } +            save(); +        } +    } + +    private void save() { +        // Give the client a chance to ignore this change if they deem it +        // invalid +        if (!callChangeListener(mSelectedPackage)) { +            // They don't want the value to be set +            return;          } + +        // Save to persistent storage (this method will make sure this +        // preference should be persistent, along with other useful checks) +        persistString(mSelectedPackage); + +        // Data has changed, notify so UI can be refreshed! +        notifyChanged(); + +        // also update summary with selected provider +        setSummary(getEntry());      }      private int getIndexOfProviderList(String packageName) { @@ -162,19 +183,14 @@ public class OpenPgpListPreference extends DialogPreference {          return -1;      } -    public void setValue(String packageName) { -        mSelectedPackage = packageName; -        persistString(packageName); +    public String getEntry() { +        return getEntryByValue(mSelectedPackage);      }      public String getValue() {          return mSelectedPackage;      } -    public String getEntry() { -        return getEntryByValue(mSelectedPackage); -    } -      @Override      protected Object onGetDefaultValue(TypedArray a, int index) {          return a.getString(index); @@ -182,7 +198,18 @@ public class OpenPgpListPreference extends DialogPreference {      @Override      protected void onSetInitialValue(boolean restoreValue, Object defaultValue) { -        setValue(restoreValue ? getPersistedString(mSelectedPackage) : (String) defaultValue); +        if (restoreValue) { +            // Restore state +            Log.d(OpenPgpApi.TAG, "restore: mSelectedPackage " + mSelectedPackage); +            mSelectedPackage = getPersistedString(mSelectedPackage); +            setSummary(getEntry()); +        } else { +            // Set state +            String value = (String) defaultValue; +            mSelectedPackage = value; +            persistString(value); +            setSummary(getEntry()); +        }      }      public String getEntryByValue(String packageName) { @@ -195,8 +222,7 @@ public class OpenPgpListPreference extends DialogPreference {          return null;      } -    private void populateExistingProviderList() -    { +    private void populateAppList() {          mList.clear();          // add "none"-entry @@ -208,7 +234,7 @@ public class OpenPgpListPreference extends DialogPreference {          mList.addAll(mLegacyList);          // search for OpenPGP providers... -        ArrayList<OpenPgpProviderEntry> providerList = new ArrayList<OpenPgpProviderEntry>(); +        ArrayList<OpenPgpProviderEntry> providerList = new ArrayList<>();          Intent intent = new Intent(OpenPgpApi.SERVICE_INTENT);          List<ResolveInfo> resInfo = getContext().getPackageManager().queryIntentServices(intent, 0);          if (!resInfo.isEmpty()) { diff --git a/src/main/java/org/openintents/openpgp/util/OpenPgpKeyPreference.java b/src/main/java/org/openintents/openpgp/util/OpenPgpKeyPreference.java new file mode 100644 index 0000000..725d3c4 --- /dev/null +++ b/src/main/java/org/openintents/openpgp/util/OpenPgpKeyPreference.java @@ -0,0 +1,268 @@ +/* + * 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.os.Parcel; +import android.os.Parcelable; +import android.preference.Preference; +import android.text.TextUtils; +import android.util.AttributeSet; +import android.util.Log; + +import org.openintents.openpgp.IOpenPgpService; +import org.openintents.openpgp.OpenPgpError; +import org.openintents.openpgp.R; + +public class OpenPgpKeyPreference extends Preference { +    private long mKeyId; +    private String mOpenPgpProvider; +    private OpenPgpServiceConnection mServiceConnection; +    private String mDefaultUserId; + +    public static final int REQUEST_CODE_KEY_PREFERENCE = 9999; + +    public OpenPgpKeyPreference(Context context, AttributeSet attrs) { +        super(context, attrs); +    } + +    @Override +    public CharSequence getSummary() { +        return (mKeyId == 0) ? getContext().getString(R.string.openpgp_no_key_selected) +                : getContext().getString(R.string.openpgp_key_selected); +    } + +    private void updateEnabled() { +        if (TextUtils.isEmpty(mOpenPgpProvider)) { +            setEnabled(false); +        } else { +            setEnabled(true); +        } +    } + +    public void setOpenPgpProvider(String packageName) { +        mOpenPgpProvider = packageName; +        updateEnabled(); +    } + +    public void setDefaultUserId(String userId) { +        mDefaultUserId = userId; +    } + +    @Override +    protected void onClick() { +        // bind to service +        mServiceConnection = new OpenPgpServiceConnection( +                getContext().getApplicationContext(), +                mOpenPgpProvider, +                new OpenPgpServiceConnection.OnBound() { +                    @Override +                    public void onBound(IOpenPgpService service) { +                        Log.d(OpenPgpApi.TAG, "onBound!"); + +                        Intent data = new Intent(); +                        data.setAction(OpenPgpApi.ACTION_GET_SIGN_KEY_ID); +                        data.putExtra(OpenPgpApi.EXTRA_USER_ID, mDefaultUserId); + +                        OpenPgpApi api = new OpenPgpApi(getContext(), mServiceConnection.getService()); +                        api.executeApiAsync(data, null, null, new MyCallback(REQUEST_CODE_KEY_PREFERENCE)); +                    } + +                    @Override +                    public void onError(Exception e) { +                        Log.e(OpenPgpApi.TAG, "exception when binding!", e); +                    } +                } +        ); +        mServiceConnection.bindToService(); +    } + +    private class MyCallback implements OpenPgpApi.IOpenPgpCallback { +        int requestCode; + +        private MyCallback(int requestCode) { +            this.requestCode = requestCode; +        } + +        @Override +        public void onReturn(Intent result) { +            switch (result.getIntExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR)) { +                case OpenPgpApi.RESULT_CODE_SUCCESS: { +                    Log.e(OpenPgpApi.TAG, "RESULT_CODE_SUCCESS: Should not happen!"); + +                    break; +                } +                case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: { + +                    PendingIntent pi = result.getParcelableExtra(OpenPgpApi.RESULT_INTENT); +                    try { +                        Activity act = (Activity) getContext(); +                        act.startIntentSenderFromChild( +                                act, pi.getIntentSender(), +                                requestCode, null, 0, 0, 0); +                    } catch (IntentSender.SendIntentException e) { +                        Log.e(OpenPgpApi.TAG, "SendIntentException", e); +                    } +                    break; +                } +                case OpenPgpApi.RESULT_CODE_ERROR: { +                    OpenPgpError error = result.getParcelableExtra(OpenPgpApi.RESULT_ERROR); +                    Log.e(OpenPgpApi.TAG, "RESULT_CODE_ERROR: " + error.getMessage()); + +                    break; +                } +            } +        } +    } + +    private void save(long newValue) { +        // Give the client a chance to ignore this change if they deem it +        // invalid +        if (!callChangeListener(newValue)) { +            // They don't want the value to be set +            return; +        } + +        mKeyId = newValue; + +        // Save to persistent storage (this method will make sure this +        // preference should be persistent, along with other useful checks) +        persistLong(mKeyId); + +        // Data has changed, notify so UI can be refreshed! +        notifyChanged(); +    } + +    @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, 0); +    } + +    @Override +    protected void onSetInitialValue(boolean restoreValue, Object defaultValue) { +        if (restoreValue) { +            // Restore state +            mKeyId = getPersistedLong(mKeyId); +        } else { +            // Set state +            long value = (Long) defaultValue; +            mKeyId = value; +            persistLong(value); +        } +    } + +    @Override +    protected Parcelable onSaveInstanceState() { +        /* +         * Suppose a client uses this preference type without persisting. We +         * must save the instance state so it is able to, for example, survive +         * orientation changes. +         */ + +        final Parcelable superState = super.onSaveInstanceState(); +        if (isPersistent()) { +            // No need to save instance state since it's persistent +            return superState; +        } + +        // Save the instance state +        final SavedState myState = new SavedState(superState); +        myState.keyId = mKeyId; +        myState.openPgpProvider = mOpenPgpProvider; +        myState.defaultUserId = mDefaultUserId; +        return myState; +    } + +    @Override +    protected void onRestoreInstanceState(Parcelable state) { +        if (!state.getClass().equals(SavedState.class)) { +            // Didn't save state for us in onSaveInstanceState +            super.onRestoreInstanceState(state); +            return; +        } + +        // Restore the instance state +        SavedState myState = (SavedState) state; +        super.onRestoreInstanceState(myState.getSuperState()); +        mKeyId = myState.keyId; +        mOpenPgpProvider = myState.openPgpProvider; +        mDefaultUserId = myState.defaultUserId; +        notifyChanged(); +    } + +    /** +     * SavedState, a subclass of {@link BaseSavedState}, will store the state +     * of MyPreference, a subclass of Preference. +     * <p/> +     * It is important to always call through to super methods. +     */ +    private static class SavedState extends BaseSavedState { +        long keyId; +        String openPgpProvider; +        String defaultUserId; + +        public SavedState(Parcel source) { +            super(source); + +            keyId = source.readInt(); +            openPgpProvider = source.readString(); +            defaultUserId = source.readString(); +        } + +        @Override +        public void writeToParcel(Parcel dest, int flags) { +            super.writeToParcel(dest, flags); + +            dest.writeLong(keyId); +            dest.writeString(openPgpProvider); +            dest.writeString(defaultUserId); +        } + +        public SavedState(Parcelable superState) { +            super(superState); +        } + +        public static final Parcelable.Creator<SavedState> CREATOR = +                new Parcelable.Creator<SavedState>() { +                    public SavedState createFromParcel(Parcel in) { +                        return new SavedState(in); +                    } + +                    public SavedState[] newArray(int size) { +                        return new SavedState[size]; +                    } +                }; +    } + +    public boolean handleOnActivityResult(int requestCode, int resultCode, Intent data) { +        if (requestCode == REQUEST_CODE_KEY_PREFERENCE && resultCode == Activity.RESULT_OK) { +            long keyId = data.getLongExtra(OpenPgpApi.EXTRA_SIGN_KEY_ID, 0); +            save(keyId); +            return true; +        } else { +            return false; +        } +    } + +}
\ No newline at end of file diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 0119831..a45524f 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -3,5 +3,7 @@      <string name="openpgp_list_preference_none">None</string>      <string name="openpgp_install_openkeychain_via">Install OpenKeychain via %s</string> +    <string name="openpgp_no_key_selected">No key selected</string> +    <string name="openpgp_key_selected">Key has been selected</string>  </resources>
\ No newline at end of file  | 
