From dd334be92c5513a06c809ee3ea25e411dfad0589 Mon Sep 17 00:00:00 2001 From: zafir Date: Wed, 15 Jul 2015 01:14:10 -0700 Subject: Camera M permissions: lockscreen improvements This CL now just provides some improvements for lockscreen independent of any onCreate/onResume lifecycle adjustments. Fixes include: * add a black content view to Permissions Activity -- noticed screen junk opening from lockscreen due to unpainted regions, the whole activity needs to paint the screen not just the dialog. * use FLAG_SHOW_WHEN_LOCKED to show permissions screen over lockscreen, per bug discussion in this case force failure, don't prompt for permission grants. * fun double onResumes induce flicker jank in the dialog UI. Inherit QuickActivity to automatically pick up the workarounds for double onResumes from lockscreens, no more flicker in the permission dialog. * also borrow from CameraActivity, broadcast receives to shut down the permissions dialog when screen goes off or user hits home on top of lockscreen. Actually apply this more broadly so that even below lockscreen, we finish this activity on screen off, IMO it is jarring to go in through lockscreen and see our permission dialog again without context of having just opened camera. * tweak permission dialog to not be cancelable, and to finish activity on back button press. * excludeFromRecents on the activity to prevent dual recents for Camera to show up when opening both via SecureCameraActivity and CameraActivity. Bug: 22502696 Change-Id: Ib545d3baa2d83b52604eec5517047b0c6278cd92 --- AndroidManifest.xml | 1 + res/layout/permissions.xml | 21 +++++++ src/com/android/camera/PermissionsActivity.java | 78 ++++++++++++++++++++++--- 3 files changed, 92 insertions(+), 8 deletions(-) create mode 100644 res/layout/permissions.xml diff --git a/AndroidManifest.xml b/AndroidManifest.xml index b8816a616..c5fdb6653 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -73,6 +73,7 @@ + + diff --git a/src/com/android/camera/PermissionsActivity.java b/src/com/android/camera/PermissionsActivity.java index 5824fd5de..9d2708fd0 100644 --- a/src/com/android/camera/PermissionsActivity.java +++ b/src/com/android/camera/PermissionsActivity.java @@ -2,20 +2,30 @@ package com.android.camera; import android.Manifest; import android.app.Activity; +import android.app.Dialog; import android.app.AlertDialog; +import android.app.KeyguardManager; +import android.content.BroadcastReceiver; +import android.content.Context; import android.content.DialogInterface; +import android.content.Intent; +import android.content.IntentFilter; import android.content.pm.PackageManager; import android.os.Bundle; +import android.view.KeyEvent; +import android.view.Window; +import android.view.WindowManager; import com.android.camera.app.CameraServicesImpl; import com.android.camera.debug.Log; import com.android.camera.settings.Keys; import com.android.camera.settings.SettingsManager; +import com.android.camera.util.QuickActivity; import com.android.camera2.R; /** * Activity that shows permissions request dialogs and handles lack of critical permissions. */ -public class PermissionsActivity extends Activity { +public class PermissionsActivity extends QuickActivity { private static final Log.Tag TAG = new Log.Tag("PermissionsActivity"); private static int PERMISSION_REQUEST_CODE = 1; @@ -36,19 +46,56 @@ public class PermissionsActivity extends Activity { private boolean mFlagHasStoragePermission; private SettingsManager mSettingsManager; + /** + * Close activity when secure app passes lock screen or screen turns + * off. + */ + private final BroadcastReceiver mShutdownReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + Log.v(TAG, "received intent, finishing: " + intent.getAction()); + finish(); + } + }; + @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); + protected void onCreateTasks(Bundle savedInstanceState) { + setContentView(R.layout.permissions); mSettingsManager = CameraServicesImpl.instance().getSettingsManager(); + + // Filter for screen off so that we can finish permissions activity + // when screen is off. + IntentFilter filter_screen_off = new IntentFilter(Intent.ACTION_SCREEN_OFF); + registerReceiver(mShutdownReceiver, filter_screen_off); + + // Filter for phone unlock so that we can finish permissions activity + // via this UI path: + // 1. from secure lock screen, user starts secure camera + // 2. user presses home button + // 3. user unlocks phone + IntentFilter filter_user_unlock = new IntentFilter(Intent.ACTION_USER_PRESENT); + registerReceiver(mShutdownReceiver, filter_user_unlock); + + Window win = getWindow(); + if (isKeyguardLocked()) { + win.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED); + } else { + win.clearFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED); + } } @Override - protected void onResume() { - super.onResume(); + protected void onResumeTasks() { mNumPermissionsToRequest = 0; checkPermissions(); } + @Override + protected void onDestroyTasks() { + Log.v(TAG, "onDestroy: unregistering receivers"); + unregisterReceiver(mShutdownReceiver); + } + private void checkPermissions() { if (checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { @@ -81,11 +128,12 @@ public class PermissionsActivity extends Activity { } if (mNumPermissionsToRequest != 0) { - if (!mSettingsManager.getBoolean(SettingsManager.SCOPE_GLOBAL, + if (!isKeyguardLocked() && !mSettingsManager.getBoolean(SettingsManager.SCOPE_GLOBAL, Keys.KEY_HAS_SEEN_PERMISSIONS_DIALOGS)) { buildPermissionsRequest(); } else { - //Permissions dialog has already been shown, and we're still missing permissions. + // Permissions dialog has already been shown, or we're on + // lockscreen, and we're still missing permissions. handlePermissionsFailure(); } } else { @@ -117,12 +165,14 @@ public class PermissionsActivity extends Activity { mIndexPermissionRequestLocation = permissionsRequestIndex; } + Log.v(TAG, "requestPermissions count: " + permissionsToRequest.length); requestPermissions(permissionsToRequest, PERMISSION_REQUEST_CODE); } @Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { + Log.v(TAG, "onPermissionsResult counts: " + permissions.length + ":" + grantResults.length); mSettingsManager.set( SettingsManager.SCOPE_GLOBAL, Keys.KEY_HAS_SEEN_PERMISSIONS_DIALOGS, @@ -171,7 +221,19 @@ public class PermissionsActivity extends Activity { private void handlePermissionsFailure() { new AlertDialog.Builder(this).setTitle(getResources().getString(R.string.camera_error_title)) .setMessage(getResources().getString(R.string.error_permissions)) - .setPositiveButton(getResources().getString(R.string.dialog_dismiss), new DialogInterface.OnClickListener() { + .setCancelable(false) + .setOnKeyListener(new Dialog.OnKeyListener() { + @Override + public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + setResult(RESULT_CODE_FAILED, null); + finish(); + } + return true; + } + }) + .setPositiveButton(getResources().getString(R.string.dialog_dismiss), + new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { setResult(RESULT_CODE_FAILED, null); -- cgit v1.2.3