1 /*
2  * Copyright (C) 2014 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.camera.widget;
18 
19 import android.content.Context;
20 import android.content.res.TypedArray;
21 import android.graphics.drawable.Drawable;
22 import android.view.View;
23 import android.widget.ImageView;
24 
25 import com.android.camera.ButtonManager;
26 import com.android.camera.app.AppController;
27 import com.android.camera.debug.Log;
28 import com.android.camera.settings.Keys;
29 import com.android.camera.settings.SettingsManager;
30 import com.android.camera.util.PhotoSphereHelper;
31 import com.android.camera2.R;
32 
33 /**
34  * IndicatorIconController sets the visibility and icon state of
35  * on screen indicators.
36  *
37  * Indicators are only visible if they are in a non-default state.  The
38  * visibility of an indicator is set when an indicator's setting changes.
39  */
40 public class IndicatorIconController
41     implements SettingsManager.OnSettingChangedListener,
42                ButtonManager.ButtonStatusListener {
43 
44     private final static Log.Tag TAG = new Log.Tag("IndicatorIconCtrlr");
45 
46     private ImageView mFlashIndicator;
47     private ImageView mHdrIndicator;
48     private ImageView mPanoIndicator;
49     private ImageView mCountdownTimerIndicator;
50 
51     private ImageView mExposureIndicatorN2;
52     private ImageView mExposureIndicatorN1;
53     private ImageView mExposureIndicatorP1;
54     private ImageView mExposureIndicatorP2;
55 
56     private TypedArray mFlashIndicatorPhotoIcons;
57     private TypedArray mFlashIndicatorVideoIcons;
58     private TypedArray mHdrPlusIndicatorIcons;
59     private TypedArray mHdrIndicatorIcons;
60     private TypedArray mPanoIndicatorIcons;
61     private TypedArray mCountdownTimerIndicatorIcons;
62 
63     private AppController mController;
64 
IndicatorIconController(AppController controller, View root)65     public IndicatorIconController(AppController controller, View root) {
66         mController = controller;
67         Context context = controller.getAndroidContext();
68 
69         mFlashIndicator = (ImageView) root.findViewById(R.id.flash_indicator);
70         mFlashIndicatorPhotoIcons = context.getResources().obtainTypedArray(
71             R.array.camera_flashmode_indicator_icons);
72         mFlashIndicatorVideoIcons = context.getResources().obtainTypedArray(
73             R.array.video_flashmode_indicator_icons);
74 
75         mHdrIndicator = (ImageView) root.findViewById(R.id.hdr_indicator);
76         mHdrPlusIndicatorIcons = context.getResources().obtainTypedArray(
77             R.array.pref_camera_hdr_plus_indicator_icons);
78         mHdrIndicatorIcons = context.getResources().obtainTypedArray(
79             R.array.pref_camera_hdr_indicator_icons);
80 
81         int panoIndicatorArrayId = PhotoSphereHelper.getPanoramaOrientationIndicatorArrayId();
82         if (panoIndicatorArrayId > 0) {
83             mPanoIndicator = (ImageView) root.findViewById(R.id.pano_indicator);
84             mPanoIndicatorIcons =
85                 context.getResources().obtainTypedArray(panoIndicatorArrayId);
86         }
87 
88         mCountdownTimerIndicator = (ImageView) root.findViewById(R.id.countdown_timer_indicator);
89         mCountdownTimerIndicatorIcons = context.getResources().obtainTypedArray(
90                 R.array.pref_camera_countdown_indicators);
91 
92         mExposureIndicatorN2 = (ImageView) root.findViewById(R.id.exposure_n2_indicator);
93         mExposureIndicatorN1 = (ImageView) root.findViewById(R.id.exposure_n1_indicator);
94         mExposureIndicatorP1 = (ImageView) root.findViewById(R.id.exposure_p1_indicator);
95         mExposureIndicatorP2 = (ImageView) root.findViewById(R.id.exposure_p2_indicator);
96     }
97 
98     @Override
onButtonVisibilityChanged(ButtonManager buttonManager, int buttonId)99     public void onButtonVisibilityChanged(ButtonManager buttonManager, int buttonId) {
100         syncIndicatorWithButton(buttonId);
101     }
102 
103     @Override
onButtonEnabledChanged(ButtonManager buttonManager, int buttonId)104     public void onButtonEnabledChanged(ButtonManager buttonManager, int buttonId) {
105         syncIndicatorWithButton(buttonId);
106     }
107 
108     /**
109      * Syncs a specific indicator's icon and visibility
110      * based on the enabled state and visibility of a button.
111      */
syncIndicatorWithButton(int buttonId)112     private void syncIndicatorWithButton(int buttonId) {
113         switch (buttonId) {
114             case ButtonManager.BUTTON_FLASH: {
115                 syncFlashIndicator();
116                 break;
117             }
118             case ButtonManager.BUTTON_TORCH: {
119                 syncFlashIndicator();
120                 break;
121             }
122             case ButtonManager.BUTTON_HDR_PLUS: {
123                 syncHdrIndicator();
124                 break;
125             }
126             case ButtonManager.BUTTON_HDR: {
127                 syncHdrIndicator();
128                 break;
129             }
130             case ButtonManager.BUTTON_EXPOSURE_COMPENSATION: {
131                 syncExposureIndicator();
132                 break;
133             }
134             default:
135                 // Do nothing.  The indicator doesn't care
136                 // about button that don't correspond to indicators.
137         }
138     }
139 
140     /**
141      * Sets all indicators to the correct resource and visibility
142      * based on the current settings.
143      */
syncIndicators()144     public void syncIndicators() {
145         syncFlashIndicator();
146         syncHdrIndicator();
147         syncPanoIndicator();
148         syncExposureIndicator();
149         syncCountdownTimerIndicator();
150     }
151 
152     /**
153      * If the new visibility is different from the current visibility
154      * on a view, change the visibility and call any registered
155      * {@link OnIndicatorVisibilityChangedListener}.
156      */
changeVisibility(View view, int visibility)157     private static void changeVisibility(View view, int visibility) {
158         if (view.getVisibility() != visibility) {
159             view.setVisibility(visibility);
160         }
161     }
162 
163     /**
164      * Sync the icon and visibility of the flash indicator.
165      */
syncFlashIndicator()166     private void syncFlashIndicator() {
167         ButtonManager buttonManager = mController.getButtonManager();
168         // If flash isn't an enabled and visible option,
169         // do not show the indicator.
170         if ((buttonManager.isEnabled(ButtonManager.BUTTON_FLASH)
171                 && buttonManager.isVisible(ButtonManager.BUTTON_FLASH))
172                 || (buttonManager.isEnabled(ButtonManager.BUTTON_TORCH)
173                 && buttonManager.isVisible(ButtonManager.BUTTON_TORCH))) {
174 
175             int modeIndex = mController.getCurrentModuleIndex();
176             if (modeIndex == mController.getAndroidContext().getResources()
177                     .getInteger(R.integer.camera_mode_video)) {
178                 setIndicatorState(mController.getCameraScope(),
179                                   Keys.KEY_VIDEOCAMERA_FLASH_MODE, mFlashIndicator,
180                                   mFlashIndicatorVideoIcons, false);
181             } else if (modeIndex == mController.getAndroidContext().getResources()
182                     .getInteger(R.integer.camera_mode_gcam)) {
183                 setIndicatorState(mController.getCameraScope(),
184                                   Keys.KEY_HDR_PLUS_FLASH_MODE, mFlashIndicator,
185                                   mFlashIndicatorPhotoIcons, false);
186             } else {
187                 setIndicatorState(mController.getCameraScope(),
188                                   Keys.KEY_FLASH_MODE, mFlashIndicator,
189                                   mFlashIndicatorPhotoIcons, false);
190             }
191         } else {
192             changeVisibility(mFlashIndicator, View.GONE);
193         }
194     }
195 
196     /**
197      * Sync the icon and the visibility of the hdr/hdrplus indicator.
198      */
syncHdrIndicator()199     private void syncHdrIndicator() {
200         ButtonManager buttonManager = mController.getButtonManager();
201         // If hdr isn't an enabled and visible option,
202         // do not show the indicator.
203         if (buttonManager.isEnabled(ButtonManager.BUTTON_HDR_PLUS)
204                 && buttonManager.isVisible(ButtonManager.BUTTON_HDR_PLUS)) {
205             setIndicatorState(SettingsManager.SCOPE_GLOBAL,
206                               Keys.KEY_CAMERA_HDR_PLUS, mHdrIndicator,
207                               mHdrPlusIndicatorIcons, false);
208         } else if (buttonManager.isEnabled(ButtonManager.BUTTON_HDR)
209                 && buttonManager.isVisible(ButtonManager.BUTTON_HDR)) {
210             setIndicatorState(SettingsManager.SCOPE_GLOBAL,
211                               Keys.KEY_CAMERA_HDR, mHdrIndicator,
212                               mHdrIndicatorIcons, false);
213         } else {
214             changeVisibility(mHdrIndicator, View.GONE);
215         }
216     }
217 
218     /**
219      * Sync the icon and the visibility of the pano indicator.
220      */
syncPanoIndicator()221     private void syncPanoIndicator() {
222         if (mPanoIndicator == null) {
223             Log.w(TAG, "Trying to sync a pano indicator that is not initialized.");
224             return;
225         }
226 
227         ButtonManager buttonManager = mController.getButtonManager();
228         if (buttonManager.isPanoEnabled()) {
229             setIndicatorState(SettingsManager.SCOPE_GLOBAL,
230                               Keys.KEY_CAMERA_PANO_ORIENTATION, mPanoIndicator,
231                               mPanoIndicatorIcons, true);
232         } else {
233             changeVisibility(mPanoIndicator, View.GONE);
234         }
235     }
236 
syncExposureIndicator()237     private void syncExposureIndicator() {
238         if (mExposureIndicatorN2 == null
239             || mExposureIndicatorN1 == null
240             || mExposureIndicatorP1 == null
241             || mExposureIndicatorP2 == null) {
242             Log.w(TAG, "Trying to sync exposure indicators that are not initialized.");
243             return;
244         }
245 
246 
247         // Reset all exposure indicator icons.
248         changeVisibility(mExposureIndicatorN2, View.GONE);
249         changeVisibility(mExposureIndicatorN1, View.GONE);
250         changeVisibility(mExposureIndicatorP1, View.GONE);
251         changeVisibility(mExposureIndicatorP2, View.GONE);
252 
253         ButtonManager buttonManager = mController.getButtonManager();
254         if (buttonManager.isEnabled(ButtonManager.BUTTON_EXPOSURE_COMPENSATION)
255                 && buttonManager.isVisible(ButtonManager.BUTTON_EXPOSURE_COMPENSATION)) {
256 
257             int compValue = mController.getSettingsManager().getInteger(
258                     mController.getCameraScope(), Keys.KEY_EXPOSURE);
259             int comp = Math.round(compValue * buttonManager.getExposureCompensationStep());
260 
261             // Turn on the appropriate indicator.
262             switch (comp) {
263                 case -2:
264                     changeVisibility(mExposureIndicatorN2, View.VISIBLE);
265                     break;
266                 case -1:
267                     changeVisibility(mExposureIndicatorN1, View.VISIBLE);
268                     break;
269                 case 0:
270                     // Do nothing.
271                     break;
272                 case 1:
273                     changeVisibility(mExposureIndicatorP1, View.VISIBLE);
274                     break;
275                 case 2:
276                     changeVisibility(mExposureIndicatorP2, View.VISIBLE);
277             }
278         }
279     }
280 
syncCountdownTimerIndicator()281     private void syncCountdownTimerIndicator() {
282         ButtonManager buttonManager = mController.getButtonManager();
283 
284         if (buttonManager.isEnabled(ButtonManager.BUTTON_COUNTDOWN)
285             && buttonManager.isVisible(ButtonManager.BUTTON_COUNTDOWN)) {
286             setIndicatorState(SettingsManager.SCOPE_GLOBAL,
287                               Keys.KEY_COUNTDOWN_DURATION, mCountdownTimerIndicator,
288                               mCountdownTimerIndicatorIcons, false);
289         } else {
290             changeVisibility(mCountdownTimerIndicator, View.GONE);
291         }
292     }
293 
294     /**
295      * Sets the image resource and visibility of the indicator
296      * based on the indicator's corresponding setting state.
297      */
setIndicatorState(String scope, String key, ImageView imageView, TypedArray iconArray, boolean showDefault)298     private void setIndicatorState(String scope, String key, ImageView imageView,
299                                    TypedArray iconArray, boolean showDefault) {
300         SettingsManager settingsManager = mController.getSettingsManager();
301 
302         int valueIndex = settingsManager.getIndexOfCurrentValue(scope, key);
303         if (valueIndex < 0) {
304             // This can happen when the setting is camera dependent
305             // and the camera is not yet open.  CameraAppUI.onChangeCamera()
306             // will call this again when the camera is open.
307             Log.w(TAG, "The setting for this indicator is not available.");
308             imageView.setVisibility(View.GONE);
309             return;
310         }
311         Drawable drawable = iconArray.getDrawable(valueIndex);
312         if (drawable == null) {
313             throw new IllegalStateException("Indicator drawable is null.");
314         }
315         imageView.setImageDrawable(drawable);
316 
317         // Set the indicator visible if not in default state.
318         boolean visibilityChanged = false;
319         if (!showDefault && settingsManager.isDefault(scope, key)) {
320             changeVisibility(imageView, View.GONE);
321         } else {
322             changeVisibility(imageView, View.VISIBLE);
323         }
324     }
325 
326     @Override
onSettingChanged(SettingsManager settingsManager, String key)327     public void onSettingChanged(SettingsManager settingsManager, String key) {
328         if (key.equals(Keys.KEY_FLASH_MODE)) {
329             syncFlashIndicator();
330             return;
331         }
332         if (key.equals(Keys.KEY_VIDEOCAMERA_FLASH_MODE)) {
333             syncFlashIndicator();
334             return;
335         }
336         if (key.equals(Keys.KEY_CAMERA_HDR_PLUS)) {
337             syncHdrIndicator();
338             return;
339         }
340         if (key.equals(Keys.KEY_CAMERA_HDR)) {
341             syncHdrIndicator();
342             return;
343         }
344         if (key.equals(Keys.KEY_CAMERA_PANO_ORIENTATION)) {
345             syncPanoIndicator();
346             return;
347         }
348         if (key.equals(Keys.KEY_EXPOSURE)) {
349             syncExposureIndicator();
350             return;
351         }
352         if (key.equals(Keys.KEY_COUNTDOWN_DURATION)) {
353             syncCountdownTimerIndicator();
354             return;
355         }
356     }
357 
358 }
359