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 |