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:
Jorim Jaggi
2015-05-29 14:49:08 -07:00
parent cd0f3a1afe
commit d944986fbd
17 changed files with 317 additions and 109 deletions

View File

@@ -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[]);

View File

@@ -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[]);

View File

@@ -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;
}
}

View 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);
}

View File

@@ -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) {

View File

@@ -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);
}
}

View File

@@ -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();

View File

@@ -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 */);
}
}

View File

@@ -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) {

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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;

View File

@@ -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;
}
}

View File

@@ -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>

View File

@@ -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>

View File

@@ -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");
}
}

View File

@@ -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);
}
}