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 { onFirstRunStateReady()43 public void onFirstRunStateReady(); onFirstRunDialogCancelled()44 public void onFirstRunDialogCancelled(); onCameraAccessException()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 */ FirstRunDialog( AppController appController, Context androidContext, ResolutionSetting resolutionSetting, SettingsManager settingManager, OneCameraManager hardwareManager, FirstRunDialogListener listener)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 */ showIfNecessary()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 */ dismiss()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 */ shouldShowLocationDialog()139 private boolean shouldShowLocationDialog() { 140 return !mSettingsManager.isSet(SettingsManager.SCOPE_GLOBAL, Keys.KEY_RECORD_LOCATION); 141 } 142 shouldShowAspectRatioDialog()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 */ promptAspectRatioPreferenceDialog()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 */ promptLocationPreferenceDialog()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