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.AndroidTestCase;
21 import android.test.suitebuilder.annotation.SmallTest;
22 
23 import com.google.android.collect.Maps;
24 
25 import java.io.ByteArrayOutputStream;
26 import java.io.IOException;
27 import java.io.InputStream;
28 import java.util.Map;
29 
30 /**
31  * Adds support for loading photo files easily from test resources.
32  */
33 @SmallTest
34 public class PhotoLoadingTestCase extends AndroidTestCase {
35 
36     private Map<Integer, PhotoEntry> photoResourceCache = Maps.newHashMap();
37     protected static enum PhotoSize {
38         ORIGINAL,
39         DISPLAY_PHOTO,
40         THUMBNAIL
41     }
42 
43     protected final class PhotoEntry {
44         Map<PhotoSize, byte[]> photoMap = Maps.newHashMap();
PhotoEntry(byte[] original)45         public PhotoEntry(byte[] original) {
46             try {
47                 PhotoProcessor processor = newPhotoProcessor(original, false);
48                 photoMap.put(PhotoSize.ORIGINAL, original);
49                 photoMap.put(PhotoSize.DISPLAY_PHOTO, processor.getDisplayPhotoBytes());
50                 photoMap.put(PhotoSize.THUMBNAIL, processor.getThumbnailPhotoBytes());
51             } catch (IOException ignored) {
52                 // Test is probably going to fail as a result anyway.
53             }
54         }
55 
getPhoto(PhotoSize size)56         public byte[] getPhoto(PhotoSize size) {
57             return photoMap.get(size);
58         }
59     }
60 
61     // The test photo will be loaded frequently in tests, so we'll just process it once.
62     private static PhotoEntry testPhotoEntry;
63 
64     /**
65      * Create a new {@link PhotoProcessor} for unit tests.
66      *
67      * The instance generated here is always configured for 256x256 regardless of the
68      * device memory size.
69      */
newPhotoProcessor(byte[] data, boolean forceCropToSquare)70     protected PhotoProcessor newPhotoProcessor(byte[] data, boolean forceCropToSquare)
71             throws IOException {
72         return new PhotoProcessor(data, 256, 96, forceCropToSquare);
73     }
74 
loadTestPhoto()75     protected byte[] loadTestPhoto() {
76         int testPhotoId = com.android.providers.contacts.tests.R.drawable.ic_contact_picture;
77         if (testPhotoEntry == null) {
78             loadPhotoFromResource(testPhotoId, PhotoSize.ORIGINAL);
79             testPhotoEntry = photoResourceCache.get(testPhotoId);
80         }
81         return testPhotoEntry.getPhoto(PhotoSize.ORIGINAL);
82     }
83 
loadTestPhoto(PhotoSize size)84     protected byte[] loadTestPhoto(PhotoSize size) {
85         loadTestPhoto();
86         return testPhotoEntry.getPhoto(size);
87     }
88 
loadPhotoFromResource(int resourceId, PhotoSize size)89     protected byte[] loadPhotoFromResource(int resourceId, PhotoSize size) {
90         PhotoEntry entry = photoResourceCache.get(resourceId);
91         if (entry == null) {
92             final Resources resources = getTestContext().getResources();
93             InputStream is = resources.openRawResource(resourceId);
94             byte[] content = readInputStreamFully(is);
95             entry = new PhotoEntry(content);
96             photoResourceCache.put(resourceId, entry);
97         }
98         return entry.getPhoto(size);
99     }
100 
readInputStreamFully(InputStream is)101     protected byte[] readInputStreamFully(InputStream is) {
102         ByteArrayOutputStream os = new ByteArrayOutputStream();
103         byte[] buffer = new byte[10000];
104         int count;
105         try {
106             while ((count = is.read(buffer)) != -1) {
107                 os.write(buffer, 0, count);
108             }
109             is.close();
110         } catch (IOException e) {
111             throw new RuntimeException(e);
112         }
113         return os.toByteArray();
114     }
115 }
116