diff options
Diffstat (limited to 'OpenKeychain/src')
5 files changed, 112 insertions, 45 deletions
| diff --git a/OpenKeychain/src/main/AndroidManifest.xml b/OpenKeychain/src/main/AndroidManifest.xml index c6378136d..9b11a0774 100644 --- a/OpenKeychain/src/main/AndroidManifest.xml +++ b/OpenKeychain/src/main/AndroidManifest.xml @@ -3,8 +3,8 @@      xmlns:tools="http://schemas.android.com/tools"      package="org.sufficientlysecure.keychain"      android:installLocation="auto" -    android:versionCode="29200" -    android:versionName="2.9.2"> +    android:versionCode="29201" +    android:versionName="3.0 beta1">      <!--          General remarks diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/ImportKeysList.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/ImportKeysList.java index a8ddd5419..02cb502d0 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/ImportKeysList.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/ImportKeysList.java @@ -59,6 +59,8 @@ public class ImportKeysList extends ArrayList<ImportKeysListEntry> {      // being a little anal about the ArrayList#addAll contract here      private boolean mergeDupes(ImportKeysListEntry incoming, ImportKeysListEntry existing) {          boolean modified = false; + +        // if any source thinks it’s expired/revoked, it is          if (incoming.isRevoked()) {              existing.setRevoked(true);              modified = true; @@ -67,8 +69,16 @@ public class ImportKeysList extends ArrayList<ImportKeysListEntry> {              existing.setExpired(true);              modified = true;          } + +        // we’re going to want to try to fetch the key from everywhere we found it, so remember +        //  all the origins          for (String origin : incoming.getOrigins()) {              existing.addOrigin(origin); + +            // to work properly, Keybase-sourced entries need to pass along the extra +            if (KeybaseKeyserver.ORIGIN.equals(origin)) { +                existing.setExtraData(incoming.getExtraData()); +            }          }          ArrayList<String> incomingIDs = incoming.getUserIds();          ArrayList<String> existingIDs = existing.getUserIds(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java index 1c1978fe9..93c792564 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java @@ -91,7 +91,6 @@ public class AppSettingsActivity extends ActionBarActivity {          return super.onOptionsItemSelected(item);      } -    // TODO: breaks Yubikey NFC Foreground dispatching      private void startApp() {          Intent i;          PackageManager manager = getPackageManager(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java index 65ea9ec70..d3bbf5cac 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppsListFragment.java @@ -40,9 +40,11 @@ import android.widget.AdapterView.OnItemClickListener;  import android.widget.ImageView;  import android.widget.TextView; +import org.sufficientlysecure.keychain.Constants;  import org.sufficientlysecure.keychain.R;  import org.sufficientlysecure.keychain.provider.KeychainContract;  import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps; +import org.sufficientlysecure.keychain.util.Log;  public class AppsListFragment extends ListFragment implements          LoaderManager.LoaderCallbacks<Cursor> { @@ -57,14 +59,31 @@ public class AppsListFragment extends ListFragment implements          getListView().setOnItemClickListener(new OnItemClickListener() {              @Override              public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) { -                boolean isInstalled = mAdapter.getItemIsInstalled(position);                  String selectedPackageName = mAdapter.getItemPackageName(position); - -                if (isInstalled) { -                    // edit app settings -                    Intent intent = new Intent(getActivity(), AppSettingsActivity.class); -                    intent.setData(KeychainContract.ApiApps.buildByPackageNameUri(selectedPackageName)); -                    startActivity(intent); +                boolean installed = mAdapter.getItemIsInstalled(position); +                boolean registered = mAdapter.getItemIsRegistered(position); + +                if (installed) { +                    if (registered) { +                        // edit app settings +                        Intent intent = new Intent(getActivity(), AppSettingsActivity.class); +                        intent.setData(KeychainContract.ApiApps.buildByPackageNameUri(selectedPackageName)); +                        startActivity(intent); +                    } else { +                        Intent i; +                        PackageManager manager = getActivity().getPackageManager(); +                        try { +                            i = manager.getLaunchIntentForPackage(selectedPackageName); +                            if (i == null) +                                throw new PackageManager.NameNotFoundException(); +                            // start like the Android launcher would do +                            i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); +                            i.addCategory(Intent.CATEGORY_LAUNCHER); +                            startActivity(i); +                        } catch (PackageManager.NameNotFoundException e) { +                            Log.e(Constants.TAG, "startApp", e); +                        } +                    }                  } else {                      try {                          startActivity(new Intent(Intent.ACTION_VIEW, @@ -88,26 +107,34 @@ public class AppsListFragment extends ListFragment implements          mAdapter = new RegisteredAppsAdapter(getActivity(), null, 0);          setListAdapter(mAdapter); -        // Prepare the loader. Either re-connect with an existing one, -        // or start a new one. -        getLoaderManager().initLoader(0, null, this); +        // Loader is started in onResume! +    } + +    @Override +    public void onResume() { +        super.onResume(); +        // after coming back from Google Play -> reload +        getLoaderManager().restartLoader(0, null, this);      } -    private static final String TEMP_COLUMN_INSTALLED = "INSTALLED";      private static final String TEMP_COLUMN_NAME = "NAME"; +    private static final String TEMP_COLUMN_INSTALLED = "INSTALLED"; +    private static final String TEMP_COLUMN_REGISTERED = "REGISTERED";      // These are the Contacts rows that we will retrieve.      static final String[] PROJECTION = new String[]{              ApiApps._ID, // 0              ApiApps.PACKAGE_NAME, // 1 +            "null as " + TEMP_COLUMN_NAME, // installed apps can retrieve app name from Android OS              "0 as " + TEMP_COLUMN_INSTALLED, // changed later in cursor joiner -            "null as " + TEMP_COLUMN_NAME // installed apps can retrieve app name from Android OS +            "1 as " + TEMP_COLUMN_REGISTERED // if it is in db it is registered      };      private static final int INDEX_ID = 0;      private static final int INDEX_PACKAGE_NAME = 1; -    private static final int INDEX_INSTALLED = 2; -    private static final int INDEX_NAME = 3; +    private static final int INDEX_NAME = 2; +    private static final int INDEX_INSTALLED = 3; +    private static final int INDEX_REGISTERED = 4;      public Loader<Cursor> onCreateLoader(int id, Bundle args) {          // This is called when a new Loader needs to be created. This @@ -126,18 +153,20 @@ public class AppsListFragment extends ListFragment implements          MatrixCursor availableAppsCursor = new MatrixCursor(new String[]{                  ApiApps._ID,                  ApiApps.PACKAGE_NAME, +                TEMP_COLUMN_NAME,                  TEMP_COLUMN_INSTALLED, -                TEMP_COLUMN_NAME +                TEMP_COLUMN_REGISTERED          }); -        availableAppsCursor.addRow(new Object[]{1, "com.fsck.k9", 0, "K-9 Mail"}); -        availableAppsCursor.addRow(new Object[]{1, "eu.siacs.conversations", 0, "Conversations (Instant Messaging)"}); -//        availableAppsCursor.addRow(new Object[]{1, "org.sufficientlysecure.keychain.demo", 0, "API Example"}); +        availableAppsCursor.addRow(new Object[]{1, "com.fsck.k9", "K-9 Mail", 0, 0}); +        availableAppsCursor.addRow(new Object[]{1, "eu.siacs.conversations", "Conversations (Instant Messaging)", 0, 0}); +//        availableAppsCursor.addRow(new Object[]{1, "org.sufficientlysecure.keychain.demo", "API Example", 0, 0});          MatrixCursor mergedCursor = new MatrixCursor(new String[]{                  ApiApps._ID,                  ApiApps.PACKAGE_NAME, +                TEMP_COLUMN_NAME,                  TEMP_COLUMN_INSTALLED, -                TEMP_COLUMN_NAME +                TEMP_COLUMN_REGISTERED          });          CursorJoiner joiner = new CursorJoiner( @@ -148,45 +177,39 @@ public class AppsListFragment extends ListFragment implements          for (CursorJoiner.Result joinerResult : joiner) {              switch (joinerResult) {                  case LEFT: { -                    // handle case where a row in cursorA is unique +                    // handle case where a row in availableAppsCursor is unique +                    String packageName = availableAppsCursor.getString(INDEX_PACKAGE_NAME); +                      mergedCursor.addRow(new Object[]{                              availableAppsCursor.getLong(INDEX_ID), -                            availableAppsCursor.getString(INDEX_PACKAGE_NAME), -                            availableAppsCursor.getInt(INDEX_INSTALLED), -                            availableAppsCursor.getString(INDEX_NAME) +                            packageName, +                            availableAppsCursor.getString(INDEX_NAME), +                            isInstalled(packageName), +                            0                      });                      break;                  }                  case RIGHT: { -                    // handle case where a row in cursorB is unique +                    // handle case where a row in data is unique                      String packageName = data.getString(INDEX_PACKAGE_NAME); -                    int installed; -                    try { -                        getActivity().getPackageManager().getApplicationInfo(packageName, 0); -                        installed = 1; -                    } catch (final PackageManager.NameNotFoundException e) { -                        installed = 0; -                    }                      mergedCursor.addRow(new Object[]{                              data.getLong(INDEX_ID),                              packageName, -                            installed, -                            null +                            null, +                            isInstalled(packageName), +                            1                      });                      break;                  }                  case BOTH: {                      // handle case where a row with the same key is in both cursors                      String packageName = data.getString(INDEX_PACKAGE_NAME); +                      String name; -                    int installed; -                    try { -                        getActivity().getPackageManager().getApplicationInfo(packageName, 0); -                        installed = 1; +                    if (isInstalled(packageName) == 1) {                          name = data.getString(INDEX_NAME); -                    } catch (final PackageManager.NameNotFoundException e) { -                        installed = 0; +                    } else {                          // if not installed take name from available apps list                          name = availableAppsCursor.getString(INDEX_NAME);                      } @@ -194,20 +217,29 @@ public class AppsListFragment extends ListFragment implements                      mergedCursor.addRow(new Object[]{                              data.getLong(INDEX_ID),                              packageName, -                            installed, -                            name +                            name, +                            isInstalled(packageName), +                            1                      });                      break;                  }              }          } -          // Swap the new cursor in. (The framework will take care of closing the          // old cursor once we return.)          mAdapter.swapCursor(mergedCursor);      } +    private int isInstalled(String packageName) { +        try { +            getActivity().getPackageManager().getApplicationInfo(packageName, 0); +            return 1; +        } catch (final PackageManager.NameNotFoundException e) { +            return 0; +        } +    } +      public void onLoaderReset(Loader<Cursor> loader) {          // This is called when the last Cursor provided to onLoadFinished()          // above is about to be closed. We need to make sure we are no @@ -258,6 +290,18 @@ public class AppsListFragment extends ListFragment implements              }          } +        public boolean getItemIsRegistered(int position) { +            if (mDataValid && mCursor != null) { +                if (mCursor.moveToPosition(position)) { +                    return (mCursor.getInt(INDEX_REGISTERED) == 1); +                } else { +                    return false; +                } +            } else { +                return false; +            } +        } +          @Override          public void bindView(View view, Context context, Cursor cursor) {              TextView text = (TextView) view.findViewById(R.id.api_apps_adapter_item_name); diff --git a/OpenKeychain/src/main/res/raw/help_changelog.html b/OpenKeychain/src/main/res/raw/help_changelog.html index 2a47aded9..3c4e3de66 100644 --- a/OpenKeychain/src/main/res/raw/help_changelog.html +++ b/OpenKeychain/src/main/res/raw/help_changelog.html @@ -5,6 +5,20 @@ And don't add newlines before or after p tags because of transifex -->  <head>  </head>  <body> + +<h2>3.0</h2> +<ul> +<li>Full support for Yubikey signature generation and decryption!</li> +<li>Propose installable compatible apps in apps list</li> +<li>New design for decryption screens</li> +<li>Many fixes for key import, also fixes stripped keys</li> +<li>Honor and display key authenticate flags</li> +<li>User interface to generate custom keys</li> +<li>Fixing user id revocation certificates</li> +<li>New cloud search (searches over traditional keyservers and keybase.io)</li> +<li>Support for stripping keys inside OpenKeychain</li> +</ul> +  <h2>2.9.2</h2>  <ul>  <li>Fix keys broken in 2.9.1</li> | 
