From 9d8104e15c21294a21a421a02303c9586f823e96 Mon Sep 17 00:00:00 2001 From: mgeier63 Date: Wed, 26 Aug 2015 11:13:38 +0200 Subject: initial mod --- .../org/openintents/openpgp/IOpenPgpService.aidl | 1 + .../org/openintents/openpgp/IOpenPgpService2.aidl | 23 +++++++++++ .../org/openintents/openpgp/util/OpenPgpApi.java | 44 +++++++++----------- .../openpgp/util/OpenPgpAppPreference.java | 2 +- .../openpgp/util/OpenPgpKeyPreference.java | 4 +- .../openpgp/util/OpenPgpServiceConnection.java | 12 +++--- .../org/openintents/openpgp/util/OpenPgpUtils.java | 2 +- .../openpgp/util/ParcelFileDescriptorUtil.java | 48 +++++++--------------- 8 files changed, 69 insertions(+), 67 deletions(-) create mode 100644 openpgp-api/src/main/aidl/org/openintents/openpgp/IOpenPgpService2.aidl diff --git a/openpgp-api/src/main/aidl/org/openintents/openpgp/IOpenPgpService.aidl b/openpgp-api/src/main/aidl/org/openintents/openpgp/IOpenPgpService.aidl index 2451207..8fa619b 100644 --- a/openpgp-api/src/main/aidl/org/openintents/openpgp/IOpenPgpService.aidl +++ b/openpgp-api/src/main/aidl/org/openintents/openpgp/IOpenPgpService.aidl @@ -19,6 +19,7 @@ package org.openintents.openpgp; interface IOpenPgpService { // see OpenPgpApi for documentation + //DEPRECATED, do NOT use this, data returned from the service through "output" may be truncated Intent execute(in Intent data, in ParcelFileDescriptor input, in ParcelFileDescriptor output); } \ No newline at end of file diff --git a/openpgp-api/src/main/aidl/org/openintents/openpgp/IOpenPgpService2.aidl b/openpgp-api/src/main/aidl/org/openintents/openpgp/IOpenPgpService2.aidl new file mode 100644 index 0000000..daca0ee --- /dev/null +++ b/openpgp-api/src/main/aidl/org/openintents/openpgp/IOpenPgpService2.aidl @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2014-2015 Dominik Schürmann + * + * 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; + +interface IOpenPgpService2 { + + ParcelFileDescriptor createOutputPipe(in int pipeId); + Intent execute(in Intent data, in ParcelFileDescriptor input, int pipeId); +} \ No newline at end of file diff --git a/openpgp-api/src/main/java/org/openintents/openpgp/util/OpenPgpApi.java b/openpgp-api/src/main/java/org/openintents/openpgp/util/OpenPgpApi.java index bb11556..feac6b9 100644 --- a/openpgp-api/src/main/java/org/openintents/openpgp/util/OpenPgpApi.java +++ b/openpgp-api/src/main/java/org/openintents/openpgp/util/OpenPgpApi.java @@ -24,18 +24,19 @@ import android.os.Build; import android.os.ParcelFileDescriptor; import android.util.Log; -import org.openintents.openpgp.IOpenPgpService; +import org.openintents.openpgp.IOpenPgpService2; import org.openintents.openpgp.OpenPgpError; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.util.concurrent.atomic.AtomicInteger; public class OpenPgpApi { public static final String TAG = "OpenPgp API"; - public static final String SERVICE_INTENT = "org.openintents.openpgp.IOpenPgpService"; + public static final String SERVICE_INTENT_2 = "org.openintents.openpgp.IOpenPgpService2"; /** * see CHANGELOG.md @@ -253,10 +254,11 @@ public class OpenPgpApi { public static final String EXTRA_CALL_UUID1 = "call_uuid1"; public static final String EXTRA_CALL_UUID2 = "call_uuid2"; - IOpenPgpService mService; + IOpenPgpService2 mService; Context mContext; + final AtomicInteger mPipeIdGen = new AtomicInteger(); - public OpenPgpApi(Context context, IOpenPgpService service) { + public OpenPgpApi(Context context, IOpenPgpService2 service) { this.mContext = context; this.mService = service; } @@ -314,38 +316,32 @@ public class OpenPgpApi { Intent result; - // pipe the input and output if (is != null) { - input = ParcelFileDescriptorUtil.pipeFrom(is, - new ParcelFileDescriptorUtil.IThreadListener() { - - @Override - public void onThreadFinished(Thread thread) { - //Log.d(OpenPgpApi.TAG, "Copy to service finished"); - } - } - ); + input = ParcelFileDescriptorUtil.pipeFrom(is); } + + Thread pumpThread =null; + int outputPipeId = 0; + if (os != null) { - output = ParcelFileDescriptorUtil.pipeTo(os, - new ParcelFileDescriptorUtil.IThreadListener() { - - @Override - public void onThreadFinished(Thread thread) { - //Log.d(OpenPgpApi.TAG, "Service finished writing!"); - } - } - ); + outputPipeId = mPipeIdGen.incrementAndGet(); + output = mService.createOutputPipe(outputPipeId); + pumpThread = ParcelFileDescriptorUtil.pipeTo(os, output); } // blocks until result is ready - result = mService.execute(data, input, output); + result = mService.execute(data, input, outputPipeId); // set class loader to current context to allow unparcelling // of OpenPgpError and OpenPgpSignatureResult // http://stackoverflow.com/a/3806769 result.setExtrasClassLoader(mContext.getClassLoader()); + //wait for ALL data being pumped from remote side + if (pumpThread != null) { + pumpThread.join(); + } + return result; } catch (Exception e) { Log.e(OpenPgpApi.TAG, "Exception in executeApi call", e); diff --git a/openpgp-api/src/main/java/org/openintents/openpgp/util/OpenPgpAppPreference.java b/openpgp-api/src/main/java/org/openintents/openpgp/util/OpenPgpAppPreference.java index 4bf4cec..6cd6b90 100644 --- a/openpgp-api/src/main/java/org/openintents/openpgp/util/OpenPgpAppPreference.java +++ b/openpgp-api/src/main/java/org/openintents/openpgp/util/OpenPgpAppPreference.java @@ -263,7 +263,7 @@ public class OpenPgpAppPreference extends DialogPreference { // search for OpenPGP providers... ArrayList providerList = new ArrayList<>(); - Intent intent = new Intent(OpenPgpApi.SERVICE_INTENT); + Intent intent = new Intent(OpenPgpApi.SERVICE_INTENT_2); List resInfo = getContext().getPackageManager().queryIntentServices(intent, 0); if (!resInfo.isEmpty()) { for (ResolveInfo resolveInfo : resInfo) { diff --git a/openpgp-api/src/main/java/org/openintents/openpgp/util/OpenPgpKeyPreference.java b/openpgp-api/src/main/java/org/openintents/openpgp/util/OpenPgpKeyPreference.java index e4ef0a6..eb5693d 100644 --- a/openpgp-api/src/main/java/org/openintents/openpgp/util/OpenPgpKeyPreference.java +++ b/openpgp-api/src/main/java/org/openintents/openpgp/util/OpenPgpKeyPreference.java @@ -29,7 +29,7 @@ import android.text.TextUtils; import android.util.AttributeSet; import android.util.Log; -import org.openintents.openpgp.IOpenPgpService; +import org.openintents.openpgp.IOpenPgpService2; import org.openintents.openpgp.OpenPgpError; import org.openintents.openpgp.R; @@ -78,7 +78,7 @@ public class OpenPgpKeyPreference extends Preference { mOpenPgpProvider, new OpenPgpServiceConnection.OnBound() { @Override - public void onBound(IOpenPgpService service) { + public void onBound(IOpenPgpService2 service) { getSignKeyId(new Intent()); } diff --git a/openpgp-api/src/main/java/org/openintents/openpgp/util/OpenPgpServiceConnection.java b/openpgp-api/src/main/java/org/openintents/openpgp/util/OpenPgpServiceConnection.java index bbc8645..3fee60d 100644 --- a/openpgp-api/src/main/java/org/openintents/openpgp/util/OpenPgpServiceConnection.java +++ b/openpgp-api/src/main/java/org/openintents/openpgp/util/OpenPgpServiceConnection.java @@ -22,20 +22,20 @@ import android.content.Intent; import android.content.ServiceConnection; import android.os.IBinder; -import org.openintents.openpgp.IOpenPgpService; +import org.openintents.openpgp.IOpenPgpService2; public class OpenPgpServiceConnection { // callback interface public interface OnBound { - public void onBound(IOpenPgpService service); + public void onBound(IOpenPgpService2 service); public void onError(Exception e); } private Context mApplicationContext; - private IOpenPgpService mService; + private IOpenPgpService2 mService; private String mProviderPackageName; private OnBound mOnBoundListener; @@ -66,7 +66,7 @@ public class OpenPgpServiceConnection { this.mOnBoundListener = onBoundListener; } - public IOpenPgpService getService() { + public IOpenPgpService2 getService() { return mService; } @@ -76,7 +76,7 @@ public class OpenPgpServiceConnection { private ServiceConnection mServiceConnection = new ServiceConnection() { public void onServiceConnected(ComponentName name, IBinder service) { - mService = IOpenPgpService.Stub.asInterface(service); + mService = IOpenPgpService2.Stub.asInterface(service); if (mOnBoundListener != null) { mOnBoundListener.onBound(mService); } @@ -96,7 +96,7 @@ public class OpenPgpServiceConnection { // if not already bound... if (mService == null) { try { - Intent serviceIntent = new Intent(OpenPgpApi.SERVICE_INTENT); + Intent serviceIntent = new Intent(OpenPgpApi.SERVICE_INTENT_2); // NOTE: setPackage is very important to restrict the intent to this provider only! serviceIntent.setPackage(mProviderPackageName); boolean connect = mApplicationContext.bindService(serviceIntent, mServiceConnection, diff --git a/openpgp-api/src/main/java/org/openintents/openpgp/util/OpenPgpUtils.java b/openpgp-api/src/main/java/org/openintents/openpgp/util/OpenPgpUtils.java index ad5f47b..cb8771a 100644 --- a/openpgp-api/src/main/java/org/openintents/openpgp/util/OpenPgpUtils.java +++ b/openpgp-api/src/main/java/org/openintents/openpgp/util/OpenPgpUtils.java @@ -54,7 +54,7 @@ public class OpenPgpUtils { } public static boolean isAvailable(Context context) { - Intent intent = new Intent(OpenPgpApi.SERVICE_INTENT); + Intent intent = new Intent(OpenPgpApi.SERVICE_INTENT_2); List resInfo = context.getPackageManager().queryIntentServices(intent, 0); return !resInfo.isEmpty(); } diff --git a/openpgp-api/src/main/java/org/openintents/openpgp/util/ParcelFileDescriptorUtil.java b/openpgp-api/src/main/java/org/openintents/openpgp/util/ParcelFileDescriptorUtil.java index b9492f9..461a5ba 100644 --- a/openpgp-api/src/main/java/org/openintents/openpgp/util/ParcelFileDescriptorUtil.java +++ b/openpgp-api/src/main/java/org/openintents/openpgp/util/ParcelFileDescriptorUtil.java @@ -23,84 +23,66 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -/** - * Partially based on Stackoverflow: Transfer InputStream to another Service (across process boundaries) - **/ public class ParcelFileDescriptorUtil { - public interface IThreadListener { - void onThreadFinished(final Thread thread); - } - - public static ParcelFileDescriptor pipeFrom(InputStream inputStream, IThreadListener listener) + public static ParcelFileDescriptor pipeFrom(InputStream inputStream) throws IOException { ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe(); ParcelFileDescriptor readSide = pipe[0]; ParcelFileDescriptor writeSide = pipe[1]; - // start the transfer thread - new TransferThread(inputStream, new ParcelFileDescriptor.AutoCloseOutputStream(writeSide), - listener) + new TransferThread(inputStream, new ParcelFileDescriptor.AutoCloseOutputStream(writeSide)) .start(); return readSide; } - public static ParcelFileDescriptor pipeTo(OutputStream outputStream, IThreadListener listener) + + public static TransferThread pipeTo(OutputStream outputStream, ParcelFileDescriptor output) throws IOException { - ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe(); - ParcelFileDescriptor readSide = pipe[0]; - ParcelFileDescriptor writeSide = pipe[1]; - // start the transfer thread - new TransferThread(new ParcelFileDescriptor.AutoCloseInputStream(readSide), outputStream, - listener) - .start(); + TransferThread t = new TransferThread(new ParcelFileDescriptor.AutoCloseInputStream(output), outputStream); - return writeSide; + t.start(); + return t; } + static class TransferThread extends Thread { final InputStream mIn; final OutputStream mOut; - final IThreadListener mListener; - TransferThread(InputStream in, OutputStream out, IThreadListener listener) { - super("ParcelFileDescriptor Transfer Thread"); + TransferThread(InputStream in, OutputStream out) { + super("IPC Transfer Thread"); mIn = in; mOut = out; - mListener = listener; setDaemon(true); } @Override public void run() { - byte[] buf = new byte[1024]; + byte[] buf = new byte[4096]; int len; try { while ((len = mIn.read(buf)) > 0) { mOut.write(buf, 0, len); } - mOut.flush(); // just to be safe } catch (IOException e) { - //Log.e(OpenPgpApi.TAG, "TransferThread" + getId() + ": writing failed", e); + e.printStackTrace(); } finally { try { mIn.close(); } catch (IOException e) { - //Log.e(OpenPgpApi.TAG, "TransferThread" + getId(), e); + e.printStackTrace(); } try { mOut.close(); } catch (IOException e) { - //Log.e(OpenPgpApi.TAG, "TransferThread" + getId(), e); + e.printStackTrace(); } } - if (mListener != null) { - //Log.d(OpenPgpApi.TAG, "TransferThread " + getId() + " finished!"); - mListener.onThreadFinished(this); - } } } + } -- cgit v1.2.3