1 package com.android.camera;
2 
3 import android.Manifest;
4 import android.app.Activity;
5 import android.app.Dialog;
6 import android.app.AlertDialog;
7 import android.app.KeyguardManager;
8 import android.content.BroadcastReceiver;
9 import android.content.Context;
10 import android.content.DialogInterface;
11 import android.content.Intent;
12 import android.content.IntentFilter;
13 import android.content.pm.PackageManager;
14 import android.os.Bundle;
15 import android.view.KeyEvent;
16 import android.view.Window;
17 import android.view.WindowManager;
18 import com.android.camera.app.CameraServicesImpl;
19 import com.android.camera.debug.Log;
20 import com.android.camera.settings.Keys;
21 import com.android.camera.settings.SettingsManager;
22 import com.android.camera.util.QuickActivity;
23 import com.android.camera2.R;
24 
25 import java.util.ArrayList;
26 import java.util.List;
27 
28 /**
29  * Activity that shows permissions request dialogs and handles lack of critical permissions.
30  * TODO: Convert PermissionsActivity into a dialog to be emitted from
31  * CameraActivity as not to have to restart CameraActivity from
32  * scratch.
33  */
34 public class PermissionsActivity extends QuickActivity {
35     private static final Log.Tag TAG = new Log.Tag("PermissionsActivity");
36 
37     private static final int PERMISSION_REQUEST_CODE = 1;
38 
39     private SettingsManager mSettingsManager;
40 
41     /**
42      * Close activity when secure app passes lock screen or screen turns
43      * off.
44      */
45     private final BroadcastReceiver mShutdownReceiver = new BroadcastReceiver() {
46         @Override
47         public void onReceive(Context context, Intent intent) {
48           Log.v(TAG, "received intent, finishing: " + intent.getAction());
49           finish();
50         }
51     };
52 
53     @Override
onCreateTasks(Bundle savedInstanceState)54     protected void onCreateTasks(Bundle savedInstanceState) {
55         setContentView(R.layout.permissions);
56         mSettingsManager = CameraServicesImpl.instance().getSettingsManager();
57 
58         // Filter for screen off so that we can finish permissions activity
59         // when screen is off.
60         IntentFilter filter_screen_off = new IntentFilter(Intent.ACTION_SCREEN_OFF);
61         registerReceiver(mShutdownReceiver, filter_screen_off);
62 
63         // Filter for phone unlock so that we can finish permissions activity
64         // via this UI path:
65         //    1. from secure lock screen, user starts secure camera
66         //    2. user presses home button
67         //    3. user unlocks phone
68         IntentFilter filter_user_unlock = new IntentFilter(Intent.ACTION_USER_PRESENT);
69         registerReceiver(mShutdownReceiver, filter_user_unlock);
70 
71         Window win = getWindow();
72         if (isKeyguardLocked()) {
73             win.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
74         } else {
75             win.clearFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
76         }
77     }
78 
79     @Override
onResumeTasks()80     protected void onResumeTasks() {
81         checkPermissions();
82     }
83 
84     @Override
onDestroyTasks()85     protected void onDestroyTasks() {
86         Log.v(TAG, "onDestroy: unregistering receivers");
87         unregisterReceiver(mShutdownReceiver);
88     }
89 
checkPermissions()90     private void checkPermissions() {
91         List<String> permissions = new ArrayList<>();
92 
93         if (checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
94             permissions.add(Manifest.permission.CAMERA);
95         }
96 
97         if (checkSelfPermission(Manifest.permission.RECORD_AUDIO)
98                 != PackageManager.PERMISSION_GRANTED) {
99             permissions.add(Manifest.permission.RECORD_AUDIO);
100         }
101 
102         if (mSettingsManager.getBoolean(SettingsManager.SCOPE_GLOBAL, Keys.KEY_RECORD_LOCATION)
103                 && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION)
104                     != PackageManager.PERMISSION_GRANTED
105                 && checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION)
106                     != PackageManager.PERMISSION_GRANTED) {
107             permissions.add(Manifest.permission.ACCESS_COARSE_LOCATION);
108             permissions.add(Manifest.permission.ACCESS_FINE_LOCATION);
109         }
110 
111         if (!permissions.isEmpty()) {
112             if (!isKeyguardLocked() && !mSettingsManager.getBoolean(SettingsManager.SCOPE_GLOBAL,
113                     Keys.KEY_HAS_SEEN_PERMISSIONS_DIALOGS)) {
114                 Log.v(TAG, "requestPermissions count: " + permissions.size());
115                 requestPermissions(permissions.toArray(new String[0]), PERMISSION_REQUEST_CODE);
116             } else {
117                 // Permissions dialog has already been shown, or we're on
118                 // lockscreen, and we're still missing permissions.
119                 handlePermissionsFailure();
120             }
121         } else {
122             handlePermissionsSuccess();
123         }
124     }
125 
126     @Override
onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)127     public void onRequestPermissionsResult(int requestCode,
128                                            String[] permissions, int[] grantResults) {
129         Log.v(TAG, "onPermissionsResult counts: " + permissions.length + ":" + grantResults.length);
130         mSettingsManager.set(
131                 SettingsManager.SCOPE_GLOBAL,
132                 Keys.KEY_HAS_SEEN_PERMISSIONS_DIALOGS,
133                 true);
134 
135         boolean missingCriticalPermissions = false;
136         for (int i = 0; i < permissions.length; i++) {
137             String permission = permissions[i];
138             int result = grantResults[i];
139             // Show fail dialog if critical permissions are not granted
140             if (Manifest.permission.CAMERA.equals(permission)
141                     && result == PackageManager.PERMISSION_DENIED) {
142                 handlePermissionsFailure();
143                 missingCriticalPermissions = true;
144             } else if (Manifest.permission.RECORD_AUDIO.equals(permission)
145                     && result == PackageManager.PERMISSION_DENIED) {
146                 handlePermissionsFailure();
147                 missingCriticalPermissions = true;
148             }
149         }
150         if (!missingCriticalPermissions) {
151             handlePermissionsSuccess();
152         }
153     }
154 
handlePermissionsSuccess()155     private void handlePermissionsSuccess() {
156         Intent intent = new Intent(this, CameraActivity.class);
157         startActivity(intent);
158         finish();
159     }
160 
handlePermissionsFailure()161     private void handlePermissionsFailure() {
162         new AlertDialog.Builder(this).setTitle(getResources().getString(R.string.camera_error_title))
163                 .setMessage(getResources().getString(R.string.error_permissions))
164                 .setCancelable(false)
165                 .setOnKeyListener(new Dialog.OnKeyListener() {
166                     @Override
167                     public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
168                         if (keyCode == KeyEvent.KEYCODE_BACK) {
169                             finish();
170                         }
171                         return true;
172                     }
173                 })
174                 .setPositiveButton(getResources().getString(R.string.dialog_dismiss),
175                         new DialogInterface.OnClickListener() {
176                     @Override
177                     public void onClick(DialogInterface dialog, int which) {
178                         finish();
179                     }
180                 })
181                 .show();
182     }
183 }
184