Fix API review: Camera prewarm
Let the intent receiver of a camea launch intent declare a prewarm service instead of sending broadcasts. Bug: 21347653 Change-Id: I11e31aad4f788ad90eb46a661b819d3e808ddb51
This commit is contained in:
@@ -26126,8 +26126,6 @@ package android.provider {
|
||||
method public static java.lang.String getVersion(android.content.Context);
|
||||
field public static final java.lang.String ACTION_IMAGE_CAPTURE = "android.media.action.IMAGE_CAPTURE";
|
||||
field public static final java.lang.String ACTION_IMAGE_CAPTURE_SECURE = "android.media.action.IMAGE_CAPTURE_SECURE";
|
||||
field public static final java.lang.String ACTION_STILL_IMAGE_CAMERA_COOLDOWN = "android.media.action.STILL_IMAGE_CAMERA_COOLDOWN";
|
||||
field public static final java.lang.String ACTION_STILL_IMAGE_CAMERA_PREWARM = "android.media.action.STILL_IMAGE_CAMERA_PREWARM";
|
||||
field public static final java.lang.String ACTION_VIDEO_CAPTURE = "android.media.action.VIDEO_CAPTURE";
|
||||
field public static final java.lang.String AUTHORITY = "media";
|
||||
field public static final java.lang.String EXTRA_DURATION_LIMIT = "android.intent.extra.durationLimit";
|
||||
@@ -26155,6 +26153,7 @@ package android.provider {
|
||||
field public static final java.lang.String INTENT_ACTION_VIDEO_PLAY_FROM_SEARCH = "android.media.action.VIDEO_PLAY_FROM_SEARCH";
|
||||
field public static final java.lang.String MEDIA_IGNORE_FILENAME = ".nomedia";
|
||||
field public static final java.lang.String MEDIA_SCANNER_VOLUME = "volume";
|
||||
field public static final java.lang.String META_DATA_STILL_IMAGE_CAMERA_PREWARM_SERVICE = "android.media.still_image_camera_preview_service";
|
||||
field public static final java.lang.String UNKNOWN_STRING = "<unknown>";
|
||||
}
|
||||
|
||||
@@ -28713,6 +28712,13 @@ package android.service.dreams {
|
||||
|
||||
package android.service.media {
|
||||
|
||||
public abstract class CameraPrewarmService extends android.app.Service {
|
||||
ctor public CameraPrewarmService();
|
||||
method public android.os.IBinder onBind(android.content.Intent);
|
||||
method public abstract void onCooldown(boolean);
|
||||
method public abstract void onPrewarm();
|
||||
}
|
||||
|
||||
public abstract class MediaBrowserService extends android.app.Service {
|
||||
ctor public MediaBrowserService();
|
||||
method public void dump(java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
|
||||
|
||||
@@ -28049,8 +28049,6 @@ package android.provider {
|
||||
method public static java.lang.String getVersion(android.content.Context);
|
||||
field public static final java.lang.String ACTION_IMAGE_CAPTURE = "android.media.action.IMAGE_CAPTURE";
|
||||
field public static final java.lang.String ACTION_IMAGE_CAPTURE_SECURE = "android.media.action.IMAGE_CAPTURE_SECURE";
|
||||
field public static final java.lang.String ACTION_STILL_IMAGE_CAMERA_COOLDOWN = "android.media.action.STILL_IMAGE_CAMERA_COOLDOWN";
|
||||
field public static final java.lang.String ACTION_STILL_IMAGE_CAMERA_PREWARM = "android.media.action.STILL_IMAGE_CAMERA_PREWARM";
|
||||
field public static final java.lang.String ACTION_VIDEO_CAPTURE = "android.media.action.VIDEO_CAPTURE";
|
||||
field public static final java.lang.String AUTHORITY = "media";
|
||||
field public static final java.lang.String EXTRA_DURATION_LIMIT = "android.intent.extra.durationLimit";
|
||||
@@ -28078,6 +28076,7 @@ package android.provider {
|
||||
field public static final java.lang.String INTENT_ACTION_VIDEO_PLAY_FROM_SEARCH = "android.media.action.VIDEO_PLAY_FROM_SEARCH";
|
||||
field public static final java.lang.String MEDIA_IGNORE_FILENAME = ".nomedia";
|
||||
field public static final java.lang.String MEDIA_SCANNER_VOLUME = "volume";
|
||||
field public static final java.lang.String META_DATA_STILL_IMAGE_CAMERA_PREWARM_SERVICE = "android.media.still_image_camera_preview_service";
|
||||
field public static final java.lang.String UNKNOWN_STRING = "<unknown>";
|
||||
}
|
||||
|
||||
@@ -30739,6 +30738,13 @@ package android.service.dreams {
|
||||
|
||||
package android.service.media {
|
||||
|
||||
public abstract class CameraPrewarmService extends android.app.Service {
|
||||
ctor public CameraPrewarmService();
|
||||
method public android.os.IBinder onBind(android.content.Intent);
|
||||
method public abstract void onCooldown(boolean);
|
||||
method public abstract void onPrewarm();
|
||||
}
|
||||
|
||||
public abstract class MediaBrowserService extends android.app.Service {
|
||||
ctor public MediaBrowserService();
|
||||
method public void dump(java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
|
||||
|
||||
@@ -22,6 +22,7 @@ import android.content.ContentResolver;
|
||||
import android.content.ContentUris;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.database.DatabaseUtils;
|
||||
import android.database.sqlite.SQLiteException;
|
||||
@@ -33,6 +34,7 @@ import android.media.ThumbnailUtils;
|
||||
import android.net.Uri;
|
||||
import android.os.Environment;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.service.media.CameraPrewarmService;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
@@ -226,33 +228,24 @@ public final class MediaStore {
|
||||
public static final String INTENT_ACTION_STILL_IMAGE_CAMERA = "android.media.action.STILL_IMAGE_CAMERA";
|
||||
|
||||
/**
|
||||
* The name of the Intent action used to indicate that a camera launch might be imminent. This
|
||||
* broadcast should be targeted to the package that is receiving
|
||||
* {@link #INTENT_ACTION_STILL_IMAGE_CAMERA} or
|
||||
* {@link #INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE}, depending on the context. If such
|
||||
* intent would launch the resolver activity, this broadcast should not be sent at all.
|
||||
* Name under which an activity handling {@link #INTENT_ACTION_STILL_IMAGE_CAMERA} or
|
||||
* {@link #INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE} publishes the service name for its prewarm
|
||||
* service.
|
||||
* <p>
|
||||
* A receiver of this broadcast should do the absolute minimum amount of work to initialize the
|
||||
* camera in order to reduce startup time in likely case that shortly after an actual camera
|
||||
* launch intent would be sent.
|
||||
* This meta-data should reference the fully qualified class name of the prewarm service
|
||||
* extending {@link CameraPrewarmService}.
|
||||
* <p>
|
||||
* In case the actual intent will not be fired, the target package will receive
|
||||
* {@link #ACTION_STILL_IMAGE_CAMERA_COOLDOWN}. However, it is recommended that the receiver
|
||||
* also implements a timeout to close the camera after receiving this intent, as there is no
|
||||
* guarantee that {@link #ACTION_STILL_IMAGE_CAMERA_COOLDOWN} will be delivered.
|
||||
* The prewarm service will get bound and receive a prewarm signal
|
||||
* {@link CameraPrewarmService#onPrewarm()} when a camera launch intent fire might be imminent.
|
||||
* An application implementing a prewarm service should do the absolute minimum amount of work
|
||||
* to initialize the camera in order to reduce startup time in likely case that shortly after a
|
||||
* camera launch intent would be sent.
|
||||
* <p>
|
||||
* If the camera launch intent gets fired shortly after, the service will be unbound
|
||||
* asynchronously, without receiving
|
||||
*/
|
||||
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
|
||||
public static final String ACTION_STILL_IMAGE_CAMERA_PREWARM = "android.media.action.STILL_IMAGE_CAMERA_PREWARM";
|
||||
|
||||
/**
|
||||
* The name of the Intent action used to indicate that an imminent camera launch has been
|
||||
* cancelled by the user. This broadcast should be targeted to the package that has received
|
||||
* {@link #ACTION_STILL_IMAGE_CAMERA_PREWARM}.
|
||||
* <p>
|
||||
* A receiver of this broadcast should close the camera immediately.
|
||||
*/
|
||||
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
|
||||
public static final String ACTION_STILL_IMAGE_CAMERA_COOLDOWN = "android.media.action.STILL_IMAGE_CAMERA_COOLDOWN";
|
||||
public static final String META_DATA_STILL_IMAGE_CAMERA_PREWARM_SERVICE =
|
||||
"android.media.still_image_camera_preview_service";
|
||||
|
||||
/**
|
||||
* The name of the Intent action used to launch a camera in still image mode
|
||||
@@ -2268,5 +2261,4 @@ public final class MediaStore {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
96
core/java/android/service/media/CameraPrewarmService.java
Normal file
96
core/java/android/service/media/CameraPrewarmService.java
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
package android.service.media;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Message;
|
||||
import android.os.Messenger;
|
||||
|
||||
/**
|
||||
* Extend this class to implement a camera prewarm service. See
|
||||
* {@link android.provider.MediaStore#META_DATA_STILL_IMAGE_CAMERA_PREWARM_SERVICE}.
|
||||
*/
|
||||
public abstract class CameraPrewarmService extends Service {
|
||||
|
||||
/**
|
||||
* Intent action to bind the service as a prewarm service.
|
||||
* @hide
|
||||
*/
|
||||
public static final String ACTION_PREWARM =
|
||||
"android.service.media.CameraPrewarmService.ACTION_PREWARM";
|
||||
|
||||
/**
|
||||
* Message sent by the client indicating that the camera intent has been fired.
|
||||
* @hide
|
||||
*/
|
||||
public static final int MSG_CAMERA_FIRED = 1;
|
||||
|
||||
private final Handler mHandler = new Handler() {
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
switch (msg.what) {
|
||||
case MSG_CAMERA_FIRED:
|
||||
mCameraIntentFired = true;
|
||||
break;
|
||||
default:
|
||||
super.handleMessage(msg);
|
||||
}
|
||||
}
|
||||
};
|
||||
private boolean mCameraIntentFired;
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
if (ACTION_PREWARM.equals(intent.getAction())) {
|
||||
onPrewarm();
|
||||
return new Messenger(mHandler).getBinder();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onUnbind(Intent intent) {
|
||||
if (ACTION_PREWARM.equals(intent.getAction())) {
|
||||
onCooldown(mCameraIntentFired);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the camera should be prewarmed.
|
||||
*/
|
||||
public abstract void onPrewarm();
|
||||
|
||||
/**
|
||||
* Called when prewarm phase is done, either because the camera launch intent has been fired
|
||||
* at this point or prewarm is no longer needed. A client should close the camera
|
||||
* immediately in the latter case.
|
||||
* <p>
|
||||
* In case the camera launch intent has been fired, there is no guarantee about the ordering
|
||||
* of these two events. Cooldown might happen either before or after the activity has been
|
||||
* created that handles the camera intent.
|
||||
*
|
||||
* @param cameraIntentFired Indicates whether the intent to launch the camera has been
|
||||
* fired.
|
||||
*/
|
||||
public abstract void onCooldown(boolean cameraIntentFired);
|
||||
}
|
||||
@@ -60,6 +60,7 @@ public class KeyguardHostView extends FrameLayout implements SecurityCallback {
|
||||
protected ViewMediatorCallback mViewMediatorCallback;
|
||||
protected LockPatternUtils mLockPatternUtils;
|
||||
private OnDismissAction mDismissAction;
|
||||
private Runnable mCancelAction;
|
||||
|
||||
private final KeyguardUpdateMonitorCallback mUpdateCallback =
|
||||
new KeyguardUpdateMonitorCallback() {
|
||||
@@ -126,8 +127,17 @@ public class KeyguardHostView extends FrameLayout implements SecurityCallback {
|
||||
*
|
||||
* @param action
|
||||
*/
|
||||
public void setOnDismissAction(OnDismissAction action) {
|
||||
public void setOnDismissAction(OnDismissAction action, Runnable cancelAction) {
|
||||
if (mCancelAction != null) {
|
||||
mCancelAction.run();
|
||||
mCancelAction = null;
|
||||
}
|
||||
mDismissAction = action;
|
||||
mCancelAction = cancelAction;
|
||||
}
|
||||
|
||||
public void cancelDismissAction() {
|
||||
setOnDismissAction(null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -197,6 +207,7 @@ public class KeyguardHostView extends FrameLayout implements SecurityCallback {
|
||||
if (mDismissAction != null) {
|
||||
deferKeyguardDone = mDismissAction.onDismiss();
|
||||
mDismissAction = null;
|
||||
mCancelAction = null;
|
||||
}
|
||||
if (mViewMediatorCallback != null) {
|
||||
if (deferKeyguardDone) {
|
||||
|
||||
@@ -24,6 +24,11 @@ import android.content.Intent;
|
||||
* Keyguard.
|
||||
*/
|
||||
public interface ActivityStarter {
|
||||
public void startActivity(Intent intent, boolean dismissShade);
|
||||
void startActivity(Intent intent, boolean dismissShade);
|
||||
void startActivity(Intent intent, boolean dismissShade, Callback callback);
|
||||
void preventNextAnimation();
|
||||
|
||||
interface Callback {
|
||||
void onActivityStarted(int resultCode);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,7 +160,7 @@ public class KeyguardAffordanceHelper {
|
||||
} else {
|
||||
mTouchSlopExeeded = false;
|
||||
}
|
||||
mCallback.onSwipingStarted(targetView == mLeftIcon);
|
||||
mCallback.onSwipingStarted(targetView == mRightIcon);
|
||||
mSwipingInProgress = true;
|
||||
mTargetedView = targetView;
|
||||
mInitialTouchX = x;
|
||||
@@ -550,7 +550,7 @@ public class KeyguardAffordanceHelper {
|
||||
|
||||
float getMaxTranslationDistance();
|
||||
|
||||
void onSwipingStarted(boolean isRightwardMotion);
|
||||
void onSwipingStarted(boolean rightIcon);
|
||||
|
||||
void onSwipingAborted();
|
||||
|
||||
|
||||
@@ -16,12 +16,17 @@
|
||||
|
||||
package com.android.systemui.statusbar.phone;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.app.ActivityManagerNative;
|
||||
import android.app.Application;
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.ServiceConnection;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.res.Configuration;
|
||||
@@ -29,9 +34,13 @@ import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.InsetDrawable;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.Message;
|
||||
import android.os.Messenger;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.MediaStore;
|
||||
import android.service.media.CameraPrewarmService;
|
||||
import android.telecom.TelecomManager;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
@@ -100,7 +109,23 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
|
||||
private PhoneStatusBar mPhoneStatusBar;
|
||||
|
||||
private final Interpolator mLinearOutSlowInInterpolator;
|
||||
private boolean mPrewarmSent;
|
||||
private boolean mPrewarmBound;
|
||||
private Messenger mPrewarmMessenger;
|
||||
private final ServiceConnection mPrewarmConnection = new ServiceConnection() {
|
||||
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||
mPrewarmMessenger = new Messenger(service);
|
||||
mPrewarmBound = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceDisconnected(ComponentName name) {
|
||||
mPrewarmBound = false;
|
||||
mPrewarmMessenger = null;
|
||||
}
|
||||
};
|
||||
|
||||
private boolean mLeftIsVoiceAssist;
|
||||
private AssistManager mAssistManager;
|
||||
|
||||
@@ -343,37 +368,44 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
|
||||
mLockPatternUtils.requireCredentialEntry(KeyguardUpdateMonitor.getCurrentUser());
|
||||
}
|
||||
|
||||
public void prewarmCamera() {
|
||||
public void bindCameraPrewarmService() {
|
||||
Intent intent = getCameraIntent();
|
||||
String targetPackage = PreviewInflater.getTargetPackage(mContext, intent,
|
||||
ActivityInfo targetInfo = PreviewInflater.getTargetActivityInfo(mContext, intent,
|
||||
KeyguardUpdateMonitor.getCurrentUser());
|
||||
if (targetPackage != null) {
|
||||
Intent prewarm = new Intent(MediaStore.ACTION_STILL_IMAGE_CAMERA_PREWARM);
|
||||
prewarm.setPackage(targetPackage);
|
||||
mPrewarmSent = true;
|
||||
mContext.sendBroadcast(prewarm);
|
||||
if (targetInfo != null) {
|
||||
String clazz = targetInfo.metaData.getString(
|
||||
MediaStore.META_DATA_STILL_IMAGE_CAMERA_PREWARM_SERVICE);
|
||||
if (clazz != null) {
|
||||
Intent serviceIntent = new Intent();
|
||||
serviceIntent.setClassName(targetInfo.packageName, clazz);
|
||||
serviceIntent.setAction(CameraPrewarmService.ACTION_PREWARM);
|
||||
try {
|
||||
getContext().bindServiceAsUser(serviceIntent, mPrewarmConnection,
|
||||
Context.BIND_AUTO_CREATE, new UserHandle(UserHandle.USER_CURRENT));
|
||||
} catch (SecurityException e) {
|
||||
Log.w(TAG, "Unable to bind to prewarm service package=" + targetInfo.packageName
|
||||
+ " class=" + clazz, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void maybeCooldownCamera() {
|
||||
if (!mPrewarmSent) {
|
||||
return;
|
||||
}
|
||||
mPrewarmSent = false;
|
||||
Intent intent = getCameraIntent();
|
||||
String targetPackage = PreviewInflater.getTargetPackage(mContext, intent,
|
||||
KeyguardUpdateMonitor.getCurrentUser());
|
||||
if (targetPackage != null) {
|
||||
Intent prewarm = new Intent(MediaStore.ACTION_STILL_IMAGE_CAMERA_COOLDOWN);
|
||||
prewarm.setPackage(targetPackage);
|
||||
mContext.sendBroadcast(prewarm);
|
||||
public void unbindCameraPrewarmService(boolean launched) {
|
||||
if (mPrewarmBound) {
|
||||
if (launched) {
|
||||
try {
|
||||
mPrewarmMessenger.send(Message.obtain(null /* handler */,
|
||||
CameraPrewarmService.MSG_CAMERA_FIRED));
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Error sending camera fired message", e);
|
||||
}
|
||||
}
|
||||
mContext.unbindService(mPrewarmConnection);
|
||||
mPrewarmBound = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void launchCamera() {
|
||||
|
||||
// Reset prewarm state.
|
||||
mPrewarmSent = false;
|
||||
final Intent intent = getCameraIntent();
|
||||
boolean wouldLaunchResolverActivity = PreviewInflater.wouldLaunchResolverActivity(
|
||||
mContext, intent, KeyguardUpdateMonitor.getCurrentUser());
|
||||
@@ -381,18 +413,47 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
|
||||
AsyncTask.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mContext.startActivityAsUser(intent, UserHandle.CURRENT);
|
||||
int result = ActivityManager.START_CANCELED;
|
||||
try {
|
||||
result = ActivityManagerNative.getDefault().startActivityAsUser(
|
||||
null, getContext().getBasePackageName(),
|
||||
intent,
|
||||
intent.resolveTypeIfNeeded(getContext().getContentResolver()),
|
||||
null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, null,
|
||||
UserHandle.CURRENT.getIdentifier());
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Unable to start camera activity", e);
|
||||
}
|
||||
mActivityStarter.preventNextAnimation();
|
||||
final boolean launched = isSuccessfulLaunch(result);
|
||||
post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
unbindCameraPrewarmService(launched);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
|
||||
// We need to delay starting the activity because ResolverActivity finishes itself if
|
||||
// launched behind lockscreen.
|
||||
mActivityStarter.startActivity(intent, false /* dismissShade */);
|
||||
mActivityStarter.startActivity(intent, false /* dismissShade */,
|
||||
new ActivityStarter.Callback() {
|
||||
@Override
|
||||
public void onActivityStarted(int resultCode) {
|
||||
unbindCameraPrewarmService(isSuccessfulLaunch(resultCode));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isSuccessfulLaunch(int result) {
|
||||
return result == ActivityManager.START_SUCCESS
|
||||
|| result == ActivityManager.START_DELIVERED_TO_TOP
|
||||
|| result == ActivityManager.START_TASK_TO_FRONT;
|
||||
}
|
||||
|
||||
public void launchLeftAffordance() {
|
||||
if (mLeftIsVoiceAssist) {
|
||||
launchVoiceAssist();
|
||||
@@ -412,8 +473,8 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
|
||||
if (mPhoneStatusBar.isKeyguardCurrentlySecure()) {
|
||||
AsyncTask.execute(runnable);
|
||||
} else {
|
||||
mPhoneStatusBar.executeRunnableDismissingKeyguard(runnable, false /* dismissShade */,
|
||||
false /* afterKeyguardGone */);
|
||||
mPhoneStatusBar.executeRunnableDismissingKeyguard(runnable, null /* cancelAction */,
|
||||
false /* dismissShade */, false /* afterKeyguardGone */);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -95,16 +95,16 @@ public class KeyguardBouncer {
|
||||
mShowingSoon = false;
|
||||
}
|
||||
|
||||
public void showWithDismissAction(OnDismissAction r) {
|
||||
public void showWithDismissAction(OnDismissAction r, Runnable cancelAction) {
|
||||
ensureView();
|
||||
mKeyguardView.setOnDismissAction(r);
|
||||
mKeyguardView.setOnDismissAction(r, cancelAction);
|
||||
show(false /* resetSecuritySelection */);
|
||||
}
|
||||
|
||||
public void hide(boolean destroyView) {
|
||||
cancelShowRunnable();
|
||||
if (mKeyguardView != null) {
|
||||
mKeyguardView.setOnDismissAction(null);
|
||||
mKeyguardView.cancelDismissAction();
|
||||
mKeyguardView.cleanUp();
|
||||
}
|
||||
if (destroyView) {
|
||||
|
||||
@@ -1934,12 +1934,12 @@ public class NotificationPanelView extends PanelView implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSwipingStarted(boolean isRightwardMotion) {
|
||||
boolean start = getLayoutDirection() == LAYOUT_DIRECTION_RTL ? isRightwardMotion
|
||||
: !isRightwardMotion;
|
||||
if (!start) {
|
||||
public void onSwipingStarted(boolean rightIcon) {
|
||||
boolean camera = getLayoutDirection() == LAYOUT_DIRECTION_RTL ? !rightIcon
|
||||
: rightIcon;
|
||||
if (camera) {
|
||||
mSecureCameraLaunchManager.onSwipingStarted();
|
||||
mKeyguardBottomArea.prewarmCamera();
|
||||
mKeyguardBottomArea.bindCameraPrewarmService();
|
||||
}
|
||||
requestDisallowInterceptTouchEvent(true);
|
||||
mOnlyAffordanceInThisMotion = true;
|
||||
@@ -1948,7 +1948,7 @@ public class NotificationPanelView extends PanelView implements
|
||||
|
||||
@Override
|
||||
public void onSwipingAborted() {
|
||||
mKeyguardBottomArea.maybeCooldownCamera();
|
||||
mKeyguardBottomArea.unbindCameraPrewarmService(false /* launched */);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1825,6 +1825,11 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
startActivityDismissingKeyguard(intent, false, dismissShade);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startActivity(Intent intent, boolean dismissShade, Callback callback) {
|
||||
startActivityDismissingKeyguard(intent, false, dismissShade, callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preventNextAnimation() {
|
||||
overrideActivityPendingAppTransition(true /* keyguardShowing */);
|
||||
@@ -2707,7 +2712,12 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
}
|
||||
|
||||
public void startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned,
|
||||
final boolean dismissShade) {
|
||||
boolean dismissShade) {
|
||||
startActivityDismissingKeyguard(intent, onlyProvisioned, dismissShade, null /* callback */);
|
||||
}
|
||||
|
||||
public void startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned,
|
||||
final boolean dismissShade, final Callback callback) {
|
||||
if (onlyProvisioned && !isDeviceProvisioned()) return;
|
||||
|
||||
final boolean afterKeyguardGone = PreviewInflater.wouldLaunchResolverActivity(
|
||||
@@ -2717,16 +2727,35 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
public void run() {
|
||||
intent.setFlags(
|
||||
Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||
mContext.startActivityAsUser(
|
||||
intent, new UserHandle(UserHandle.USER_CURRENT));
|
||||
int result = ActivityManager.START_CANCELED;
|
||||
try {
|
||||
result = ActivityManagerNative.getDefault().startActivityAsUser(
|
||||
null, mContext.getBasePackageName(),
|
||||
intent,
|
||||
intent.resolveTypeIfNeeded(mContext.getContentResolver()),
|
||||
null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, null,
|
||||
UserHandle.CURRENT.getIdentifier());
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Unable to start activity", e);
|
||||
}
|
||||
overrideActivityPendingAppTransition(
|
||||
keyguardShowing && !afterKeyguardGone);
|
||||
if (callback != null) {
|
||||
callback.onActivityStarted(result);
|
||||
}
|
||||
}
|
||||
};
|
||||
executeRunnableDismissingKeyguard(runnable, dismissShade, afterKeyguardGone);
|
||||
Runnable cancelRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
callback.onActivityStarted(ActivityManager.START_CANCELED);
|
||||
}
|
||||
};
|
||||
executeRunnableDismissingKeyguard(runnable, cancelRunnable, dismissShade, afterKeyguardGone);
|
||||
}
|
||||
|
||||
public void executeRunnableDismissingKeyguard(final Runnable runnable,
|
||||
final Runnable cancelAction,
|
||||
final boolean dismissShade,
|
||||
final boolean afterKeyguardGone) {
|
||||
final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing();
|
||||
@@ -2753,7 +2782,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}, afterKeyguardGone);
|
||||
}, cancelAction, afterKeyguardGone);
|
||||
}
|
||||
|
||||
private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
|
||||
@@ -2813,10 +2842,15 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dismissKeyguardThenExecute(final OnDismissAction action,
|
||||
protected void dismissKeyguardThenExecute(OnDismissAction action, boolean afterKeyguardGone) {
|
||||
dismissKeyguardThenExecute(action, null /* cancelRunnable */, afterKeyguardGone);
|
||||
}
|
||||
|
||||
private void dismissKeyguardThenExecute(OnDismissAction action, Runnable cancelAction,
|
||||
boolean afterKeyguardGone) {
|
||||
if (mStatusBarKeyguardViewManager.isShowing()) {
|
||||
mStatusBarKeyguardViewManager.dismissWithAction(action, afterKeyguardGone);
|
||||
mStatusBarKeyguardViewManager.dismissWithAction(action, cancelAction,
|
||||
afterKeyguardGone);
|
||||
} else {
|
||||
action.onDismiss();
|
||||
}
|
||||
|
||||
@@ -126,10 +126,11 @@ public class StatusBarKeyguardViewManager {
|
||||
updateStates();
|
||||
}
|
||||
|
||||
public void dismissWithAction(OnDismissAction r, boolean afterKeyguardGone) {
|
||||
public void dismissWithAction(OnDismissAction r, Runnable cancelAction,
|
||||
boolean afterKeyguardGone) {
|
||||
if (mShowing) {
|
||||
if (!afterKeyguardGone) {
|
||||
mBouncer.showWithDismissAction(r);
|
||||
mBouncer.showWithDismissAction(r, cancelAction);
|
||||
} else {
|
||||
mBouncer.show(false /* resetSecuritySelection */);
|
||||
mAfterKeyguardGoneAction = r;
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.systemui.statusbar.policy;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.os.Bundle;
|
||||
@@ -138,14 +139,14 @@ public class PreviewInflater {
|
||||
|
||||
public static boolean wouldLaunchResolverActivity(Context ctx, Intent intent,
|
||||
int currentUserId) {
|
||||
return getTargetPackage(ctx, intent, currentUserId) == null;
|
||||
return getTargetActivityInfo(ctx, intent, currentUserId) == null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the target package of the intent it resolves to a specific package or {@code null} if
|
||||
* it resolved to the resolver activity
|
||||
* @return the target activity info of the intent it resolves to a specific package or
|
||||
* {@code null} if it resolved to the resolver activity
|
||||
*/
|
||||
public static String getTargetPackage(Context ctx, Intent intent,
|
||||
public static ActivityInfo getTargetActivityInfo(Context ctx, Intent intent,
|
||||
int currentUserId) {
|
||||
PackageManager packageManager = ctx.getPackageManager();
|
||||
final List<ResolveInfo> appList = packageManager.queryIntentActivitiesAsUser(
|
||||
@@ -158,7 +159,7 @@ public class PreviewInflater {
|
||||
if (resolved == null || wouldLaunchResolverActivity(resolved, appList)) {
|
||||
return null;
|
||||
} else {
|
||||
return resolved.activityInfo.packageName;
|
||||
return resolved.activityInfo;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,14 +21,14 @@
|
||||
|
||||
<activity android:name=".CameraActivity"
|
||||
android:theme="@android:style/Theme.NoTitleBar">
|
||||
<intent-filter>
|
||||
<action android:name="android.media.action.STILL_IMAGE_CAMERA_SECURE" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.media.action.STILL_IMAGE_CAMERA" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
<meta-data
|
||||
android:name="android.media.still_image_camera_preview_service"
|
||||
android:value="com.google.android.test.cameraprewarm.PrewarmService">
|
||||
</meta-data>
|
||||
</activity>
|
||||
|
||||
<activity android:name=".SecureCameraActivity"
|
||||
@@ -37,16 +37,15 @@
|
||||
<action android:name="android.media.action.STILL_IMAGE_CAMERA_SECURE" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
<meta-data
|
||||
android:name="android.media.still_image_camera_preview_service"
|
||||
android:value="com.google.android.test.cameraprewarm.PrewarmService">
|
||||
</meta-data>
|
||||
</activity>
|
||||
|
||||
<receiver android:name=".PrewarmReceiver" >
|
||||
<intent-filter>
|
||||
<action android:name="android.media.action.STILL_IMAGE_CAMERA_PREWARM" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.media.action.STILL_IMAGE_CAMERA_COOLDOWN" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<service android:name=".PrewarmService"
|
||||
android:exported="true">
|
||||
</service>
|
||||
|
||||
</application>
|
||||
</manifest>
|
||||
|
||||
@@ -16,6 +16,6 @@
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<string name="activity_title">Assistant</string>
|
||||
<string name="activity_title">Camera Prewarm test</string>
|
||||
<string name="search_label">Orilla Search Engine</string>
|
||||
</resources>
|
||||
|
||||
@@ -19,7 +19,6 @@ package com.google.android.test.cameraprewarm;
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.google.android.test.cameraprewarm.R;
|
||||
|
||||
@@ -31,7 +30,6 @@ public class CameraActivity extends Activity {
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.camera_activity);
|
||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
|
||||
Log.i(TAG, "Activity created");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,20 +16,18 @@
|
||||
|
||||
package com.google.android.test.cameraprewarm;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.provider.MediaStore;
|
||||
import android.service.media.CameraPrewarmService;
|
||||
import android.util.Log;
|
||||
|
||||
public class PrewarmReceiver extends BroadcastReceiver {
|
||||
public class PrewarmService extends CameraPrewarmService {
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (intent.getAction().equals(MediaStore.ACTION_STILL_IMAGE_CAMERA_PREWARM)) {
|
||||
Log.i(CameraActivity.TAG, "Prewarm received");
|
||||
} else if (intent.getAction().equals(MediaStore.ACTION_STILL_IMAGE_CAMERA_COOLDOWN)){
|
||||
Log.i(CameraActivity.TAG, "Cooldown received");
|
||||
}
|
||||
public void onPrewarm() {
|
||||
Log.i("PrewarmService", "Warming up");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCooldown(boolean cameraIntentFired) {
|
||||
Log.i("PrewarmService", "Cooling down fired=" + cameraIntentFired);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user