Merge "Manual frameworks/base merge from lockhotness (camera)." into jb-mr1-lockscreen-dev

This commit is contained in:
John Spurlock
2012-10-25 11:40:11 -07:00
committed by Android (Google) Code Review
10 changed files with 322 additions and 285 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

View File

@@ -3935,14 +3935,6 @@
you will be asked to unlock your phone using an email account.\n\n you will be asked to unlock your phone using an email account.\n\n
Try again in <xliff:g id="number">%d</xliff:g> seconds. Try again in <xliff:g id="number">%d</xliff:g> seconds.
</string> </string>
<!-- Placeholder text shown if the camera widget layout is missing or invalid -->
<string name="kg_camera_widget_not_found">Camera widget not found</string>
<!-- DO NOT TRANSLATE. Context package to use when locating the camera widget -->
<string name="kg_camera_widget_context_package">com.google.android.gallery3d</string>
<!-- DO NOT TRANSLATE. Layout package to use when locating the camera widget -->
<string name="kg_camera_widget_layout_package">com.android.gallery3d</string>
<!-- DO NOT TRANSLATE. Layout name to use when locating the camera widget -->
<string name="kg_camera_widget_layout_name">keyguard_widget</string>
<!-- Message shown in dialog when user is attempting to set the music volume above the <!-- Message shown in dialog when user is attempting to set the music volume above the
recommended maximum level for headphones --> recommended maximum level for headphones -->

View File

@@ -1383,10 +1383,6 @@
<java-symbol type="string" name="keyguard_password_enter_pin_code" /> <java-symbol type="string" name="keyguard_password_enter_pin_code" />
<java-symbol type="string" name="keyguard_password_enter_puk_code" /> <java-symbol type="string" name="keyguard_password_enter_puk_code" />
<java-symbol type="string" name="keyguard_password_wrong_pin_code" /> <java-symbol type="string" name="keyguard_password_wrong_pin_code" />
<java-symbol type="string" name="kg_camera_widget_context_package" />
<java-symbol type="string" name="kg_camera_widget_layout_name" />
<java-symbol type="string" name="kg_camera_widget_layout_package" />
<java-symbol type="string" name="kg_camera_widget_not_found" />
<java-symbol type="string" name="lockscreen_carrier_default" /> <java-symbol type="string" name="lockscreen_carrier_default" />
<java-symbol type="string" name="lockscreen_charged" /> <java-symbol type="string" name="lockscreen_charged" />
<java-symbol type="string" name="lockscreen_failed_attempts_almost_at_wipe" /> <java-symbol type="string" name="lockscreen_failed_attempts_almost_at_wipe" />

View File

@@ -16,34 +16,27 @@
package com.android.internal.policy.impl.keyguard; package com.android.internal.policy.impl.keyguard;
import java.util.List;
import android.app.ActivityManagerNative;
import android.content.ActivityNotFoundException;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo; import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color; import android.graphics.Color;
import android.os.Handler; import android.os.Handler;
import android.os.RemoteException;
import android.os.SystemClock; import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.MediaStore;
import android.util.Log; import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.WindowManager; import android.widget.FrameLayout;
import android.widget.TextView; import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import com.android.internal.policy.impl.keyguard.KeyguardActivityLauncher.CameraWidgetInfo;
import com.android.internal.R; import com.android.internal.R;
import com.android.internal.widget.LockPatternUtils;
public class CameraWidgetFrame extends KeyguardWidgetFrame { public class CameraWidgetFrame extends KeyguardWidgetFrame {
private static final String TAG = CameraWidgetFrame.class.getSimpleName(); private static final String TAG = CameraWidgetFrame.class.getSimpleName();
private static final boolean DEBUG = KeyguardHostView.DEBUG; private static final boolean DEBUG = KeyguardHostView.DEBUG;
private static final int WIDGET_ANIMATION_DURATION = 250;
interface Callbacks { interface Callbacks {
void onLaunchingCamera(); void onLaunchingCamera();
@@ -51,45 +44,65 @@ public class CameraWidgetFrame extends KeyguardWidgetFrame {
} }
private final Handler mHandler = new Handler(); private final Handler mHandler = new Handler();
private final LockPatternUtils mLockPatternUtils; private final KeyguardActivityLauncher mActivityLauncher;
private final Callbacks mCallbacks; private final Callbacks mCallbacks;
private boolean mCameraWidgetFound; private View mWidgetView;
private long mLaunchCameraStart; private long mLaunchCameraStart;
private final Runnable mLaunchCameraRunnable = new Runnable() { private final Runnable mLaunchCameraRunnable = new Runnable() {
@Override @Override
public void run() { public void run() {
launchCamera(); mActivityLauncher.launchCamera();
}}; }};
public CameraWidgetFrame(Context context, Callbacks callbacks) { private final Runnable mRenderRunnable = new Runnable() {
@Override
public void run() {
render();
}};
private CameraWidgetFrame(Context context, Callbacks callbacks,
KeyguardActivityLauncher activityLauncher) {
super(context); super(context);
mLockPatternUtils = new LockPatternUtils(context);
mCallbacks = callbacks; mCallbacks = callbacks;
mActivityLauncher = activityLauncher;
View cameraView = createCameraView();
addView(cameraView);
} }
private View createCameraView() { public static CameraWidgetFrame create(Context context, Callbacks callbacks,
View cameraView = null; KeyguardActivityLauncher launcher) {
if (context == null || callbacks == null || launcher == null)
return null;
CameraWidgetInfo widgetInfo = launcher.getCameraWidgetInfo();
if (widgetInfo == null)
return null;
View widgetView = widgetInfo.layoutId > 0 ?
inflateWidgetView(context, widgetInfo) :
inflateGenericWidgetView(context);
if (widgetView == null)
return null;
ImageView preview = new ImageView(context);
preview.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT));
preview.setScaleType(ScaleType.FIT_CENTER);
CameraWidgetFrame cameraWidgetFrame = new CameraWidgetFrame(context, callbacks, launcher);
cameraWidgetFrame.addView(preview);
cameraWidgetFrame.mWidgetView = widgetView;
return cameraWidgetFrame;
}
private static View inflateWidgetView(Context context, CameraWidgetInfo widgetInfo) {
View widgetView = null;
Exception exception = null; Exception exception = null;
try { try {
String contextPackage = mContext.getString(R.string.kg_camera_widget_context_package); Context cameraContext = context.createPackageContext(
String layoutPackage = mContext.getString(R.string.kg_camera_widget_layout_package); widgetInfo.contextPackage, Context.CONTEXT_RESTRICTED);
String layoutName = mContext.getString(R.string.kg_camera_widget_layout_name);
Context cameraContext = mContext.createPackageContext(
contextPackage, Context.CONTEXT_RESTRICTED);
LayoutInflater cameraInflater = (LayoutInflater) LayoutInflater cameraInflater = (LayoutInflater)
cameraContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); cameraContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
cameraInflater = cameraInflater.cloneInContext(cameraContext); cameraInflater = cameraInflater.cloneInContext(cameraContext);
widgetView = cameraInflater.inflate(widgetInfo.layoutId, null, false);
int layoutId = cameraContext.getResources()
.getIdentifier(layoutName, "layout", layoutPackage);
cameraView = cameraInflater.inflate(layoutId, null, false);
} catch (NameNotFoundException e) { } catch (NameNotFoundException e) {
exception = e; exception = e;
} catch (RuntimeException e) { } catch (RuntimeException e) {
@@ -98,27 +111,44 @@ public class CameraWidgetFrame extends KeyguardWidgetFrame {
if (exception != null) { if (exception != null) {
Log.w(TAG, "Error creating camera widget view", exception); Log.w(TAG, "Error creating camera widget view", exception);
} }
if (cameraView == null) { return widgetView;
cameraView = createCameraErrorView();
} else {
mCameraWidgetFound = true;
}
return cameraView;
} }
private View createCameraErrorView() { private static View inflateGenericWidgetView(Context context) {
TextView errorView = new TextView(mContext); ImageView iv = new ImageView(context);
errorView.setGravity(Gravity.CENTER); iv.setImageResource(com.android.internal.R.drawable.ic_lockscreen_camera);
errorView.setText(R.string.kg_camera_widget_not_found); iv.setScaleType(ScaleType.CENTER);
errorView.setBackgroundColor(Color.argb(127, 0, 0, 0)); iv.setBackgroundColor(Color.argb(127, 0, 0, 0));
return errorView; return iv;
}
public void render() {
int width = getRootView().getWidth();
int height = getRootView().getHeight();
if (DEBUG) Log.d(TAG, String.format("render [%sx%s]", width, height));
Bitmap offscreen = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(offscreen);
mWidgetView.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
mWidgetView.layout(0, 0, width, height);
mWidgetView.draw(c);
((ImageView)getChildAt(0)).setImageBitmap(offscreen);
} }
private void transitionToCamera() { private void transitionToCamera() {
int startWidth = getChildAt(0).getWidth();
int startHeight = getChildAt(0).getHeight();
int finishWidth = getRootView().getWidth();
int finishHeight = getRootView().getHeight();
float scaleX = (float) finishWidth / startWidth;
float scaleY = (float) finishHeight / startHeight;
float scale = Math.max(scaleX, scaleY);
animate() animate()
.scaleX(1.22f) // TODO compute this at runtime .scaleX(scale)
.scaleY(1.22f) .scaleY(scale)
.setDuration(250) .setDuration(WIDGET_ANIMATION_DURATION)
.withEndAction(mLaunchCameraRunnable) .withEndAction(mLaunchCameraRunnable)
.start(); .start();
mCallbacks.onLaunchingCamera(); mCallbacks.onLaunchingCamera();
@@ -127,7 +157,6 @@ public class CameraWidgetFrame extends KeyguardWidgetFrame {
@Override @Override
public void onWindowFocusChanged(boolean hasWindowFocus) { public void onWindowFocusChanged(boolean hasWindowFocus) {
super.onWindowFocusChanged(hasWindowFocus); super.onWindowFocusChanged(hasWindowFocus);
if (!mCameraWidgetFound) return;
if (!hasWindowFocus) { if (!hasWindowFocus) {
if (mLaunchCameraStart > 0) { if (mLaunchCameraStart > 0) {
@@ -141,8 +170,6 @@ public class CameraWidgetFrame extends KeyguardWidgetFrame {
@Override @Override
public void onActive(boolean isActive) { public void onActive(boolean isActive) {
if (!mCameraWidgetFound) return;
if (isActive) { if (isActive) {
mHandler.post(new Runnable(){ mHandler.post(new Runnable(){
@Override @Override
@@ -165,85 +192,9 @@ public class CameraWidgetFrame extends KeyguardWidgetFrame {
setScaleY(1); setScaleY(1);
} }
// =========== from KeyguardSelectorView =========== @Override
protected void launchCamera() { protected void onAttachedToWindow() {
mLaunchCameraStart = SystemClock.uptimeMillis(); super.onAttachedToWindow();
boolean isSecure = mLockPatternUtils.isSecure(); mHandler.post(mRenderRunnable);
if (DEBUG) Log.d(TAG, "launchCamera " + (isSecure?"(secure)":"(insecure)"));
if (isSecure) {
// Launch the secure version of the camera
final Intent intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE);
intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
if (wouldLaunchResolverActivity(intent)) {
// TODO: Show disambiguation dialog instead.
// For now, we'll treat this like launching any other app from secure keyguard.
// When they do, user sees the system's ResolverActivity which lets them choose
// which secure camera to use.
launchActivity(intent, false);
} else {
launchActivity(intent, true);
}
} else {
// Launch the normal camera
launchActivity(new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA), false);
}
} }
/**
* Launches the said intent for the current foreground user.
* @param intent
* @param showsWhileLocked true if the activity can be run on top of keyguard.
* See {@link WindowManager#FLAG_SHOW_WHEN_LOCKED}
*/
private void launchActivity(final Intent intent, boolean showsWhileLocked) {
intent.addFlags(
Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_SINGLE_TOP
| Intent.FLAG_ACTIVITY_CLEAR_TOP);
boolean isSecure = mLockPatternUtils.isSecure();
if (!isSecure || showsWhileLocked) {
if (!isSecure) try {
ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
} catch (RemoteException e) {
Log.w(TAG, "can't dismiss keyguard on launch");
}
try {
mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
} catch (ActivityNotFoundException e) {
Log.w(TAG, "Activity not found for intent + " + intent.getAction());
}
} else {
Log.w(TAG, "TODO: handle this case");
onCameraLaunched();
// // Create a runnable to start the activity and ask the user to enter their
// // credentials.
// mCallback.setOnDismissRunnable(new Runnable() {
// @Override
// public void run() {
// mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
// }
// });
// mCallback.dismiss(false);
}
}
private boolean wouldLaunchResolverActivity(Intent intent) {
PackageManager packageManager = mContext.getPackageManager();
ResolveInfo resolved = packageManager.resolveActivityAsUser(intent,
PackageManager.MATCH_DEFAULT_ONLY, mLockPatternUtils.getCurrentUser());
final List<ResolveInfo> appList = packageManager.queryIntentActivitiesAsUser(
intent, PackageManager.MATCH_DEFAULT_ONLY, mLockPatternUtils.getCurrentUser());
// If the list contains the above resolved activity, then it can't be
// 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;
}
} }

View File

@@ -0,0 +1,175 @@
/*
* Copyright (C) 2012 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.internal.policy.impl.keyguard;
import android.app.ActivityManagerNative;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.WindowManager;
import com.android.internal.widget.LockPatternUtils;
import java.util.List;
public abstract class KeyguardActivityLauncher {
private static final String TAG = KeyguardActivityLauncher.class.getSimpleName();
private static final boolean DEBUG = KeyguardHostView.DEBUG;
private static final String META_DATA_KEYGUARD_LAYOUT = "com.android.keyguard.layout";
private static final Intent SECURE_CAMERA_INTENT =
new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE)
.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
private static final Intent INSECURE_CAMERA_INTENT =
new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
abstract Context getContext();
abstract KeyguardSecurityCallback getCallback();
abstract LockPatternUtils getLockPatternUtils();
public static class CameraWidgetInfo {
public String contextPackage;
public int layoutId;
}
public CameraWidgetInfo getCameraWidgetInfo() {
CameraWidgetInfo info = new CameraWidgetInfo();
Intent intent = getCameraIntent();
PackageManager packageManager = getContext().getPackageManager();
final List<ResolveInfo> appList = packageManager.queryIntentActivitiesAsUser(
intent, PackageManager.MATCH_DEFAULT_ONLY, getLockPatternUtils().getCurrentUser());
if (appList.size() == 0) {
if (DEBUG) Log.d(TAG, "getCameraWidgetInfo(): Nothing found");
return null;
}
ResolveInfo resolved = packageManager.resolveActivityAsUser(intent,
PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_META_DATA,
getLockPatternUtils().getCurrentUser());
if (DEBUG) Log.d(TAG, "getCameraWidgetInfo(): resolved: " + resolved);
if (wouldLaunchResolverActivity(resolved, appList)) {
if (DEBUG) Log.d(TAG, "getCameraWidgetInfo(): Would launch resolver");
return info;
}
if (resolved == null || resolved.activityInfo == null) {
return null;
}
if (resolved.activityInfo.metaData == null || resolved.activityInfo.metaData.isEmpty()) {
if (DEBUG) Log.d(TAG, "getCameraWidgetInfo(): no metadata found");
return info;
}
int layoutId = resolved.activityInfo.metaData.getInt(META_DATA_KEYGUARD_LAYOUT);
if (layoutId == 0) {
if (DEBUG) Log.d(TAG, "getCameraWidgetInfo(): no layout specified");
return info;
}
info.contextPackage = resolved.activityInfo.packageName;
info.layoutId = layoutId;
return info;
}
public void launchCamera() {
LockPatternUtils lockPatternUtils = getLockPatternUtils();
if (lockPatternUtils.isSecure()) {
// Launch the secure version of the camera
if (wouldLaunchResolverActivity(SECURE_CAMERA_INTENT)) {
// TODO: Show disambiguation dialog instead.
// For now, we'll treat this like launching any other app from secure keyguard.
// When they do, user sees the system's ResolverActivity which lets them choose
// which secure camera to use.
launchActivity(SECURE_CAMERA_INTENT, false);
} else {
launchActivity(SECURE_CAMERA_INTENT, true);
}
} else {
// wouldLaunchResolverActivity(new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA));
// Launch the normal camera
launchActivity(INSECURE_CAMERA_INTENT, false);
}
}
/**
* Launches the said intent for the current foreground user.
* @param intent
* @param showsWhileLocked true if the activity can be run on top of keyguard.
* See {@link WindowManager#FLAG_SHOW_WHEN_LOCKED}
*/
public void launchActivity(final Intent intent, boolean showsWhileLocked) {
final Context context = getContext();
LockPatternUtils lockPatternUtils = getLockPatternUtils();
intent.addFlags(
Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_SINGLE_TOP
| Intent.FLAG_ACTIVITY_CLEAR_TOP);
boolean isSecure = lockPatternUtils.isSecure();
if (!isSecure || showsWhileLocked) {
if (!isSecure) try {
ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
} catch (RemoteException e) {
Log.w(TAG, "can't dismiss keyguard on launch");
}
try {
context.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
} catch (ActivityNotFoundException e) {
Log.w(TAG, "Activity not found for intent + " + intent.getAction());
}
} else {
// Create a runnable to start the activity and ask the user to enter their
// credentials.
KeyguardSecurityCallback callback = getCallback();
callback.setOnDismissRunnable(new Runnable() {
@Override
public void run() {
context.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
}
});
callback.dismiss(false);
}
}
private Intent getCameraIntent() {
return getLockPatternUtils().isSecure() ? SECURE_CAMERA_INTENT : INSECURE_CAMERA_INTENT;
}
private boolean wouldLaunchResolverActivity(Intent intent) {
PackageManager packageManager = getContext().getPackageManager();
ResolveInfo resolved = packageManager.resolveActivityAsUser(intent,
PackageManager.MATCH_DEFAULT_ONLY, getLockPatternUtils().getCurrentUser());
List<ResolveInfo> appList = packageManager.queryIntentActivitiesAsUser(
intent, PackageManager.MATCH_DEFAULT_ONLY, getLockPatternUtils().getCurrentUser());
return wouldLaunchResolverActivity(resolved, appList);
}
private boolean wouldLaunchResolverActivity(ResolveInfo resolved, List<ResolveInfo> appList) {
// If the list contains the above resolved activity, then it can't be
// 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;
}
}

View File

@@ -49,7 +49,6 @@ import android.view.WindowManager;
import android.view.animation.AnimationUtils; import android.view.animation.AnimationUtils;
import android.widget.RemoteViews.OnClickHandler; import android.widget.RemoteViews.OnClickHandler;
import android.widget.TextView; import android.widget.TextView;
import android.widget.ViewFlipper;
import com.android.internal.R; import com.android.internal.R;
import com.android.internal.policy.impl.keyguard.KeyguardSecurityModel.SecurityMode; import com.android.internal.policy.impl.keyguard.KeyguardSecurityModel.SecurityMode;
@@ -831,6 +830,46 @@ public class KeyguardHostView extends KeyguardViewBase {
} }
} }
private final CameraWidgetFrame.Callbacks mCameraWidgetCallbacks =
new CameraWidgetFrame.Callbacks() {
@Override
public void onLaunchingCamera() {
SlidingChallengeLayout slider = locateSlider();
if (slider != null) {
slider.showHandle(false);
}
}
@Override
public void onCameraLaunched() {
SlidingChallengeLayout slider = locateSlider();
if (slider != null) {
slider.showHandle(true);
}
mAppWidgetContainer.scrollLeft();
}
private SlidingChallengeLayout locateSlider() {
return (SlidingChallengeLayout) findViewById(R.id.sliding_layout);
}
};
private final KeyguardActivityLauncher mActivityLauncher = new KeyguardActivityLauncher() {
@Override
Context getContext() {
return mContext;
}
@Override
KeyguardSecurityCallback getCallback() {
return mCallback;
}
@Override
LockPatternUtils getLockPatternUtils() {
return mLockPatternUtils;
}};
private void addDefaultWidgets() { private void addDefaultWidgets() {
LayoutInflater inflater = LayoutInflater.from(mContext); LayoutInflater inflater = LayoutInflater.from(mContext);
inflater.inflate(R.layout.keyguard_transport_control_view, this, true); inflater.inflate(R.layout.keyguard_transport_control_view, this, true);
@@ -840,30 +879,11 @@ public class KeyguardHostView extends KeyguardViewBase {
View statusWidget = inflater.inflate(R.layout.keyguard_status_view, null, true); View statusWidget = inflater.inflate(R.layout.keyguard_status_view, null, true);
mAppWidgetContainer.addWidget(statusWidget); mAppWidgetContainer.addWidget(statusWidget);
if (mContext.getResources().getBoolean(R.bool.kg_enable_camera_default_widget)) { if (mContext.getResources().getBoolean(R.bool.kg_enable_camera_default_widget)) {
View cameraWidget = new CameraWidgetFrame(mContext, new CameraWidgetFrame.Callbacks() { View cameraWidget =
CameraWidgetFrame.create(mContext, mCameraWidgetCallbacks, mActivityLauncher);
private SlidingChallengeLayout locateSlider() { if (cameraWidget != null) {
return (SlidingChallengeLayout) findViewById(R.id.sliding_layout); mAppWidgetContainer.addWidget(cameraWidget);
} }
@Override
public void onLaunchingCamera() {
SlidingChallengeLayout slider = locateSlider();
if (slider != null) {
slider.showHandle(false);
}
}
@Override
public void onCameraLaunched() {
SlidingChallengeLayout slider = locateSlider();
if (slider != null) {
slider.showHandle(true);
}
mAppWidgetContainer.scrollLeft();
}
});
mAppWidgetContainer.addWidget(cameraWidget);
} }
View addWidgetButton = addWidget.findViewById(R.id.keyguard_add_widget_view); View addWidgetButton = addWidget.findViewById(R.id.keyguard_add_widget_view);

View File

@@ -16,18 +16,12 @@
package com.android.internal.policy.impl.keyguard; package com.android.internal.policy.impl.keyguard;
import android.animation.ObjectAnimator; import android.animation.ObjectAnimator;
import android.app.ActivityManagerNative;
import android.app.SearchManager; import android.app.SearchManager;
import android.app.admin.DevicePolicyManager; import android.app.admin.DevicePolicyManager;
import android.content.ActivityNotFoundException;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.RemoteException;
import android.os.UserHandle; import android.os.UserHandle;
import android.provider.MediaStore;
import android.provider.Settings; import android.provider.Settings;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.Log; import android.util.Log;
@@ -41,8 +35,6 @@ import com.android.internal.widget.multiwaveview.GlowPadView;
import com.android.internal.widget.multiwaveview.GlowPadView.OnTriggerListener; import com.android.internal.widget.multiwaveview.GlowPadView.OnTriggerListener;
import com.android.internal.R; import com.android.internal.R;
import java.util.List;
public class KeyguardSelectorView extends LinearLayout implements KeyguardSecurityView { public class KeyguardSelectorView extends LinearLayout implements KeyguardSecurityView {
private static final boolean DEBUG = KeyguardHostView.DEBUG; private static final boolean DEBUG = KeyguardHostView.DEBUG;
private static final String TAG = "SecuritySelectorView"; private static final String TAG = "SecuritySelectorView";
@@ -67,7 +59,7 @@ public class KeyguardSelectorView extends LinearLayout implements KeyguardSecuri
((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE)) ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
.getAssistIntent(mContext, UserHandle.USER_CURRENT); .getAssistIntent(mContext, UserHandle.USER_CURRENT);
if (assistIntent != null) { if (assistIntent != null) {
launchActivity(assistIntent, false); mActivityLauncher.launchActivity(assistIntent, false);
} else { } else {
Log.w(TAG, "Failed to get intent for assist activity"); Log.w(TAG, "Failed to get intent for assist activity");
} }
@@ -75,7 +67,7 @@ public class KeyguardSelectorView extends LinearLayout implements KeyguardSecuri
break; break;
case com.android.internal.R.drawable.ic_lockscreen_camera: case com.android.internal.R.drawable.ic_lockscreen_camera:
launchCamera(); mActivityLauncher.launchCamera();
mCallback.userActivity(0); mCallback.userActivity(0);
break; break;
@@ -119,49 +111,27 @@ public class KeyguardSelectorView extends LinearLayout implements KeyguardSecuri
} }
}; };
private final KeyguardActivityLauncher mActivityLauncher = new KeyguardActivityLauncher() {
@Override
KeyguardSecurityCallback getCallback() {
return mCallback;
}
@Override
LockPatternUtils getLockPatternUtils() {
return mLockPatternUtils;
}
@Override
Context getContext() {
return mContext;
}};
public KeyguardSelectorView(Context context) { public KeyguardSelectorView(Context context) {
this(context, null); this(context, null);
} }
private boolean wouldLaunchResolverActivity(Intent intent) {
PackageManager packageManager = mContext.getPackageManager();
ResolveInfo resolved = packageManager.resolveActivityAsUser(intent,
PackageManager.MATCH_DEFAULT_ONLY, mLockPatternUtils.getCurrentUser());
final List<ResolveInfo> appList = packageManager.queryIntentActivitiesAsUser(
intent, PackageManager.MATCH_DEFAULT_ONLY, mLockPatternUtils.getCurrentUser());
// If the list contains the above resolved activity, then it can't be
// 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;
}
protected void launchCamera() {
if (mLockPatternUtils.isSecure()) {
// Launch the secure version of the camera
final Intent intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE);
intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
if (wouldLaunchResolverActivity(intent)) {
// TODO: Show disambiguation dialog instead.
// For now, we'll treat this like launching any other app from secure keyguard.
// When they do, user sees the system's ResolverActivity which lets them choose
// which secure camera to use.
launchActivity(intent, false);
} else {
launchActivity(intent, true);
}
} else {
// Launch the normal camera
launchActivity(new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA), false);
}
}
public KeyguardSelectorView(Context context, AttributeSet attrs) { public KeyguardSelectorView(Context context, AttributeSet attrs) {
super(context, attrs); super(context, attrs);
mLockPatternUtils = new LockPatternUtils(getContext()); mLockPatternUtils = new LockPatternUtils(getContext());
@@ -267,42 +237,6 @@ public class KeyguardSelectorView extends LinearLayout implements KeyguardSecuri
mLockPatternUtils = utils; mLockPatternUtils = utils;
} }
/**
* Launches the said intent for the current foreground user.
* @param intent
* @param showsWhileLocked true if the activity can be run on top of keyguard.
* See {@link WindowManager#FLAG_SHOW_WHEN_LOCKED}
*/
private void launchActivity(final Intent intent, boolean showsWhileLocked) {
intent.addFlags(
Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_SINGLE_TOP
| Intent.FLAG_ACTIVITY_CLEAR_TOP);
boolean isSecure = mLockPatternUtils.isSecure();
if (!isSecure || showsWhileLocked) {
if (!isSecure) try {
ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
} catch (RemoteException e) {
Log.w(TAG, "can't dismiss keyguard on launch");
}
try {
mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
} catch (ActivityNotFoundException e) {
Log.w(TAG, "Activity not found for intent + " + intent.getAction());
}
} else {
// Create a runnable to start the activity and ask the user to enter their
// credentials.
mCallback.setOnDismissRunnable(new Runnable() {
@Override
public void run() {
mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
}
});
mCallback.dismiss(false);
}
}
@Override @Override
public void reset() { public void reset() {
mGlowPadView.reset(false); mGlowPadView.reset(false);

View File

@@ -1,31 +0,0 @@
/*
* Copyright (C) 2012 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.internal.policy.impl.keyguard;
import android.app.Activity;
import android.os.Bundle;
import android.widget.FrameLayout;
public class SecureCamera extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new FrameLayout(this));
}
}