OSDN Git Service

Camera M permissions: lockscreen improvements
authorzafir <zafir@google.com>
Wed, 15 Jul 2015 08:14:10 +0000 (01:14 -0700)
committerAlan Newberger <alann@google.com>
Fri, 17 Jul 2015 18:09:18 +0000 (11:09 -0700)
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
res/layout/permissions.xml [new file with mode: 0644]
src/com/android/camera/PermissionsActivity.java

index b8816a6..c5fdb66 100644 (file)
@@ -73,6 +73,7 @@
         <activity
                 android:name="com.android.camera.PermissionsActivity"
                 android:label="@string/app_name"
+                android:excludeFromRecents="true"
                 android:parentActivityName="com.android.camera.CameraActivity" >
             <meta-data
                     android:name="android.support.PARENT_ACTIVITY"
diff --git a/res/layout/permissions.xml b/res/layout/permissions.xml
new file mode 100644 (file)
index 0000000..389b1e1
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/permissions"
+    android:background="@android:color/black"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent" />
index 5824fd5..9d2708f 100644 (file)
@@ -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);