aboutsummaryrefslogtreecommitdiffstats
path: root/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java
diff options
context:
space:
mode:
Diffstat (limited to 'OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java')
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java217
1 files changed, 48 insertions, 169 deletions
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java
index bc513d532..cfd2b9ec3 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
+ * Copyright (C) 2013-2014 Dominik Schürmann <dominik@dominikschuermann.de>
*
* 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
@@ -19,17 +19,16 @@ package org.sufficientlysecure.keychain.service.remote;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.TimeUnit;
+import org.openintents.openpgp.OpenPgpError;
+import org.openintents.openpgp.util.OpenPgpConstants;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.service.exception.WrongPackageSignatureException;
import org.sufficientlysecure.keychain.util.Log;
-import org.sufficientlysecure.keychain.util.PausableThreadPoolExecutor;
+import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
@@ -50,66 +49,19 @@ import android.os.Messenger;
public abstract class RemoteService extends Service {
Context mContext;
- private final ArrayBlockingQueue<Runnable> mPoolQueue = new ArrayBlockingQueue<Runnable>(100);
- // TODO: Are these parameters okay?
- private PausableThreadPoolExecutor mThreadPool = new PausableThreadPoolExecutor(2, 4, 10,
- TimeUnit.SECONDS, mPoolQueue);
+ private static final int PRIVATE_REQUEST_CODE_REGISTER = 651;
+ private static final int PRIVATE_REQUEST_CODE_ERROR = 652;
- private final Object userInputLock = new Object();
-
- /**
- * Override handleUserInput() to handle OKAY (1) and CANCEL (0). After handling the waiting
- * threads will be notified and the queue resumed
- */
- protected class UserInputCallback extends BaseCallback {
-
- public void handleUserInput(Message msg) {
- }
-
- @Override
- public boolean handleMessage(Message msg) {
- handleUserInput(msg);
-
- // resume
- synchronized (userInputLock) {
- userInputLock.notifyAll();
- }
- mThreadPool.resume();
- return true;
- }
-
- }
-
- /**
- * Extends Handler.Callback with OKAY (1), CANCEL (0) variables
- */
- private class BaseCallback implements Handler.Callback {
- public static final int OKAY = 1;
- public static final int CANCEL = 0;
-
- @Override
- public boolean handleMessage(Message msg) {
- return false;
- }
-
- }
public Context getContext() {
return mContext;
}
- /**
- * Should be used from Stub implementations of AIDL interfaces to enqueue a runnable for
- * execution
- *
- * @param r
- */
- protected void checkAndEnqueue(Runnable r) {
+ protected Bundle isAllowed(Bundle params) {
try {
if (isCallerAllowed(false)) {
- mThreadPool.execute(r);
- Log.d(Constants.TAG, "Enqueued runnable…");
+ return null;
} else {
String[] callingPackages = getPackageManager().getPackagesForUid(
Binder.getCallingUid());
@@ -121,32 +73,46 @@ public abstract class RemoteService extends Service {
packageSignature = getPackageSignature(packageName);
} catch (NameNotFoundException e) {
Log.e(Constants.TAG, "Should not happen, returning!", e);
- return;
- }
- Log.e(Constants.TAG,
- "Not allowed to use service! Starting activity for registration!");
- Bundle extras = new Bundle();
- extras.putString(RemoteServiceActivity.EXTRA_PACKAGE_NAME, packageName);
- extras.putByteArray(RemoteServiceActivity.EXTRA_PACKAGE_SIGNATURE, packageSignature);
- RegisterActivityCallback callback = new RegisterActivityCallback();
-
- pauseAndStartUserInteraction(RemoteServiceActivity.ACTION_REGISTER, callback,
- extras);
-
- if (callback.isAllowed()) {
- mThreadPool.execute(r);
- Log.d(Constants.TAG, "Enqueued runnable…");
- } else {
- Log.d(Constants.TAG, "User disallowed app!");
+ // return error
+ Bundle result = new Bundle();
+ result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_ERROR);
+ result.putParcelable(OpenPgpConstants.RESULT_ERRORS,
+ new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage()));
+ return result;
}
+ Log.e(Constants.TAG, "Not allowed to use service! return PendingIntent for registration!");
+
+ Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class);
+ intent.setAction(RemoteServiceActivity.ACTION_REGISTER);
+ intent.putExtra(RemoteServiceActivity.EXTRA_PACKAGE_NAME, packageName);
+ intent.putExtra(RemoteServiceActivity.EXTRA_PACKAGE_SIGNATURE, packageSignature);
+ intent.putExtra(OpenPgpConstants.PI_RESULT_PARAMS, params);
+
+ PendingIntent pi = PendingIntent.getActivity(getBaseContext(), PRIVATE_REQUEST_CODE_REGISTER, intent, 0);
+
+ // return PendingIntent to be executed by client
+ Bundle result = new Bundle();
+ result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_USER_INTERACTION_REQUIRED);
+ result.putParcelable(OpenPgpConstants.RESULT_INTENT, pi);
+
+ return result;
}
} catch (WrongPackageSignatureException e) {
- Log.e(Constants.TAG, e.getMessage());
+ Log.e(Constants.TAG, "wrong signature!", e);
+
+ Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class);
+ intent.setAction(RemoteServiceActivity.ACTION_ERROR_MESSAGE);
+ intent.putExtra(RemoteServiceActivity.EXTRA_ERROR_MESSAGE, getString(R.string.api_error_wrong_signature));
+ intent.putExtra(OpenPgpConstants.PI_RESULT_PARAMS, params);
+
+ PendingIntent pi = PendingIntent.getActivity(getBaseContext(), PRIVATE_REQUEST_CODE_ERROR, intent, 0);
+
+ // return PendingIntent to be executed by client
+ Bundle result = new Bundle();
+ result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_USER_INTERACTION_REQUIRED);
+ result.putParcelable(OpenPgpConstants.RESULT_INTENT, pi);
- Bundle extras = new Bundle();
- extras.putString(RemoteServiceActivity.EXTRA_ERROR_MESSAGE,
- getString(R.string.api_error_wrong_signature));
- pauseAndStartUserInteraction(RemoteServiceActivity.ACTION_ERROR_MESSAGE, null, extras);
+ return result;
}
}
@@ -161,40 +127,8 @@ public abstract class RemoteService extends Service {
}
/**
- * Locks current thread and pauses execution of runnables and starts activity for user input
- *
- * @param action
- * @param messenger
- * @param extras
- */
- protected void pauseAndStartUserInteraction(String action, BaseCallback callback, Bundle extras) {
- synchronized (userInputLock) {
- mThreadPool.pause();
-
- Log.d(Constants.TAG, "starting activity...");
- Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- intent.setAction(action);
-
- Messenger messenger = new Messenger(new Handler(getMainLooper(), callback));
-
- extras.putParcelable(RemoteServiceActivity.EXTRA_MESSENGER, messenger);
- intent.putExtras(extras);
-
- startActivity(intent);
-
- // lock current thread for user input
- try {
- userInputLock.wait();
- } catch (InterruptedException e) {
- Log.e(Constants.TAG, "CryptoService", e);
- }
- }
- }
-
- /**
* Retrieves AppSettings from database for the application calling this remote service
- *
+ *
* @return
*/
protected AppSettings getAppSettings() {
@@ -215,66 +149,11 @@ public abstract class RemoteService extends Service {
return null;
}
- class RegisterActivityCallback extends BaseCallback {
- public static final String PACKAGE_NAME = "package_name";
-
- private boolean allowed = false;
- private String packageName;
-
- public boolean isAllowed() {
- return allowed;
- }
-
- public String getPackageName() {
- return packageName;
- }
-
- @Override
- public boolean handleMessage(Message msg) {
- if (msg.arg1 == OKAY) {
- allowed = true;
- packageName = msg.getData().getString(PACKAGE_NAME);
-
- // resume threads
- try {
- if (isPackageAllowed(packageName)) {
- synchronized (userInputLock) {
- userInputLock.notifyAll();
- }
- mThreadPool.resume();
- } else {
- // Should not happen!
- Log.e(Constants.TAG, "Should not happen! Emergency shutdown!");
- mThreadPool.shutdownNow();
- }
- } catch (WrongPackageSignatureException e) {
- Log.e(Constants.TAG, e.getMessage());
-
- Bundle extras = new Bundle();
- extras.putString(RemoteServiceActivity.EXTRA_ERROR_MESSAGE,
- getString(R.string.api_error_wrong_signature));
- pauseAndStartUserInteraction(RemoteServiceActivity.ACTION_ERROR_MESSAGE, null,
- extras);
- }
- } else {
- allowed = false;
-
- synchronized (userInputLock) {
- userInputLock.notifyAll();
- }
- mThreadPool.resume();
- }
- return true;
- }
-
- }
-
/**
* Checks if process that binds to this service (i.e. the package name corresponding to the
* process) is in the list of allowed package names.
- *
- * @param allowOnlySelf
- * allow only Keychain app itself
+ *
+ * @param allowOnlySelf allow only Keychain app itself
* @return true if process is allowed to use this service
* @throws WrongPackageSignatureException
*/
@@ -308,7 +187,7 @@ public abstract class RemoteService extends Service {
/**
* Checks if packageName is a registered app for the API. Does not return true for own package!
- *
+ *
* @param packageName
* @return
* @throws WrongPackageSignatureException