1package com.android.camera; 2 3import android.Manifest; 4import android.app.Activity; 5import android.app.Dialog; 6import android.app.AlertDialog; 7import android.app.KeyguardManager; 8import android.content.BroadcastReceiver; 9import android.content.Context; 10import android.content.DialogInterface; 11import android.content.Intent; 12import android.content.IntentFilter; 13import android.content.pm.PackageManager; 14import android.os.Bundle; 15import android.view.KeyEvent; 16import android.view.Window; 17import android.view.WindowManager; 18import com.android.camera.app.CameraServicesImpl; 19import com.android.camera.debug.Log; 20import com.android.camera.settings.Keys; 21import com.android.camera.settings.SettingsManager; 22import com.android.camera.util.QuickActivity; 23import com.android.camera2.R; 24 25/** 26 * Activity that shows permissions request dialogs and handles lack of critical permissions. 27 */ 28public class PermissionsActivity extends QuickActivity { 29 private static final Log.Tag TAG = new Log.Tag("PermissionsActivity"); 30 31 private static int PERMISSION_REQUEST_CODE = 1; 32 private static int RESULT_CODE_OK = 1; 33 private static int RESULT_CODE_FAILED = 2; 34 35 private int mIndexPermissionRequestCamera; 36 private int mIndexPermissionRequestMicrophone; 37 private int mIndexPermissionRequestLocation; 38 private int mIndexPermissionRequestStorage; 39 private boolean mShouldRequestCameraPermission; 40 private boolean mShouldRequestMicrophonePermission; 41 private boolean mShouldRequestLocationPermission; 42 private boolean mShouldRequestStoragePermission; 43 private int mNumPermissionsToRequest; 44 private boolean mFlagHasCameraPermission; 45 private boolean mFlagHasMicrophonePermission; 46 private boolean mFlagHasStoragePermission; 47 private SettingsManager mSettingsManager; 48 49 /** 50 * Close activity when secure app passes lock screen or screen turns 51 * off. 52 */ 53 private final BroadcastReceiver mShutdownReceiver = new BroadcastReceiver() { 54 @Override 55 public void onReceive(Context context, Intent intent) { 56 Log.v(TAG, "received intent, finishing: " + intent.getAction()); 57 finish(); 58 } 59 }; 60 61 @Override 62 protected void onCreateTasks(Bundle savedInstanceState) { 63 setContentView(R.layout.permissions); 64 mSettingsManager = CameraServicesImpl.instance().getSettingsManager(); 65 66 // Filter for screen off so that we can finish permissions activity 67 // when screen is off. 68 IntentFilter filter_screen_off = new IntentFilter(Intent.ACTION_SCREEN_OFF); 69 registerReceiver(mShutdownReceiver, filter_screen_off); 70 71 // Filter for phone unlock so that we can finish permissions activity 72 // via this UI path: 73 // 1. from secure lock screen, user starts secure camera 74 // 2. user presses home button 75 // 3. user unlocks phone 76 IntentFilter filter_user_unlock = new IntentFilter(Intent.ACTION_USER_PRESENT); 77 registerReceiver(mShutdownReceiver, filter_user_unlock); 78 79 Window win = getWindow(); 80 if (isKeyguardLocked()) { 81 win.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED); 82 } else { 83 win.clearFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED); 84 } 85 } 86 87 @Override 88 protected void onResumeTasks() { 89 mNumPermissionsToRequest = 0; 90 checkPermissions(); 91 } 92 93 @Override 94 protected void onDestroyTasks() { 95 Log.v(TAG, "onDestroy: unregistering receivers"); 96 unregisterReceiver(mShutdownReceiver); 97 } 98 99 private void checkPermissions() { 100 if (checkSelfPermission(Manifest.permission.CAMERA) 101 != PackageManager.PERMISSION_GRANTED) { 102 mNumPermissionsToRequest++; 103 mShouldRequestCameraPermission = true; 104 } else { 105 mFlagHasCameraPermission = true; 106 } 107 108 if (checkSelfPermission(Manifest.permission.RECORD_AUDIO) 109 != PackageManager.PERMISSION_GRANTED) { 110 mNumPermissionsToRequest++; 111 mShouldRequestMicrophonePermission = true; 112 } else { 113 mFlagHasMicrophonePermission = true; 114 } 115 116 if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) 117 != PackageManager.PERMISSION_GRANTED) { 118 mNumPermissionsToRequest++; 119 mShouldRequestStoragePermission = true; 120 } else { 121 mFlagHasStoragePermission = true; 122 } 123 124 if (checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) 125 != PackageManager.PERMISSION_GRANTED) { 126 mNumPermissionsToRequest++; 127 mShouldRequestLocationPermission = true; 128 } 129 130 if (mNumPermissionsToRequest != 0) { 131 if (!isKeyguardLocked() && !mSettingsManager.getBoolean(SettingsManager.SCOPE_GLOBAL, 132 Keys.KEY_HAS_SEEN_PERMISSIONS_DIALOGS)) { 133 buildPermissionsRequest(); 134 } else { 135 // Permissions dialog has already been shown, or we're on 136 // lockscreen, and we're still missing permissions. 137 handlePermissionsFailure(); 138 } 139 } else { 140 handlePermissionsSuccess(); 141 } 142 } 143 144 private void buildPermissionsRequest() { 145 String[] permissionsToRequest = new String[mNumPermissionsToRequest]; 146 int permissionsRequestIndex = 0; 147 148 if (mShouldRequestCameraPermission) { 149 permissionsToRequest[permissionsRequestIndex] = Manifest.permission.CAMERA; 150 mIndexPermissionRequestCamera = permissionsRequestIndex; 151 permissionsRequestIndex++; 152 } 153 if (mShouldRequestMicrophonePermission) { 154 permissionsToRequest[permissionsRequestIndex] = Manifest.permission.RECORD_AUDIO; 155 mIndexPermissionRequestMicrophone = permissionsRequestIndex; 156 permissionsRequestIndex++; 157 } 158 if (mShouldRequestStoragePermission) { 159 permissionsToRequest[permissionsRequestIndex] = Manifest.permission.READ_EXTERNAL_STORAGE; 160 mIndexPermissionRequestStorage = permissionsRequestIndex; 161 permissionsRequestIndex++; 162 } 163 if (mShouldRequestLocationPermission) { 164 permissionsToRequest[permissionsRequestIndex] = Manifest.permission.ACCESS_COARSE_LOCATION; 165 mIndexPermissionRequestLocation = permissionsRequestIndex; 166 } 167 168 Log.v(TAG, "requestPermissions count: " + permissionsToRequest.length); 169 requestPermissions(permissionsToRequest, PERMISSION_REQUEST_CODE); 170 } 171 172 @Override 173 public void onRequestPermissionsResult(int requestCode, 174 String permissions[], int[] grantResults) { 175 Log.v(TAG, "onPermissionsResult counts: " + permissions.length + ":" + grantResults.length); 176 mSettingsManager.set( 177 SettingsManager.SCOPE_GLOBAL, 178 Keys.KEY_HAS_SEEN_PERMISSIONS_DIALOGS, 179 true); 180 181 if (mShouldRequestCameraPermission) { 182 if (grantResults.length > 0 && grantResults[mIndexPermissionRequestCamera] == 183 PackageManager.PERMISSION_GRANTED) { 184 mFlagHasCameraPermission = true; 185 } else { 186 handlePermissionsFailure(); 187 } 188 } 189 if (mShouldRequestMicrophonePermission) { 190 if (grantResults.length > 0 && grantResults[mIndexPermissionRequestMicrophone] == 191 PackageManager.PERMISSION_GRANTED) { 192 mFlagHasMicrophonePermission = true; 193 } else { 194 handlePermissionsFailure(); 195 } 196 } 197 if (mShouldRequestStoragePermission) { 198 if (grantResults.length > 0 && grantResults[mIndexPermissionRequestStorage] == 199 PackageManager.PERMISSION_GRANTED) { 200 mFlagHasStoragePermission = true; 201 } else { 202 handlePermissionsFailure(); 203 } 204 } 205 206 if (mShouldRequestLocationPermission) { 207 if (grantResults.length > 0 && grantResults[mIndexPermissionRequestLocation] == 208 PackageManager.PERMISSION_GRANTED) { 209 // Do nothing 210 } else { 211 // Do nothing 212 } 213 } 214 215 if (mFlagHasCameraPermission && mFlagHasMicrophonePermission && mFlagHasStoragePermission) { 216 handlePermissionsSuccess(); 217 } 218 } 219 220 private void handlePermissionsSuccess() { 221 Intent intent = new Intent(this, CameraActivity.class); 222 startActivity(intent); 223 finish(); 224 } 225 226 private void handlePermissionsFailure() { 227 new AlertDialog.Builder(this).setTitle(getResources().getString(R.string.camera_error_title)) 228 .setMessage(getResources().getString(R.string.error_permissions)) 229 .setCancelable(false) 230 .setOnKeyListener(new Dialog.OnKeyListener() { 231 @Override 232 public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) { 233 if (keyCode == KeyEvent.KEYCODE_BACK) { 234 finish(); 235 } 236 return true; 237 } 238 }) 239 .setPositiveButton(getResources().getString(R.string.dialog_dismiss), 240 new DialogInterface.OnClickListener() { 241 @Override 242 public void onClick(DialogInterface dialog, int which) { 243 finish(); 244 } 245 }) 246 .show(); 247 } 248} 249