• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 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.gallery3d.common;
18 
19 import android.app.admin.DevicePolicyManager;
20 import android.content.ComponentName;
21 import android.hardware.Camera;
22 import android.os.Build;
23 import android.provider.MediaStore.MediaColumns;
24 import android.view.View;
25 import android.view.WindowManager;
26 
27 import java.lang.ClassNotFoundException;
28 import java.lang.reflect.Field;
29 import java.lang.reflect.Method;
30 import java.util.Arrays;
31 
32 public class ApiHelper {
33     public static interface VERSION_CODES {
34         // These value are copied from Build.VERSION_CODES
35         public static final int GINGERBREAD_MR1 = 10;
36         public static final int HONEYCOMB = 11;
37         public static final int HONEYCOMB_MR1 = 12;
38         public static final int HONEYCOMB_MR2 = 13;
39         public static final int ICE_CREAM_SANDWICH = 14;
40         public static final int ICE_CREAM_SANDWICH_MR1 = 15;
41         public static final int JELLY_BEAN = 16;
42         public static final int JELLY_BEAN_MR1 = 17;
43         public static final int JELLY_BEAN_MR2 = 18;
44     }
45 
46     public static final boolean AT_LEAST_16 = Build.VERSION.SDK_INT >= 16;
47 
48     public static final boolean USE_888_PIXEL_FORMAT =
49             Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN;
50 
51     public static final boolean ENABLE_PHOTO_EDITOR =
52             Build.VERSION.SDK_INT >= VERSION_CODES.ICE_CREAM_SANDWICH;
53 
54     public static final boolean HAS_VIEW_SYSTEM_UI_FLAG_LAYOUT_STABLE =
55             hasField(View.class, "SYSTEM_UI_FLAG_LAYOUT_STABLE");
56 
57     public static final boolean HAS_VIEW_SYSTEM_UI_FLAG_HIDE_NAVIGATION =
58             hasField(View.class, "SYSTEM_UI_FLAG_HIDE_NAVIGATION");
59 
60     public static final boolean HAS_MEDIA_COLUMNS_WIDTH_AND_HEIGHT =
61             hasField(MediaColumns.class, "WIDTH");
62 
63     public static final boolean HAS_REUSING_BITMAP_IN_BITMAP_REGION_DECODER =
64             Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN;
65 
66     public static final boolean HAS_REUSING_BITMAP_IN_BITMAP_FACTORY =
67             Build.VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB;
68 
69     public static final boolean HAS_SET_BEAM_PUSH_URIS =
70             Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN;
71 
72     public static final boolean HAS_SET_DEFALT_BUFFER_SIZE = hasMethod(
73             "android.graphics.SurfaceTexture", "setDefaultBufferSize",
74             int.class, int.class);
75 
76     public static final boolean HAS_RELEASE_SURFACE_TEXTURE = hasMethod(
77             "android.graphics.SurfaceTexture", "release");
78 
79     public static final boolean HAS_SURFACE_TEXTURE =
80             Build.VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB;
81 
82     public static final boolean HAS_MTP =
83             Build.VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB_MR1;
84 
85     public static final boolean HAS_AUTO_FOCUS_MOVE_CALLBACK =
86             Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN;
87 
88     public static final boolean HAS_REMOTE_VIEWS_SERVICE =
89             Build.VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB;
90 
91     public static final boolean HAS_INTENT_EXTRA_LOCAL_ONLY =
92             Build.VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB;
93 
94     public static final boolean HAS_SET_SYSTEM_UI_VISIBILITY =
95             hasMethod(View.class, "setSystemUiVisibility", int.class);
96 
97     public static final boolean HAS_FACE_DETECTION;
98     static {
99         boolean hasFaceDetection = false;
100         try {
101             Class<?> listenerClass = Class.forName(
102                     "android.hardware.Camera$FaceDetectionListener");
103             hasFaceDetection =
104                     hasMethod(Camera.class, "setFaceDetectionListener", listenerClass) &&
105                     hasMethod(Camera.class, "startFaceDetection") &&
106                     hasMethod(Camera.class, "stopFaceDetection") &&
107                     hasMethod(Camera.Parameters.class, "getMaxNumDetectedFaces");
108         } catch (Throwable t) {
109         }
110         HAS_FACE_DETECTION = hasFaceDetection;
111     }
112 
113     public static final boolean HAS_GET_CAMERA_DISABLED =
114             hasMethod(DevicePolicyManager.class, "getCameraDisabled", ComponentName.class);
115 
116     public static final boolean HAS_MEDIA_ACTION_SOUND =
117             Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN;
118 
119     public static final boolean HAS_TIME_LAPSE_RECORDING =
120             Build.VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB;
121 
122     public static final boolean HAS_ZOOM_WHEN_RECORDING =
123             Build.VERSION.SDK_INT >= VERSION_CODES.ICE_CREAM_SANDWICH;
124 
125     public static final boolean HAS_CAMERA_FOCUS_AREA =
126             Build.VERSION.SDK_INT >= VERSION_CODES.ICE_CREAM_SANDWICH;
127 
128     public static final boolean HAS_CAMERA_METERING_AREA =
129             Build.VERSION.SDK_INT >= VERSION_CODES.ICE_CREAM_SANDWICH;
130 
131     public static final boolean HAS_MOTION_EVENT_TRANSFORM =
132             Build.VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB;
133 
134     public static final boolean HAS_EFFECTS_RECORDING = false;
135 
136     // "Background" filter does not have "context" input port in jelly bean.
137     public static final boolean HAS_EFFECTS_RECORDING_CONTEXT_INPUT =
138             Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN_MR1;
139 
140     public static final boolean HAS_GET_SUPPORTED_VIDEO_SIZE =
141             Build.VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB;
142 
143     public static final boolean HAS_SET_ICON_ATTRIBUTE =
144             Build.VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB;
145 
146     public static final boolean HAS_MEDIA_PROVIDER_FILES_TABLE =
147             Build.VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB;
148 
149     public static final boolean HAS_SURFACE_TEXTURE_RECORDING =
150             Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN;
151 
152     public static final boolean HAS_ACTION_BAR =
153             Build.VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB;
154 
155     // Ex: View.setTranslationX.
156     public static final boolean HAS_VIEW_TRANSFORM_PROPERTIES =
157             Build.VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB;
158 
159     public static final boolean HAS_CAMERA_HDR =
160             Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN_MR1;
161 
162     public static final boolean HAS_OPTIONS_IN_MUTABLE =
163             Build.VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB;
164 
165     public static final boolean CAN_START_PREVIEW_IN_JPEG_CALLBACK =
166             Build.VERSION.SDK_INT >= VERSION_CODES.ICE_CREAM_SANDWICH;
167 
168     public static final boolean HAS_VIEW_PROPERTY_ANIMATOR =
169             Build.VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB_MR1;
170 
171     public static final boolean HAS_POST_ON_ANIMATION =
172             Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN;
173 
174     public static final boolean HAS_ANNOUNCE_FOR_ACCESSIBILITY =
175             Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN;
176 
177     public static final boolean HAS_OBJECT_ANIMATION =
178             Build.VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB;
179 
180     public static final boolean HAS_GLES20_REQUIRED =
181             Build.VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB;
182 
183     public static final boolean HAS_ROTATION_ANIMATION =
184             hasField(WindowManager.LayoutParams.class, "rotationAnimation");
185 
186     public static final boolean HAS_ORIENTATION_LOCK =
187             Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN_MR2;
188 
189     public static final boolean HAS_CANCELLATION_SIGNAL =
190             Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN;
191 
192     public static final boolean HAS_MEDIA_MUXER =
193                     Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN_MR2;
194 
195     public static final boolean HAS_DISPLAY_LISTENER =
196             Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN_MR1;
197 
getIntFieldIfExists(Class<?> klass, String fieldName, Class<?> obj, int defaultVal)198     public static int getIntFieldIfExists(Class<?> klass, String fieldName,
199             Class<?> obj, int defaultVal) {
200         try {
201             Field f = klass.getDeclaredField(fieldName);
202             return f.getInt(obj);
203         } catch (Exception e) {
204             return defaultVal;
205         }
206     }
207 
hasField(Class<?> klass, String fieldName)208     private static boolean hasField(Class<?> klass, String fieldName) {
209         for (Field f : klass.getDeclaredFields()) {
210             if (f.getName().equals(fieldName)) {
211                 return true;
212             }
213         }
214         return false;
215     }
216 
hasMethod(String className, String methodName, Class<?>... parameterTypes)217     private static boolean hasMethod(String className, String methodName,
218             Class<?>... parameterTypes) {
219         try {
220             Class<?> klass = Class.forName(className);
221             return hasMethod(klass, methodName, parameterTypes);
222         } catch (ClassNotFoundException e) {
223             return false;
224         }
225     }
226 
hasMethod( Class<?> klass, String methodName, Class<?> ... paramTypes)227     private static boolean hasMethod(
228             Class<?> klass, String methodName, Class<?> ... paramTypes) {
229         for (Method method : klass.getDeclaredMethods()) {
230             if (method.getName().equals(methodName) &&
231                 Arrays.equals(method.getParameterTypes(), paramTypes)) {
232                 return true;
233             }
234         }
235         return false;
236     }
237 }
238