diff options
author | Selim Cinek <cinek@google.com> | 2015-09-01 18:05:08 -0700 |
---|---|---|
committer | Selim Cinek <cinek@google.com> | 2015-09-08 23:49:59 +0000 |
commit | edf47486507f5edad1d1d8e6091b9a82f9e56930 (patch) | |
tree | 5f3b8632b10361582754f3560785a77509cf56da /packages | |
parent | 3bed3bf498eadcaa760608a415c66e017d2eb690 (diff) | |
download | frameworks_base-edf47486507f5edad1d1d8e6091b9a82f9e56930.zip frameworks_base-edf47486507f5edad1d1d8e6091b9a82f9e56930.tar.gz frameworks_base-edf47486507f5edad1d1d8e6091b9a82f9e56930.tar.bz2 |
Removed the secure camera launcher
With Android M, the system correctly handles camera arbitration
and therefore the secure camera launcher was only adding delay.
Bug: 23713450
Change-Id: Icd5e7883f3560bfd0c9b5f7bd93675847949469b
Diffstat (limited to 'packages')
3 files changed, 3 insertions, 305 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java index f4439bf..012dc9c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java @@ -390,7 +390,8 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL serviceIntent.setAction(CameraPrewarmService.ACTION_PREWARM); try { if (getContext().bindServiceAsUser(serviceIntent, mPrewarmConnection, - Context.BIND_AUTO_CREATE, new UserHandle(UserHandle.USER_CURRENT))) { + Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE, + new UserHandle(UserHandle.USER_CURRENT))) { mPrewarmBound = true; } } catch (SecurityException e) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java index b93586e..9321938 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java @@ -111,12 +111,6 @@ public class NotificationPanelView extends PanelView implements private boolean mQsTracking; /** - * Handles launching the secure camera properly even when other applications may be using the - * camera hardware. - */ - private SecureCameraLaunchManager mSecureCameraLaunchManager; - - /** * If set, the ongoing touch gesture might both trigger the expansion in {@link PanelView} and * the expansion for quick settings. */ @@ -262,8 +256,6 @@ public class NotificationPanelView extends PanelView implements mKeyguardBottomArea = (KeyguardBottomAreaView) findViewById(R.id.keyguard_bottom_area); mQsNavbarScrim = findViewById(R.id.qs_navbar_scrim); mAfforanceHelper = new KeyguardAffordanceHelper(this, getContext()); - mSecureCameraLaunchManager = - new SecureCameraLaunchManager(getContext(), mKeyguardBottomArea); mLastOrientation = getResources().getConfiguration().orientation; // recompute internal state when qspanel height changes @@ -368,16 +360,6 @@ public class NotificationPanelView extends PanelView implements updateMaxHeadsUpTranslation(); } - @Override - public void onAttachedToWindow() { - mSecureCameraLaunchManager.create(); - } - - @Override - public void onDetachedFromWindow() { - mSecureCameraLaunchManager.destroy(); - } - private void startQsSizeChangeAnimation(int oldHeight, final int newHeight) { if (mQsSizeChangeAnimator != null) { oldHeight = (int) mQsSizeChangeAnimator.getAnimatedValue(); @@ -1963,7 +1945,7 @@ public class NotificationPanelView extends PanelView implements } else { EventLogTags.writeSysuiLockscreenGesture( EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_SWIPE_CAMERA, lengthDp, velocityDp); - mSecureCameraLaunchManager.startSecureCameraLaunch(); + mKeyguardBottomArea.launchCamera(); } mStatusBar.startLaunchTransitionTimeout(); mBlockTouches = true; @@ -2010,7 +1992,6 @@ public class NotificationPanelView extends PanelView implements boolean camera = getLayoutDirection() == LAYOUT_DIRECTION_RTL ? !rightIcon : rightIcon; if (camera) { - mSecureCameraLaunchManager.onSwipingStarted(); mKeyguardBottomArea.bindCameraPrewarmService(); } requestDisallowInterceptTouchEvent(true); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SecureCameraLaunchManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SecureCameraLaunchManager.java deleted file mode 100644 index 45c8938..0000000 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SecureCameraLaunchManager.java +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Copyright (C) 2014 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. - */ - -package com.android.systemui.statusbar.phone; - -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.hardware.camera2.CameraManager; -import android.os.AsyncTask; -import android.os.Handler; -import android.provider.MediaStore; -import android.util.Log; - -import com.android.internal.widget.LockPatternUtils; -import com.android.keyguard.KeyguardUpdateMonitor; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Handles launching the secure camera properly even when other applications may be using the camera - * hardware. - * - * When other applications (e.g., Face Unlock) are using the camera, they must close the camera to - * allow the secure camera to open it. Since we want to minimize the delay when opening the secure - * camera, other apps should close the camera at the first possible opportunity (i.e., as soon as - * the user begins swiping to go to the secure camera). - * - * If the camera is unavailable when the user begins to swipe, the SecureCameraLaunchManager sends a - * broadcast to tell other apps to close the camera. When and if the user completes their swipe to - * launch the secure camera, the SecureCameraLaunchManager delays launching the secure camera until - * a callback indicates that the camera has become available. If it doesn't receive that callback - * within a specified timeout period, the secure camera is launched anyway. - * - * Ideally, the secure camera would handle waiting for the camera to become available. This allows - * some of the time necessary to close the camera to happen in parallel with starting the secure - * camera app. We can't rely on all third-party camera apps to handle this. However, an app can - * put com.android.systemui.statusbar.phone.will_wait_for_camera_available in its meta-data to - * indicate that it will be responsible for waiting for the camera to become available. - * - * It is assumed that the functions in this class, including the constructor, will be called from - * the UI thread. - */ -public class SecureCameraLaunchManager { - private static final boolean DEBUG = false; - private static final String TAG = "SecureCameraLaunchManager"; - - // Action sent as a broadcast to tell other apps to stop using the camera. Other apps that use - // the camera from keyguard (e.g., Face Unlock) should listen for this broadcast and close the - // camera as soon as possible after receiving it. - private static final String CLOSE_CAMERA_ACTION_NAME = - "com.android.systemui.statusbar.phone.CLOSE_CAMERA"; - - // Apps should put this field in their meta-data to indicate that they will take on the - // responsibility of waiting for the camera to become available. If this field is present, the - // SecureCameraLaunchManager launches the secure camera even if the camera hardware has not - // become available. Having the secure camera app do the waiting is the optimal approach, but - // without this field, the SecureCameraLaunchManager doesn't launch the secure camera until the - // camera hardware is available. - private static final String META_DATA_WILL_WAIT_FOR_CAMERA_AVAILABLE = - "com.android.systemui.statusbar.phone.will_wait_for_camera_available"; - - // If the camera hardware hasn't become available after this period of time, the - // SecureCameraLaunchManager launches the secure camera anyway. - private static final int CAMERA_AVAILABILITY_TIMEOUT_MS = 1000; - - private Context mContext; - private Handler mHandler; - private LockPatternUtils mLockPatternUtils; - private KeyguardBottomAreaView mKeyguardBottomArea; - - private CameraManager mCameraManager; - private CameraAvailabilityCallback mCameraAvailabilityCallback; - private Map<String, Boolean> mCameraAvailabilityMap; - private boolean mWaitingToLaunchSecureCamera; - private Runnable mLaunchCameraRunnable; - - private class CameraAvailabilityCallback extends CameraManager.AvailabilityCallback { - @Override - public void onCameraUnavailable(String cameraId) { - if (DEBUG) Log.d(TAG, "onCameraUnavailble(" + cameraId + ")"); - mCameraAvailabilityMap.put(cameraId, false); - } - - @Override - public void onCameraAvailable(String cameraId) { - if (DEBUG) Log.d(TAG, "onCameraAvailable(" + cameraId + ")"); - mCameraAvailabilityMap.put(cameraId, true); - - // If we were waiting for the camera hardware to become available to launch the - // secure camera, we can launch it now if all cameras are available. If one or more - // cameras are still not available, we will get this callback again for those - // cameras. - if (mWaitingToLaunchSecureCamera && areAllCamerasAvailable()) { - mKeyguardBottomArea.launchCamera(); - mWaitingToLaunchSecureCamera = false; - - // We no longer need to launch the camera after the timeout hits. - mHandler.removeCallbacks(mLaunchCameraRunnable); - } - } - } - - public SecureCameraLaunchManager(Context context, KeyguardBottomAreaView keyguardBottomArea) { - mContext = context; - mHandler = new Handler(); - mLockPatternUtils = new LockPatternUtils(context); - mKeyguardBottomArea = keyguardBottomArea; - - mCameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE); - mCameraAvailabilityCallback = new CameraAvailabilityCallback(); - - // An onCameraAvailable() or onCameraUnavailable() callback will be received for each camera - // when the availability callback is registered, thus initializing the map. - // - // Keeping track of the state of all cameras using the onCameraAvailable() and - // onCameraUnavailable() callbacks can get messy when dealing with hot-pluggable cameras. - // However, we have a timeout in place such that we will never hang waiting for cameras. - mCameraAvailabilityMap = new HashMap<String, Boolean>(); - - mWaitingToLaunchSecureCamera = false; - mLaunchCameraRunnable = new Runnable() { - @Override - public void run() { - if (mWaitingToLaunchSecureCamera) { - Log.w(TAG, "Timeout waiting for camera availability"); - mKeyguardBottomArea.launchCamera(); - mWaitingToLaunchSecureCamera = false; - } - } - }; - } - - /** - * Initializes the SecureCameraManager and starts listening for camera availability. - */ - public void create() { - mCameraManager.registerAvailabilityCallback(mCameraAvailabilityCallback, mHandler); - } - - /** - * Stops listening for camera availability and cleans up the SecureCameraManager. - */ - public void destroy() { - mCameraManager.unregisterAvailabilityCallback(mCameraAvailabilityCallback); - } - - /** - * Called when the user is starting to swipe horizontally, possibly to start the secure camera. - * Although this swipe ultimately may not result in the secure camera opening, we need to stop - * all other camera usage (e.g., Face Unlock) as soon as possible. We send out a broadcast to - * notify other apps that they should close the camera immediately. The broadcast is sent even - * if the camera appears to be available, because there could be an app that is about to open - * the camera. - */ - public void onSwipingStarted() { - if (DEBUG) Log.d(TAG, "onSwipingStarted"); - AsyncTask.execute(new Runnable() { - @Override - public void run() { - Intent intent = new Intent(); - intent.setAction(CLOSE_CAMERA_ACTION_NAME); - intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); - mContext.sendBroadcast(intent); - } - }); - } - - /** - * Called when the secure camera should be started. If the camera is available or the secure - * camera app has indicated that it will wait for camera availability, the secure camera app is - * launched immediately. Otherwise, we wait for the camera to become available (or timeout) - * before launching the secure camera. - */ - public void startSecureCameraLaunch() { - if (DEBUG) Log.d(TAG, "startSecureCameraLunch"); - if (areAllCamerasAvailable() || targetWillWaitForCameraAvailable()) { - mKeyguardBottomArea.launchCamera(); - } else { - mWaitingToLaunchSecureCamera = true; - mHandler.postDelayed(mLaunchCameraRunnable, CAMERA_AVAILABILITY_TIMEOUT_MS); - } - } - - /** - * Returns true if all of the cameras we are tracking are currently available. - */ - private boolean areAllCamerasAvailable() { - for (boolean cameraAvailable: mCameraAvailabilityMap.values()) { - if (!cameraAvailable) { - return false; - } - } - return true; - } - - /** - * Determines if the secure camera app will wait for the camera hardware to become available - * before trying to open the camera. If so, we can fire off an intent to start the secure - * camera app before the camera is available. Otherwise, it is our responsibility to wait for - * the camera hardware to become available before firing off the intent to start the secure - * camera. - * - * Ideally we are able to fire off the secure camera intent as early as possibly so that, if the - * camera is closing, it can continue to close while the secure camera app is opening. This - * improves secure camera startup time. - */ - private boolean targetWillWaitForCameraAvailable() { - // Create intent that would launch the secure camera. - Intent intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE) - .addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); - PackageManager packageManager = mContext.getPackageManager(); - - // Get the list of applications that can handle the intent. - final List<ResolveInfo> appList = packageManager.queryIntentActivitiesAsUser( - intent, PackageManager.MATCH_DEFAULT_ONLY, KeyguardUpdateMonitor.getCurrentUser()); - if (appList.size() == 0) { - if (DEBUG) Log.d(TAG, "No targets found for secure camera intent"); - return false; - } - - // Get the application that the intent resolves to. - ResolveInfo resolved = packageManager.resolveActivityAsUser(intent, - PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_META_DATA, - KeyguardUpdateMonitor.getCurrentUser()); - - if (resolved == null || resolved.activityInfo == null) { - return false; - } - - // If we would need to launch the resolver activity, then we can't assume that the target - // is one that would wait for the camera. - if (wouldLaunchResolverActivity(resolved, appList)) { - if (DEBUG) Log.d(TAG, "Secure camera intent would launch resolver"); - return false; - } - - // If the target doesn't have meta-data we must assume it won't wait for the camera. - if (resolved.activityInfo.metaData == null || resolved.activityInfo.metaData.isEmpty()) { - if (DEBUG) Log.d(TAG, "No meta-data found for secure camera application"); - return false; - } - - // Check the secure camera app meta-data to see if it indicates that it will wait for the - // camera to become available. - boolean willWaitForCameraAvailability = - resolved.activityInfo.metaData.getBoolean(META_DATA_WILL_WAIT_FOR_CAMERA_AVAILABLE); - - if (DEBUG) Log.d(TAG, "Target will wait for camera: " + willWaitForCameraAvailability); - - return willWaitForCameraAvailability; - } - - /** - * Determines if the activity that would be launched by the intent is the ResolverActivity. - */ - private boolean wouldLaunchResolverActivity(ResolveInfo resolved, List<ResolveInfo> appList) { - // If the list contains the resolved activity, then it can't be the ResolverActivity itself. - for (int i = 0; i < appList.size(); i++) { - ResolveInfo tmp = appList.get(i); - if (tmp.activityInfo.name.equals(resolved.activityInfo.name) - && tmp.activityInfo.packageName.equals(resolved.activityInfo.packageName)) { - return false; - } - } - return true; - } -} |