PermissionsActivity.java revision ac0e2425e77a9b69e76d2f31876798825ea44584
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[mIndexPermissionRequestCamera] == PackageManager.PERMISSION_GRANTED) {
183                mFlagHasCameraPermission = true;
184            } else {
185                handlePermissionsFailure();
186            }
187        }
188        if (mShouldRequestMicrophonePermission) {
189            if (grantResults[mIndexPermissionRequestMicrophone] == PackageManager.PERMISSION_GRANTED) {
190                mFlagHasMicrophonePermission = true;
191            } else {
192                handlePermissionsFailure();
193            }
194        }
195        if (mShouldRequestStoragePermission) {
196            if (grantResults[mIndexPermissionRequestStorage] == PackageManager.PERMISSION_GRANTED) {
197                mFlagHasStoragePermission = true;
198            } else {
199                handlePermissionsFailure();
200            }
201        }
202
203        if (mShouldRequestLocationPermission) {
204            if (grantResults[mIndexPermissionRequestLocation] == PackageManager.PERMISSION_GRANTED) {
205                // Do nothing
206            } else {
207                // Do nothing
208            }
209        }
210
211        if (mFlagHasCameraPermission && mFlagHasMicrophonePermission && mFlagHasStoragePermission) {
212            handlePermissionsSuccess();
213        }
214    }
215
216    private void handlePermissionsSuccess() {
217        Intent intent = new Intent(this, CameraActivity.class);
218        startActivity(intent);
219        finish();
220    }
221
222    private void handlePermissionsFailure() {
223        new AlertDialog.Builder(this).setTitle(getResources().getString(R.string.camera_error_title))
224                .setMessage(getResources().getString(R.string.error_permissions))
225                .setCancelable(false)
226                .setOnKeyListener(new Dialog.OnKeyListener() {
227                    @Override
228                    public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
229                        if (keyCode == KeyEvent.KEYCODE_BACK) {
230                            finish();
231                        }
232                        return true;
233                    }
234                })
235                .setPositiveButton(getResources().getString(R.string.dialog_dismiss),
236                        new DialogInterface.OnClickListener() {
237                    @Override
238                    public void onClick(DialogInterface dialog, int which) {
239                        finish();
240                    }
241                })
242                .show();
243    }
244}
245