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