ParcelFileDescriptorUtil.java

  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}