1e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn/* 2e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn * Copyright (C) 2011 The Android Open Source Project 3e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn * 4e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License"); 5e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn * you may not use this file except in compliance with the License. 6e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn * You may obtain a copy of the License at 7e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn * 8e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn * http://www.apache.org/licenses/LICENSE-2.0 9e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn * 10e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn * Unless required by applicable law or agreed to in writing, software 11e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS, 12e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn * See the License for the specific language governing permissions and 14e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn * limitations under the License. 15e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn */ 16e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 17e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackbornpackage com.android.server.am; 18e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 19e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackbornimport java.io.FileDescriptor; 20e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackbornimport java.io.FileInputStream; 21e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackbornimport java.io.FileOutputStream; 22e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackbornimport java.io.IOException; 23e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 24e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackbornimport android.os.Binder; 25e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackbornimport android.os.IBinder; 26e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackbornimport android.os.IInterface; 27e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackbornimport android.os.ParcelFileDescriptor; 28e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackbornimport android.os.RemoteException; 29e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackbornimport android.os.SystemClock; 30e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackbornimport android.util.Slog; 31e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 32e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn/** 33e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn * Helper for transferring data through a pipe from a client app. 34e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn */ 35e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackbornclass TransferPipe implements Runnable { 36e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn static final String TAG = "TransferPipe"; 37e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn static final boolean DEBUG = false; 38e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 39e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn static final long DEFAULT_TIMEOUT = 5000; // 5 seconds 40e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 41e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn final Thread mThread;; 42e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn final ParcelFileDescriptor[] mFds; 43e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 44e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn FileDescriptor mOutFd; 45e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn long mEndTime; 46e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn String mFailure; 47e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn boolean mComplete; 48e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 49e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn String mBufferPrefix; 50e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 51e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn interface Caller { 52e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn void go(IInterface iface, FileDescriptor fd, String prefix, 53e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn String[] args) throws RemoteException; 54e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 55e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 56e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn TransferPipe() throws IOException { 57e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn mThread = new Thread(this, "TransferPipe"); 58e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn mFds = ParcelFileDescriptor.createPipe(); 59e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 60e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 61e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn ParcelFileDescriptor getReadFd() { 62e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn return mFds[0]; 63e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 64e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 65e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn ParcelFileDescriptor getWriteFd() { 66e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn return mFds[1]; 67e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 68e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 69e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn void setBufferPrefix(String prefix) { 70e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn mBufferPrefix = prefix; 71e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 72e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 73e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn static void go(Caller caller, IInterface iface, FileDescriptor out, 74e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn String prefix, String[] args) throws IOException, RemoteException { 75e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn go(caller, iface, out, prefix, args, DEFAULT_TIMEOUT); 76e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 77e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 78e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn static void go(Caller caller, IInterface iface, FileDescriptor out, 79e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn String prefix, String[] args, long timeout) throws IOException, RemoteException { 80e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn if ((iface.asBinder()) instanceof Binder) { 81e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn // This is a local object... just call it directly. 82e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn try { 83e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn caller.go(iface, out, prefix, args); 84e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } catch (RemoteException e) { 85e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 86e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn return; 87e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 88e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 89e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn TransferPipe tp = new TransferPipe(); 90e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn try { 91e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn caller.go(iface, tp.getWriteFd().getFileDescriptor(), prefix, args); 92e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn tp.go(out, timeout); 93e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } finally { 94e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn tp.kill(); 95e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 96e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 97e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 98e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn static void goDump(IBinder binder, FileDescriptor out, 99e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn String[] args) throws IOException, RemoteException { 100e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn goDump(binder, out, args, DEFAULT_TIMEOUT); 101e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 102e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 103e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn static void goDump(IBinder binder, FileDescriptor out, 104e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn String[] args, long timeout) throws IOException, RemoteException { 105e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn if (binder instanceof Binder) { 106e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn // This is a local object... just call it directly. 107e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn try { 108e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn binder.dump(out, args); 109e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } catch (RemoteException e) { 110e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 111e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn return; 112e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 113e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 114e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn TransferPipe tp = new TransferPipe(); 115e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn try { 116e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn binder.dumpAsync(tp.getWriteFd().getFileDescriptor(), args); 117e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn tp.go(out, timeout); 118e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } finally { 119e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn tp.kill(); 120e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 121e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 122e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 123e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn void go(FileDescriptor out) throws IOException { 124e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn go(out, DEFAULT_TIMEOUT); 125e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 126e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 127e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn void go(FileDescriptor out, long timeout) throws IOException { 128e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn try { 129e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn synchronized (this) { 130e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn mOutFd = out; 131e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn mEndTime = SystemClock.uptimeMillis() + timeout; 132e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 133e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn if (DEBUG) Slog.i(TAG, "read=" + getReadFd() + " write=" + getWriteFd() 134e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn + " out=" + out); 135e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 136e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn // Close the write fd, so we know when the other side is done. 137e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn closeFd(1); 138e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 139e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn mThread.start(); 140e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 141e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn while (mFailure == null && !mComplete) { 142e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn long waitTime = mEndTime - SystemClock.uptimeMillis(); 143e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn if (waitTime <= 0) { 144e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn if (DEBUG) Slog.i(TAG, "TIMEOUT!"); 145e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn mThread.interrupt(); 146e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn throw new IOException("Timeout"); 147e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 148e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 149e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn try { 150e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn wait(waitTime); 151e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } catch (InterruptedException e) { 152e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 153e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 154e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 155e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn if (DEBUG) Slog.i(TAG, "Finished: " + mFailure); 156e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn if (mFailure != null) { 157e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn throw new IOException(mFailure); 158e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 159e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 160e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } finally { 161e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn kill(); 162e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 163e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 164e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 165e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn void closeFd(int num) { 166e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn if (mFds[num] != null) { 167e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn if (DEBUG) Slog.i(TAG, "Closing: " + mFds[num]); 168e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn try { 169e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn mFds[num].close(); 170e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } catch (IOException e) { 171e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 172e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn mFds[num] = null; 173e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 174e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 175e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 176e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn void kill() { 177e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn closeFd(0); 178e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn closeFd(1); 179e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 180e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 181e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn @Override 182e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn public void run() { 183e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn final byte[] buffer = new byte[1024]; 184e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn final FileInputStream fis = new FileInputStream(getReadFd().getFileDescriptor()); 185e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn final FileOutputStream fos = new FileOutputStream(mOutFd); 186e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 187e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn if (DEBUG) Slog.i(TAG, "Ready to read pipe..."); 188e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn byte[] bufferPrefix = null; 189e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn boolean needPrefix = true; 190e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn if (mBufferPrefix != null) { 191e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn bufferPrefix = mBufferPrefix.getBytes(); 192e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 193e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 194e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn int size; 195e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn try { 196e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn while ((size=fis.read(buffer)) > 0) { 197e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn if (DEBUG) Slog.i(TAG, "Got " + size + " bytes"); 198e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn if (bufferPrefix == null) { 199e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn fos.write(buffer, 0, size); 200e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } else { 201e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn int start = 0; 202e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn for (int i=0; i<size; i++) { 203e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn if (buffer[i] != '\n') { 204e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn if (i > start) { 205e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn fos.write(buffer, start, i-start); 206e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 207e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn start = i; 208e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn if (needPrefix) { 209e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn fos.write(bufferPrefix); 210e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn needPrefix = false; 211e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 212e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn do { 213e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn i++; 214e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } while (i<size && buffer[i] != '\n'); 215e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn if (i < size) { 216e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn needPrefix = true; 217e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 218e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 219e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 220e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn if (size > start) { 221e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn fos.write(buffer, start, size-start); 222e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 223e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 224e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 225e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn if (DEBUG) Slog.i(TAG, "End of pipe: size=" + size); 226e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn if (mThread.isInterrupted()) { 227e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn if (DEBUG) Slog.i(TAG, "Interrupted!"); 228e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 229e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } catch (IOException e) { 230e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn synchronized (this) { 231e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn mFailure = e.toString(); 232e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn notifyAll(); 233e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn return; 234e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 235e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 236e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn 237e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn synchronized (this) { 238e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn mComplete = true; 239e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn notifyAll(); 240e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 241e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn } 242e17aeb31030cfeed339a39a107912ad5e9178390Dianne Hackborn} 243