1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.providers.contacts;
18 
19 import android.content.res.Resources;
20 import android.test.suitebuilder.annotation.SmallTest;
21 
22 import com.google.android.collect.Maps;
23 
24 import java.io.ByteArrayOutputStream;
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.util.Map;
28 
29 /**
30  * Adds support for loading photo files easily from test resources.
31  */
32 @SmallTest
33 public class PhotoLoadingTestCase extends FixedAndroidTestCase {
34 
35     private Map<Integer, PhotoEntry> photoResourceCache = Maps.newHashMap();
36     protected static enum PhotoSize {
37         ORIGINAL,
38         DISPLAY_PHOTO,
39         THUMBNAIL
40     }
41 
42     protected final class PhotoEntry {
43         Map<PhotoSize, byte[]> photoMap = Maps.newHashMap();
PhotoEntry(byte[] original)44         public PhotoEntry(byte[] original) {
45             try {
46                 PhotoProcessor processor = newPhotoProcessor(original, false);
47                 photoMap.put(PhotoSize.ORIGINAL, original);
48                 photoMap.put(PhotoSize.DISPLAY_PHOTO, processor.getDisplayPhotoBytes());
49                 photoMap.put(PhotoSize.THUMBNAIL, processor.getThumbnailPhotoBytes());
50             } catch (IOException ignored) {
51                 // Test is probably going to fail as a result anyway.
52             }
53         }
54 
getPhoto(PhotoSize size)55         public byte[] getPhoto(PhotoSize size) {
56             return photoMap.get(size);
57         }
58     }
59 
60     // The test photo will be loaded frequently in tests, so we'll just process it once.
61     private static PhotoEntry testPhotoEntry;
62 
63     /**
64      * Create a new {@link PhotoProcessor} for unit tests.
65      *
66      * The instance generated here is always configured for 256x256 regardless of the
67      * device memory size.
68      */
newPhotoProcessor(byte[] data, boolean forceCropToSquare)69     protected PhotoProcessor newPhotoProcessor(byte[] data, boolean forceCropToSquare)
70             throws IOException {
71         return new PhotoProcessor(data, 256, 96, forceCropToSquare);
72     }
73 
loadTestPhoto()74     protected byte[] loadTestPhoto() {
75         int testPhotoId = com.android.providers.contacts.tests.R.drawable.ic_contact_picture;
76         if (testPhotoEntry == null) {
77             loadPhotoFromResource(testPhotoId, PhotoSize.ORIGINAL);
78             testPhotoEntry = photoResourceCache.get(testPhotoId);
79         }
80         return testPhotoEntry.getPhoto(PhotoSize.ORIGINAL);
81     }
82 
loadTestPhoto(PhotoSize size)83     protected byte[] loadTestPhoto(PhotoSize size) {
84         loadTestPhoto();
85         return testPhotoEntry.getPhoto(size);
86     }
87 
loadPhotoFromResource(int resourceId, PhotoSize size)88     protected byte[] loadPhotoFromResource(int resourceId, PhotoSize size) {
89         PhotoEntry entry = photoResourceCache.get(resourceId);
90         if (entry == null) {
91             final Resources resources = getTestContext().getResources();
92             InputStream is = resources.openRawResource(resourceId);
93             byte[] content = readInputStreamFully(is);
94             entry = new PhotoEntry(content);
95             photoResourceCache.put(resourceId, entry);
96         }
97         return entry.getPhoto(size);
98     }
99 
readInputStreamFully(InputStream is)100     protected byte[] readInputStreamFully(InputStream is) {
101         ByteArrayOutputStream os = new ByteArrayOutputStream();
102         byte[] buffer = new byte[10000];
103         int count;
104         try {
105             while ((count = is.read(buffer)) != -1) {
106                 os.write(buffer, 0, count);
107             }
108             is.close();
109         } catch (IOException e) {
110             throw new RuntimeException(e);
111         }
112         return os.toByteArray();
113     }
114 }
115