FirstRunDialog.java revision 1d84d7107686aa428ee2eeb1a8caf0ea3e43b1df
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
17package com.android.camera.app;
18
19import android.app.Dialog;
20import android.content.Context;
21import android.content.DialogInterface;
22import android.view.ViewGroup;
23
24import com.android.camera.exif.Rational;
25import com.android.camera.one.OneCamera.Facing;
26import com.android.camera.one.OneCameraAccessException;
27import com.android.camera.one.OneCameraManager;
28import com.android.camera.settings.Keys;
29import com.android.camera.settings.ResolutionSetting;
30import com.android.camera.settings.ResolutionUtil;
31import com.android.camera.settings.SettingsManager;
32import com.android.camera.util.ApiHelper;
33import com.android.camera.widget.AspectRatioDialogLayout;
34import com.android.camera.widget.LocationDialogLayout;
35
36/**
37 * The dialog to show when users open the app for the first time.
38 */
39public class FirstRunDialog {
40
41    public interface FirstRunDialogListener {
42        public void onFirstRunStateReady();
43        public void onFirstRunDialogCancelled();
44        public void onCameraAccessException();
45    }
46
47    /** The default preference of aspect ratio. */
48    private static final Rational DEFAULT_ASPECT_RATIO = ResolutionUtil.ASPECT_RATIO_4x3;
49
50    /** The default preference of whether enabling location recording. */
51    private static final boolean DEFAULT_LOCATION_RECORDING_ENABLED = true;
52
53    /** Listener to receive events. */
54    private final FirstRunDialogListener mListener;
55
56    /** The app controller. */
57    private final AppController mAppController;
58
59    /** The hardware manager. */
60    private final OneCameraManager mOneCameraManager;
61
62    /** The app context. */
63    private final Context mContext;
64
65    /** The resolution settings. */
66    private final ResolutionSetting mResolutionSetting;
67
68    /** The settings manager. */
69    private final SettingsManager mSettingsManager;
70
71    /** Aspect ratio preference dialog */
72    private Dialog mAspectRatioPreferenceDialog;
73
74    /** Location preference dialog */
75    private Dialog mLocationPreferenceDialog;
76
77    /**
78     * Constructs a first run dialog.
79     *
80     */
81    public FirstRunDialog(
82          AppController appController,
83          Context androidContext,
84          ResolutionSetting resolutionSetting,
85          SettingsManager settingManager,
86          OneCameraManager hardwareManager,
87          FirstRunDialogListener listener) {
88        mAppController = appController;
89        mContext = androidContext;
90        mResolutionSetting = resolutionSetting;
91        mSettingsManager = settingManager;
92        mOneCameraManager = hardwareManager;
93        mListener = listener;
94    }
95
96    /**
97     * Shows first run dialogs if necessary.
98     */
99    public void showIfNecessary() {
100        if (shouldShow()) {
101            // When people open the app for the first time, prompt two dialogs to
102            // ask preferences about location and aspect ratio. The first dialog is
103            // location reference.
104            promptLocationPreferenceDialog();
105        } else {
106            mListener.onFirstRunStateReady();
107        }
108    }
109
110    /**
111     * Dismiss all shown dialogs.
112     */
113    public void dismiss() {
114        if (mAspectRatioPreferenceDialog != null) {
115            // Remove the listener since we actively dismiss the dialog.
116            mAspectRatioPreferenceDialog.setOnDismissListener(null);
117            mAspectRatioPreferenceDialog.dismiss();
118            mAspectRatioPreferenceDialog = null;
119        }
120        if (mLocationPreferenceDialog != null) {
121            // Remove the listener since we actively dismiss the dialog.
122            mLocationPreferenceDialog.setOnDismissListener(null);
123            mLocationPreferenceDialog.dismiss();
124            mLocationPreferenceDialog = null;
125        }
126    }
127
128    /**
129     * Whether first run dialogs should be presented to the user.
130     *
131     * @return Whether first run dialogs should be presented to the user.
132     */
133    private boolean shouldShow() {
134        final boolean isAspectRatioPreferenceSet = mSettingsManager.getBoolean(
135                SettingsManager.SCOPE_GLOBAL, Keys.KEY_USER_SELECTED_ASPECT_RATIO);
136        final boolean isAspectRatioDevice =
137                ApiHelper.IS_NEXUS_4 || ApiHelper.IS_NEXUS_5 || ApiHelper.IS_NEXUS_6;
138        final boolean shouldShowAspectRatioDialog =
139                isAspectRatioDevice && !isAspectRatioPreferenceSet;
140        final boolean shouldShowLocationDialog =
141                !mSettingsManager.isSet(SettingsManager.SCOPE_GLOBAL, Keys.KEY_RECORD_LOCATION);
142        return shouldShowAspectRatioDialog || shouldShowLocationDialog;
143    }
144
145    /**
146     * Prompts a dialog to allow people to choose aspect ratio preference when
147     * people open the app for the first time. If the preference has been set,
148     * this will return false.
149     */
150    private void promptAspectRatioPreferenceDialog() {
151        // Create a content view for the dialog.
152        final AspectRatioDialogLayout dialogLayout = new AspectRatioDialogLayout(
153                mContext, DEFAULT_ASPECT_RATIO);
154        dialogLayout.setListener(new AspectRatioDialogLayout.AspectRatioDialogListener() {
155            @Override
156            public void onConfirm(Rational aspectRatio) {
157                // Change resolution setting based on the chosen aspect ratio.
158                try {
159                    mResolutionSetting.setPictureAspectRatio(
160                          mOneCameraManager.findFirstCameraFacing(Facing.BACK), aspectRatio);
161                    mResolutionSetting.setPictureAspectRatio(
162                          mOneCameraManager.findFirstCameraFacing(Facing.FRONT), aspectRatio);
163                } catch (OneCameraAccessException ex) {
164                    mListener.onCameraAccessException();
165                    return;
166                }
167
168                // Mark that user has made the choice.
169                mSettingsManager.set(
170                        SettingsManager.SCOPE_GLOBAL,
171                        Keys.KEY_USER_SELECTED_ASPECT_RATIO,
172                        true);
173
174                // Dismiss all dialogs.
175                dismiss();
176
177                // Notify that the app is ready to go.
178                mListener.onFirstRunStateReady();
179            }
180        });
181
182        // Create the dialog.
183        mAspectRatioPreferenceDialog = mAppController.createDialog();
184        mAspectRatioPreferenceDialog.setContentView(dialogLayout, new ViewGroup.LayoutParams(
185                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
186        // Detect if the dialog is dismissed by back button.
187        mAspectRatioPreferenceDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
188            @Override
189            public void onDismiss(DialogInterface dialog) {
190                mAspectRatioPreferenceDialog = null;
191                dismiss();
192                mListener.onFirstRunDialogCancelled();
193            }
194        });
195
196        // Show the dialog.
197        mAspectRatioPreferenceDialog.show();
198    }
199
200    /**
201     * Prompts a dialog to allow people to choose location preference when
202     * people open the app for the first time. If the preference has been set,
203     * this will return false.
204     */
205    private void promptLocationPreferenceDialog() {
206        // Create a content view for the dialog.
207        final LocationDialogLayout dialogLayout = new LocationDialogLayout(
208                mContext, DEFAULT_LOCATION_RECORDING_ENABLED);
209        dialogLayout.setListener(new LocationDialogLayout.LocationDialogListener() {
210            @Override
211            public void onConfirm(boolean locationRecordingEnabled) {
212                // Change the location preference setting.
213                mSettingsManager.set(
214                        SettingsManager.SCOPE_GLOBAL,
215                        Keys.KEY_RECORD_LOCATION,
216                        locationRecordingEnabled);
217
218                // Prompt the second dialog about aspect ratio preference.
219                promptAspectRatioPreferenceDialog();
220            }
221        });
222
223        // Create the dialog.
224        mLocationPreferenceDialog = mAppController.createDialog();
225        mLocationPreferenceDialog.setContentView(dialogLayout, new ViewGroup.LayoutParams(
226                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
227        // Detect if the dialog is dismissed by back button.
228        mLocationPreferenceDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
229            @Override
230            public void onDismiss(DialogInterface dialog) {
231                mLocationPreferenceDialog = null;
232                dismiss();
233                mListener.onFirstRunDialogCancelled();
234            }
235        });
236
237        // Show the dialog.
238        mLocationPreferenceDialog.show();
239    }
240}
241