1/*
2 * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
3 * 2013 Flow (http://stackoverflow.com/questions/18212152/transfer-inputstream-to-another-service-across-process-boundaries-with-parcelf)
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package org.openintents.openpgp.util;
19
20import android.os.ParcelFileDescriptor;
21
22import java.io.IOException;
23import java.io.InputStream;
24import java.io.OutputStream;
25
26public class ParcelFileDescriptorUtil {
27
28 public interface IThreadListener {
29 void onThreadFinished(final Thread thread);
30 }
31
32 public static ParcelFileDescriptor pipeFrom(InputStream inputStream, IThreadListener listener)
33 throws IOException {
34 ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe();
35 ParcelFileDescriptor readSide = pipe[0];
36 ParcelFileDescriptor writeSide = pipe[1];
37
38 // start the transfer thread
39 new TransferThread(inputStream, new ParcelFileDescriptor.AutoCloseOutputStream(writeSide),
40 listener)
41 .start();
42
43 return readSide;
44 }
45
46 public static ParcelFileDescriptor pipeTo(OutputStream outputStream, IThreadListener listener)
47 throws IOException {
48 ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe();
49 ParcelFileDescriptor readSide = pipe[0];
50 ParcelFileDescriptor writeSide = pipe[1];
51
52 // start the transfer thread
53 new TransferThread(new ParcelFileDescriptor.AutoCloseInputStream(readSide), outputStream,
54 listener)
55 .start();
56
57 return writeSide;
58 }
59
60 static class TransferThread extends Thread {
61 final InputStream mIn;
62 final OutputStream mOut;
63 final IThreadListener mListener;
64
65 TransferThread(InputStream in, OutputStream out, IThreadListener listener) {
66 super("ParcelFileDescriptor Transfer Thread");
67 mIn = in;
68 mOut = out;
69 mListener = listener;
70 setDaemon(true);
71 }
72
73 @Override
74 public void run() {
75 byte[] buf = new byte[1024];
76 int len;
77
78 try {
79 while ((len = mIn.read(buf)) > 0) {
80 mOut.write(buf, 0, len);
81 }
82 mOut.flush(); // just to be safe
83 } catch (IOException e) {
84 //Log.e(OpenPgpApi.TAG, "TransferThread" + getId() + ": writing failed", e);
85 } finally {
86 try {
87 mIn.close();
88 } catch (IOException e) {
89 //Log.e(OpenPgpApi.TAG, "TransferThread" + getId(), e);
90 }
91 try {
92 mOut.close();
93 } catch (IOException e) {
94 //Log.e(OpenPgpApi.TAG, "TransferThread" + getId(), e);
95 }
96 }
97 if (mListener != null) {
98 //Log.d(OpenPgpApi.TAG, "TransferThread " + getId() + " finished!");
99 mListener.onThreadFinished(this);
100 }
101 }
102 }
103}