From 016e7d68eeb173565c0a2aad51cb9807b432df17 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Fri, 29 Jun 2018 23:38:29 +0200 Subject: [PATCH] add debug actions activity (reachable from shortcuts) --- OpenKeychain/src/debug/res/xml/shortcuts.xml | 11 ++ OpenKeychain/src/main/AndroidManifest.xml | 6 + .../remote/ApiPendingIntentFactory.java | 12 +- .../keychain/ui/DebugActionsActivity.java | 157 ++++++++++++++++++ OpenKeychain/src/main/res/values/strings.xml | 3 + OpenKeychain/src/main/res/values/styles.xml | 9 + 6 files changed, 193 insertions(+), 5 deletions(-) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DebugActionsActivity.java diff --git a/OpenKeychain/src/debug/res/xml/shortcuts.xml b/OpenKeychain/src/debug/res/xml/shortcuts.xml index 6446091c1..10abca10b 100644 --- a/OpenKeychain/src/debug/res/xml/shortcuts.xml +++ b/OpenKeychain/src/debug/res/xml/shortcuts.xml @@ -22,4 +22,15 @@ android:targetClass="org.sufficientlysecure.keychain.ui.EncryptFilesActivity" android:targetPackage="org.sufficientlysecure.keychain.debug" /> + + + \ No newline at end of file diff --git a/OpenKeychain/src/main/AndroidManifest.xml b/OpenKeychain/src/main/AndroidManifest.xml index 0487cd6a3..b5ad62cd2 100644 --- a/OpenKeychain/src/main/AndroidManifest.xml +++ b/OpenKeychain/src/main/AndroidManifest.xml @@ -967,6 +967,12 @@ android:name=".remote.ui.RemoteDisplayTransferCodeActivity" android:theme="@style/Theme.Keychain.Transparent"/> + + + + + + missingEmails, - ArrayList duplicateEmails, boolean noUserIdsCheck) { + public PendingIntent createSelectPublicKeyPendingIntent(Intent data, long[] keyIdsArray, + ArrayList missingEmails, + ArrayList duplicateEmails, boolean noUserIdsCheck) { Intent intent = new Intent(mContext, RemoteSelectPubKeyActivity.class); intent.putExtra(RemoteSelectPubKeyActivity.EXTRA_SELECTED_MASTER_KEY_IDS, keyIdsArray); intent.putExtra(RemoteSelectPubKeyActivity.EXTRA_NO_USER_IDS_CHECK, noUserIdsCheck); @@ -121,7 +122,7 @@ public class ApiPendingIntentFactory { return createInternal(data, intent); } - PendingIntent createRequestKeyPermissionPendingIntent(Intent data, String packageName, long... masterKeyIds) { + public PendingIntent createRequestKeyPermissionPendingIntent(Intent data, String packageName, long... masterKeyIds) { Intent intent = new Intent(mContext, RequestKeyPermissionActivity.class); intent.putExtra(RequestKeyPermissionActivity.EXTRA_PACKAGE_NAME, packageName); intent.putExtra(RequestKeyPermissionActivity.EXTRA_REQUESTED_KEY_IDS, masterKeyIds); @@ -135,7 +136,8 @@ public class ApiPendingIntentFactory { return createInternal(data, intent); } - PendingIntent createSelectSignKeyIdLegacyPendingIntent(Intent data, String packageName, String preferredUserId) { + public PendingIntent createSelectSignKeyIdLegacyPendingIntent(Intent data, String packageName, + String preferredUserId) { Intent intent = new Intent(mContext, SelectSignKeyIdActivity.class); intent.putExtra(SelectSignKeyIdActivity.EXTRA_PACKAGE_NAME, packageName); intent.putExtra(SelectSignKeyIdActivity.EXTRA_USER_ID, preferredUserId); @@ -143,7 +145,7 @@ public class ApiPendingIntentFactory { return createInternal(data, intent); } - PendingIntent createSelectSignKeyIdPendingIntent(Intent data, String packageName, + public PendingIntent createSelectSignKeyIdPendingIntent(Intent data, String packageName, byte[] packageSignature, String preferredUserId, boolean showAutocryptHint) { Intent intent = new Intent(mContext, RemoteSelectIdKeyActivity.class); intent.putExtra(RemoteSelectIdKeyActivity.EXTRA_PACKAGE_NAME, packageName); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DebugActionsActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DebugActionsActivity.java new file mode 100644 index 000000000..e4bf1286e --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DebugActionsActivity.java @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2017 Schürmann & Breitmoser GbR + * + * This program 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. + * + * This program 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 should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.sufficientlysecure.keychain.ui; + + +import java.util.ArrayList; + +import android.annotation.SuppressLint; +import android.annotation.TargetApi; +import android.app.Activity; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.content.IntentSender.SendIntentException; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; +import android.database.sqlite.SQLiteConstraintException; +import android.os.Build.VERSION_CODES; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.widget.Toolbar; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewGroup.LayoutParams; +import android.widget.FrameLayout; +import android.widget.LinearLayout; +import android.widget.ScrollView; +import android.widget.TextView; + +import org.sufficientlysecure.keychain.BuildConfig; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.model.ApiApp; +import org.sufficientlysecure.keychain.provider.ApiAppDao; +import org.sufficientlysecure.keychain.provider.KeyRepository; +import org.sufficientlysecure.keychain.remote.ApiPendingIntentFactory; +import timber.log.Timber; + + +@TargetApi(VERSION_CODES.LOLLIPOP) +public class DebugActionsActivity extends Activity { + private byte[] packageSig; + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + packageSig = registerSelfAsApiApp(); + + setContentView(createView()); + } + + private View createView() { + Context context = getBaseContext(); + + LinearLayout verticalLayout = new LinearLayout(context); + verticalLayout.setOrientation(LinearLayout.VERTICAL); + verticalLayout.setPadding(0, 40, 0, 0); + + Toolbar toolbar = new Toolbar(this); + toolbar.setTitle("Debug Actions"); + verticalLayout.addView(toolbar, new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); + + ApiPendingIntentFactory pendingIntentFactory = new ApiPendingIntentFactory(context); + addButtonToLayout(context, verticalLayout, "Select Public Key").setOnClickListener((v) -> { + PendingIntent pendingIntent = pendingIntentFactory.createSelectPublicKeyPendingIntent( + new Intent(), new long[] {}, new ArrayList<>(), new ArrayList<>(), false); + startPendingIntent(pendingIntent); + }); + addButtonToLayout(context, verticalLayout, "Select Signing Key (legacy)").setOnClickListener((v) -> { + PendingIntent pendingIntent = pendingIntentFactory.createSelectSignKeyIdLegacyPendingIntent( + new Intent(), BuildConfig.APPLICATION_ID, "test@openkeychain.org"); + startPendingIntent(pendingIntent); + }); + addButtonToLayout(context, verticalLayout, "Select Signing Key").setOnClickListener((v) -> { + PendingIntent pendingIntent = pendingIntentFactory.createSelectSignKeyIdPendingIntent( + new Intent(), BuildConfig.APPLICATION_ID, packageSig, "test@openkeychain.org", false); + startPendingIntent(pendingIntent); + }); + addButtonToLayout(context, verticalLayout, "Select Signing Key (Autocrypt)").setOnClickListener((v) -> { + PendingIntent pendingIntent = pendingIntentFactory.createSelectSignKeyIdPendingIntent( + new Intent(), BuildConfig.APPLICATION_ID, packageSig, "test@openkeychain.org", true); + startPendingIntent(pendingIntent); + }); + addButtonToLayout(context, verticalLayout, "Request Permission (first secret key)").setOnClickListener((v) -> { + KeyRepository keyRepository = KeyRepository.create(getBaseContext()); + long firstMasterKeyId = keyRepository.getAllUnifiedKeyInfoWithSecret().get(0).master_key_id(); + PendingIntent pendingIntent = pendingIntentFactory.createRequestKeyPermissionPendingIntent( + new Intent(), BuildConfig.APPLICATION_ID, firstMasterKeyId); + startPendingIntent(pendingIntent); + }); + + ScrollView view = new ScrollView(context); + view.addView(verticalLayout, new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); + return view; + } + + private TextView addButtonToLayout(Context context, ViewGroup buttonContainer, String buttonLabel) { + TextView button = new TextView(context, null, 0, R.style.DebugButton); + button.setText(buttonLabel); + buttonContainer.addView(button, new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); + return button; + } + + private byte[] registerSelfAsApiApp() { + try { + PackageManager packageManager = getPackageManager(); + ApiAppDao apiAppDao = ApiAppDao.getInstance(getBaseContext()); + @SuppressLint("PackageManagerGetSignatures") + byte[] packageSig = packageManager.getPackageInfo(BuildConfig.APPLICATION_ID, PackageManager.GET_SIGNATURES).signatures[0].toByteArray(); + apiAppDao.insertApiApp(ApiApp.create(BuildConfig.APPLICATION_ID, packageSig)); + return packageSig; + } catch (NameNotFoundException e) { + throw new AssertionError(e); + } + } + + private void startPendingIntent(PendingIntent pendingIntent) { + try { + startIntentSenderForResult(pendingIntent.getIntentSender(), 0, null, 0, 0, 0); + } catch (SendIntentException e) { + Timber.e(e); + } + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (data != null) { + if (resultCode == RESULT_OK) { + Timber.d("result: ok, intent: %s, extras: %s", data.toString(), data.getExtras()); + } else { + Timber.d("result: cancelled, intent: %s, extras: %s", data.toString(), data.getExtras()); + } + } else { + if (resultCode == RESULT_OK) { + Timber.d("result: ok, intent: null"); + } else { + Timber.d("result: cancelled, intent: null"); + } + } + } +} diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index da278d2b2..cc0fe24ab 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -108,6 +108,9 @@ "Saved!" "Not matching" + + Debug Actions + "Encrypt files" "Exchange keys" diff --git a/OpenKeychain/src/main/res/values/styles.xml b/OpenKeychain/src/main/res/values/styles.xml index b70093b7a..4743e1eae 100644 --- a/OpenKeychain/src/main/res/values/styles.xml +++ b/OpenKeychain/src/main/res/values/styles.xml @@ -84,4 +84,13 @@ - + +