| OLD | NEW |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.chrome.browser.photo_picker; | 5 package org.chromium.chrome.browser.photo_picker; |
| 6 | 6 |
| 7 import android.app.Service; | 7 import android.app.Service; |
| 8 import android.content.Intent; | 8 import android.content.Intent; |
| 9 import android.graphics.Bitmap; | 9 import android.graphics.Bitmap; |
| 10 import android.os.Bundle; | 10 import android.os.Bundle; |
| 11 import android.os.Handler; | 11 import android.os.Handler; |
| 12 import android.os.IBinder; | 12 import android.os.IBinder; |
| 13 import android.os.Message; | 13 import android.os.Message; |
| 14 import android.os.Messenger; | 14 import android.os.Messenger; |
| 15 import android.os.ParcelFileDescriptor; | 15 import android.os.ParcelFileDescriptor; |
| 16 import android.os.RemoteException; | 16 import android.os.RemoteException; |
| 17 import android.os.SystemClock; |
| 17 | 18 |
| 18 import org.chromium.base.Log; | 19 import org.chromium.base.Log; |
| 19 | 20 |
| 20 import java.io.FileDescriptor; | 21 import java.io.FileDescriptor; |
| 21 import java.io.IOException; | 22 import java.io.IOException; |
| 22 | 23 |
| 23 /** | 24 /** |
| 24 * A service to accept requests to take image file contents and decode them. | 25 * A service to accept requests to take image file contents and decode them. |
| 25 */ | 26 */ |
| 26 public class DecoderService extends Service { | 27 public class DecoderService extends Service { |
| 27 // Message ids for communicating with the client. | 28 // Message ids for communicating with the client. |
| 28 | 29 |
| 29 // A message sent by the client to decode an image. | 30 // A message sent by the client to decode an image. |
| 30 static final int MSG_DECODE_IMAGE = 1; | 31 static final int MSG_DECODE_IMAGE = 1; |
| 31 // A message sent by the server to notify the client of the results of the d
ecoding. | 32 // A message sent by the server to notify the client of the results of the d
ecoding. |
| 32 static final int MSG_IMAGE_DECODED_REPLY = 2; | 33 static final int MSG_IMAGE_DECODED_REPLY = 2; |
| 33 | 34 |
| 34 // The keys for the bundle when passing data to and from this service. | 35 // The keys for the bundle when passing data to and from this service. |
| 35 static final String KEY_FILE_DESCRIPTOR = "file_descriptor"; | 36 static final String KEY_FILE_DESCRIPTOR = "file_descriptor"; |
| 36 static final String KEY_FILE_PATH = "file_path"; | 37 static final String KEY_FILE_PATH = "file_path"; |
| 37 static final String KEY_IMAGE_BITMAP = "image_bitmap"; | 38 static final String KEY_IMAGE_BITMAP = "image_bitmap"; |
| 38 static final String KEY_IMAGE_BYTE_COUNT = "image_byte_count"; | 39 static final String KEY_IMAGE_BYTE_COUNT = "image_byte_count"; |
| 39 static final String KEY_IMAGE_DESCRIPTOR = "image_descriptor"; | 40 static final String KEY_IMAGE_DESCRIPTOR = "image_descriptor"; |
| 40 static final String KEY_SIZE = "size"; | 41 static final String KEY_SIZE = "size"; |
| 41 static final String KEY_SUCCESS = "success"; | 42 static final String KEY_SUCCESS = "success"; |
| 43 static final String KEY_DECODE_TIME = "decode_time"; |
| 42 | 44 |
| 43 // A tag for logging error messages. | 45 // A tag for logging error messages. |
| 44 private static final String TAG = "ImageDecoder"; | 46 private static final String TAG = "ImageDecoder"; |
| 45 | 47 |
| 46 /** | 48 /** |
| 47 * Handler for incoming messages from clients. | 49 * Handler for incoming messages from clients. |
| 48 */ | 50 */ |
| 49 static class IncomingHandler extends Handler { | 51 static class IncomingHandler extends Handler { |
| 50 @Override | 52 @Override |
| 51 public void handleMessage(Message msg) { | 53 public void handleMessage(Message msg) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 63 ParcelFileDescriptor pfd = payload.getParcelable(KEY_FIL
E_DESCRIPTOR); | 65 ParcelFileDescriptor pfd = payload.getParcelable(KEY_FIL
E_DESCRIPTOR); |
| 64 size = payload.getInt(KEY_SIZE); | 66 size = payload.getInt(KEY_SIZE); |
| 65 | 67 |
| 66 // Setup a minimum viable response to parent process. Wi
ll be fleshed out | 68 // Setup a minimum viable response to parent process. Wi
ll be fleshed out |
| 67 // further below. | 69 // further below. |
| 68 bundle = new Bundle(); | 70 bundle = new Bundle(); |
| 69 bundle.putString(KEY_FILE_PATH, filePath); | 71 bundle.putString(KEY_FILE_PATH, filePath); |
| 70 bundle.putBoolean(KEY_SUCCESS, false); | 72 bundle.putBoolean(KEY_SUCCESS, false); |
| 71 | 73 |
| 72 FileDescriptor fd = pfd.getFileDescriptor(); | 74 FileDescriptor fd = pfd.getFileDescriptor(); |
| 75 |
| 76 long begin = SystemClock.elapsedRealtime(); |
| 73 Bitmap bitmap = BitmapUtils.decodeBitmapFromFileDescript
or(fd, size); | 77 Bitmap bitmap = BitmapUtils.decodeBitmapFromFileDescript
or(fd, size); |
| 78 long decodeTime = SystemClock.elapsedRealtime() - begin; |
| 79 |
| 74 try { | 80 try { |
| 75 pfd.close(); | 81 pfd.close(); |
| 76 } catch (IOException e) { | 82 } catch (IOException e) { |
| 77 Log.e(TAG, "Closing failed " + filePath + " (size: "
+ size + ") " + e); | 83 Log.e(TAG, "Closing failed " + filePath + " (size: "
+ size + ") " + e); |
| 78 } | 84 } |
| 79 | 85 |
| 80 if (bitmap == null) { | 86 if (bitmap == null) { |
| 81 Log.e(TAG, "Decode failed " + filePath + " (size: "
+ size + ")"); | 87 Log.e(TAG, "Decode failed " + filePath + " (size: "
+ size + ")"); |
| 82 sendReply(client, bundle); // Sends SUCCESS == false
; | 88 sendReply(client, bundle); // Sends SUCCESS == false
; |
| 83 return; | 89 return; |
| 84 } | 90 } |
| 85 | 91 |
| 86 // The most widely supported, easiest, and reasonably ef
ficient method is to | 92 // The most widely supported, easiest, and reasonably ef
ficient method is to |
| 87 // decode to an immutable bitmap and just return the bit
map over binder. It | 93 // decode to an immutable bitmap and just return the bit
map over binder. It |
| 88 // will internally memcpy itself to ashmem and then just
send over the file | 94 // will internally memcpy itself to ashmem and then just
send over the file |
| 89 // descriptor. In the receiving process it will just lea
ve the bitmap on | 95 // descriptor. In the receiving process it will just lea
ve the bitmap on |
| 90 // ashmem since it's immutable and carry on. | 96 // ashmem since it's immutable and carry on. |
| 91 bundle.putParcelable(KEY_IMAGE_BITMAP, bitmap); | 97 bundle.putParcelable(KEY_IMAGE_BITMAP, bitmap); |
| 92 bundle.putBoolean(KEY_SUCCESS, true); | 98 bundle.putBoolean(KEY_SUCCESS, true); |
| 99 bundle.putLong(KEY_DECODE_TIME, decodeTime); |
| 93 sendReply(client, bundle); | 100 sendReply(client, bundle); |
| 94 bitmap.recycle(); | 101 bitmap.recycle(); |
| 95 } catch (Exception e) { | 102 } catch (Exception e) { |
| 96 // This service has no UI and maintains no state so if i
t crashes on | 103 // This service has no UI and maintains no state so if i
t crashes on |
| 97 // decoding a photo, it is better UX to eat the exceptio
n instead of showing | 104 // decoding a photo, it is better UX to eat the exceptio
n instead of showing |
| 98 // a crash dialog and discarding other requests that hav
e already been sent. | 105 // a crash dialog and discarding other requests that hav
e already been sent. |
| 99 Log.e(TAG, | 106 Log.e(TAG, |
| 100 "Unexpected error during decoding " + filePath +
" (size: " + size | 107 "Unexpected error during decoding " + filePath +
" (size: " + size |
| 101 + ") " + e); | 108 + ") " + e); |
| 102 | 109 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 126 | 133 |
| 127 /** | 134 /** |
| 128 * When binding to the service, we return an interface to our messenger | 135 * When binding to the service, we return an interface to our messenger |
| 129 * for sending messages to the service. | 136 * for sending messages to the service. |
| 130 */ | 137 */ |
| 131 @Override | 138 @Override |
| 132 public IBinder onBind(Intent intent) { | 139 public IBinder onBind(Intent intent) { |
| 133 return mMessenger.getBinder(); | 140 return mMessenger.getBinder(); |
| 134 } | 141 } |
| 135 } | 142 } |
| OLD | NEW |