am 5fff5f01: Merge "Make partially visible widget pages not important for accessibility." into jb-mr1-dev
* commit '5fff5f01f8af05164d5d7be72bdadee46360ba92':
Make partially visible widget pages not important for accessibility.
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index f482335..b94f0b9 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3229,6 +3229,13 @@
"lock_screen_appwidget_ids";
/**
+ * Id of the appwidget shown on the lock screen when appwidgets are disabled.
+ * @hide
+ */
+ public static final String LOCK_SCREEN_FALLBACK_APPWIDGET_ID =
+ "lock_screen_fallback_appwidget_id";
+
+ /**
* Index of the lockscreen appwidget to restore, -1 if none.
* @hide
*/
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 5f598b1..fdaf39e 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -254,4 +254,9 @@
* Gets the infos for all visible windows.
*/
void getVisibleWindowsForDisplay(int displayId, out List<WindowInfo> outInfos);
+
+ /**
+ * Device is in safe mode.
+ */
+ boolean isSafeModeEnabled();
}
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 8d83774..8d1be53 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -351,12 +351,12 @@
public void onClick(View v) {
// Insure that this view is a child of an AdapterView
View parent = (View) v.getParent();
- while (!(parent instanceof AdapterView<?>)
+ while (parent != null && !(parent instanceof AdapterView<?>)
&& !(parent instanceof AppWidgetHostView)) {
parent = (View) parent.getParent();
}
- if (parent instanceof AppWidgetHostView) {
+ if (parent instanceof AppWidgetHostView || parent == null) {
// Somehow they've managed to get this far without having
// and AdapterView as a parent.
Log.e("RemoteViews", "Collection item doesn't have AdapterView parent");
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index e5e1a2b..47d501cd 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -18,6 +18,7 @@
import android.app.ActivityManagerNative;
import android.app.admin.DevicePolicyManager;
+import android.appwidget.AppWidgetManager;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
@@ -35,6 +36,7 @@
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
+import android.view.IWindowManager;
import android.view.View;
import android.widget.Button;
@@ -1112,6 +1114,25 @@
return sb.toString();
}
+ // appwidget used when appwidgets are disabled (we make an exception for
+ // default clock widget)
+ public void writeFallbackAppWidgetId(int appWidgetId) {
+ Settings.Secure.putIntForUser(mContentResolver,
+ Settings.Secure.LOCK_SCREEN_FALLBACK_APPWIDGET_ID,
+ appWidgetId,
+ UserHandle.USER_CURRENT);
+ }
+
+ // appwidget used when appwidgets are disabled (we make an exception for
+ // default clock widget)
+ public int getFallbackAppWidgetId() {
+ return Settings.Secure.getIntForUser(
+ mContentResolver,
+ Settings.Secure.LOCK_SCREEN_FALLBACK_APPWIDGET_ID,
+ AppWidgetManager.INVALID_APPWIDGET_ID,
+ UserHandle.USER_CURRENT);
+ }
+
private void writeAppWidgets(int[] appWidgetIds) {
Settings.Secure.putStringForUser(mContentResolver,
Settings.Secure.LOCK_SCREEN_APPWIDGET_IDS,
@@ -1325,5 +1346,15 @@
public boolean getPowerButtonInstantlyLocks() {
return getBoolean(LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS, true);
}
+
+ public static boolean isSafeModeEnabled() {
+ try {
+ return IWindowManager.Stub.asInterface(
+ ServiceManager.getService("window")).isSafeModeEnabled();
+ } catch (RemoteException e) {
+ // Shouldn't happen!
+ }
+ return false;
+ }
}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java
index 8ca6d2a..6250e54 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java
@@ -90,6 +90,7 @@
if (mBiometricUnlock != null) {
mBiometricUnlock.stop();
}
+ KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mUpdateCallback);
}
@Override
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
index b586d94..68783c3 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
@@ -37,6 +37,8 @@
import android.os.Parcel;
import android.os.Parcelable;
import android.os.SystemClock;
+import android.os.SystemProperties;
+import android.os.UserHandle;
import android.os.UserManager;
import android.util.AttributeSet;
import android.util.Log;
@@ -57,7 +59,7 @@
import java.util.List;
public class KeyguardHostView extends KeyguardViewBase {
- private static final String TAG = "KeyguardViewHost";
+ private static final String TAG = "KeyguardHostView";
// Use this to debug all of keyguard
public static boolean DEBUG = KeyguardViewMediator.DEBUG;
@@ -82,8 +84,17 @@
private KeyguardSecurityModel mSecurityModel;
private KeyguardViewStateManager mViewStateManager;
+ int mLocalStickyWidget = -1;
+ boolean mPersitentStickyWidgetLoaded = false;
+
private Rect mTempRect = new Rect();
+ private int mDisabledFeatures;
+
+ private boolean mCameraDisabled;
+
+ private boolean mSafeModeEnabled;
+
/*package*/ interface TransportCallback {
void onListenerDetached();
void onListenerAttached();
@@ -109,7 +120,26 @@
mAppWidgetManager = AppWidgetManager.getInstance(mContext);
mSecurityModel = new KeyguardSecurityModel(context);
- mViewStateManager = new KeyguardViewStateManager();
+ mViewStateManager = new KeyguardViewStateManager(this);
+
+ DevicePolicyManager dpm =
+ (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+ if (dpm != null) {
+ mDisabledFeatures = getDisabledFeatures(dpm);
+ mCameraDisabled = dpm.getCameraDisabled(null);
+ }
+
+ mSafeModeEnabled = LockPatternUtils.isSafeModeEnabled();
+
+ if (mSafeModeEnabled) {
+ Log.v(TAG, "Keyguard widgets disabled by safe mode");
+ }
+ if ((mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL) != 0) {
+ Log.v(TAG, "Keyguard widgets disabled by DPM");
+ }
+ if ((mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0) {
+ Log.v(TAG, "Keyguard secure camera disabled by DPM");
+ }
}
@Override
@@ -174,9 +204,10 @@
}
addDefaultWidgets();
- addWidgetsFromSettings();
- mSwitchPageRunnable.run();
+ addWidgetsFromSettings();
+ checkAppWidgetConsistency();
+ mSwitchPageRunnable.run();
// This needs to be called after the pages are all added.
mViewStateManager.showUsabilityHints();
@@ -184,6 +215,24 @@
updateSecurityViews();
}
+ private int getDisabledFeatures(DevicePolicyManager dpm) {
+ int disabledFeatures = DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE;
+ if (dpm != null) {
+ final int currentUser = mLockPatternUtils.getCurrentUser();
+ disabledFeatures = dpm.getKeyguardDisabledFeatures(null, currentUser);
+ }
+ return disabledFeatures;
+ }
+
+ private boolean widgetsDisabledByDpm() {
+ return (mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL) != 0;
+ }
+
+ private boolean cameraDisabledByDpm() {
+ return mCameraDisabled
+ || (mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0;
+ }
+
private void updateSecurityViews() {
int children = mSecurityViewContainer.getChildCount();
for (int i = 0; i < children; i++) {
@@ -818,15 +867,18 @@
}
}
- private boolean addWidget(int appId, int pageIndex) {
+ private boolean addWidget(int appId, int pageIndex, boolean updateDbIfFailed) {
AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appId);
if (appWidgetInfo != null) {
AppWidgetHostView view = getAppWidgetHost().createView(mContext, appId, appWidgetInfo);
addWidget(view, pageIndex);
return true;
} else {
- Log.w(TAG, "AppWidgetInfo for app widget id " + appId + " was null, deleting");
- mLockPatternUtils.removeAppWidget(appId);
+ if (updateDbIfFailed) {
+ Log.w(TAG, "AppWidgetInfo for app widget id " + appId + " was null, deleting");
+ mAppWidgetHost.deleteAppWidgetId(appId);
+ mLockPatternUtils.removeAppWidget(appId);
+ }
return false;
}
}
@@ -840,7 +892,7 @@
@Override
public void onCameraLaunchedSuccessfully() {
- if (isCameraPage(mAppWidgetContainer.getCurrentPage())) {
+ if (mAppWidgetContainer.isCameraPage(mAppWidgetContainer.getCurrentPage())) {
mAppWidgetContainer.scrollLeft();
}
setSliderHandleAlpha(1);
@@ -882,9 +934,28 @@
LayoutInflater inflater = LayoutInflater.from(mContext);
inflater.inflate(R.layout.keyguard_transport_control_view, this, true);
- View addWidget = inflater.inflate(R.layout.keyguard_add_widget, null, true);
- mAppWidgetContainer.addWidget(addWidget);
- if (mContext.getResources().getBoolean(R.bool.kg_enable_camera_default_widget)) {
+ if (!mSafeModeEnabled && !widgetsDisabledByDpm()) {
+ View addWidget = inflater.inflate(R.layout.keyguard_add_widget, this, false);
+ mAppWidgetContainer.addWidget(addWidget);
+ View addWidgetButton = addWidget.findViewById(R.id.keyguard_add_widget_view);
+ addWidgetButton.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ int appWidgetId = mAppWidgetHost.allocateAppWidgetId();
+ if (appWidgetId != -1) {
+ mActivityLauncher.launchWidgetPicker(appWidgetId);
+ } else {
+ Log.e(TAG, "Unable to allocate an AppWidget id in lock screen");
+ }
+ }
+ });
+ }
+
+ // We currently disable cameras in safe mode because we support loading 3rd party
+ // cameras we can't trust. TODO: plumb safe mode into camera creation code and only
+ // inflate system-provided camera?
+ if (!mSafeModeEnabled && !cameraDisabledByDpm()
+ && mContext.getResources().getBoolean(R.bool.kg_enable_camera_default_widget)) {
View cameraWidget =
CameraWidgetFrame.create(mContext, mCameraWidgetCallbacks, mActivityLauncher);
if (cameraWidget != null) {
@@ -892,19 +963,6 @@
}
}
- View addWidgetButton = addWidget.findViewById(R.id.keyguard_add_widget_view);
- addWidgetButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- int appWidgetId = mAppWidgetHost.allocateAppWidgetId();
- if (appWidgetId != -1) {
- mActivityLauncher.launchWidgetPicker(appWidgetId);
- } else {
- Log.e(TAG, "Unable to allocate an AppWidget id in lock screen");
- }
- }
- });
-
enableUserSelectorIfNecessary();
initializeTransportControl();
}
@@ -929,7 +987,8 @@
int lastWidget = mAppWidgetContainer.getChildCount() - 1;
int position = 0; // handle no widget case
if (lastWidget >= 0) {
- position = isCameraPage(lastWidget) ? lastWidget : lastWidget + 1;
+ position = mAppWidgetContainer.isCameraPage(lastWidget) ?
+ lastWidget : lastWidget + 1;
}
mAppWidgetContainer.addWidget(mTransportControl, position);
mTransportControl.setVisibility(View.VISIBLE);
@@ -965,14 +1024,15 @@
}
}
- private int getAddPageIndex() {
+ private int getInsertPageIndex() {
View addWidget = mAppWidgetContainer.findViewById(R.id.keyguard_add_widget);
- int addPageIndex = mAppWidgetContainer.indexOfChild(addWidget);
- // This shouldn't happen, but just to be safe!
- if (addPageIndex < 0) {
- addPageIndex = 0;
+ int insertionIndex = mAppWidgetContainer.indexOfChild(addWidget);
+ if (insertionIndex < 0) {
+ insertionIndex = 0; // no add widget page found
+ } else {
+ insertionIndex++; // place after add widget
}
- return addPageIndex;
+ return insertionIndex;
}
private void addDefaultStatusWidget(int index) {
@@ -982,18 +1042,11 @@
}
private void addWidgetsFromSettings() {
- DevicePolicyManager dpm =
- (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
- if (dpm != null) {
- final int currentUser = mLockPatternUtils.getCurrentUser();
- final int disabledFeatures = dpm.getKeyguardDisabledFeatures(null, currentUser);
- if ((disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL) != 0) {
- Log.v(TAG, "Keyguard widgets disabled because of device policy admin");
- return;
- }
+ if (mSafeModeEnabled || widgetsDisabledByDpm()) {
+ return;
}
- int addPageIndex = getAddPageIndex();
+ int insertionIndex = getInsertPageIndex();
// Add user-selected widget
final int[] widgets = mLockPatternUtils.getAppWidgets();
@@ -1003,50 +1056,90 @@
} else {
for (int i = widgets.length -1; i >= 0; i--) {
if (widgets[i] == LockPatternUtils.ID_DEFAULT_STATUS_WIDGET) {
- addDefaultStatusWidget(addPageIndex + 1);
+ addDefaultStatusWidget(insertionIndex);
} else {
// We add the widgets from left to right, starting after the first page after
// the add page. We count down, since the order will be persisted from right
// to left, starting after camera.
- addWidget(widgets[i], addPageIndex + 1);
+ addWidget(widgets[i], insertionIndex, true);
}
}
}
- checkAppWidgetConsistency();
+ }
+
+ private int allocateIdForDefaultAppWidget() {
+ int appWidgetId;
+ Resources res = getContext().getResources();
+ ComponentName defaultAppWidget = new ComponentName(
+ res.getString(R.string.widget_default_package_name),
+ res.getString(R.string.widget_default_class_name));
+
+ // Note: we don't support configuring the widget
+ appWidgetId = mAppWidgetHost.allocateAppWidgetId();
+
+ try {
+ mAppWidgetManager.bindAppWidgetId(appWidgetId, defaultAppWidget);
+
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "Error when trying to bind default AppWidget: " + e);
+ mAppWidgetHost.deleteAppWidgetId(appWidgetId);
+ appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
+ }
+ return appWidgetId;
}
public void checkAppWidgetConsistency() {
final int childCount = mAppWidgetContainer.getChildCount();
boolean widgetPageExists = false;
for (int i = 0; i < childCount; i++) {
- if (isWidgetPage(i)) {
+ if (mAppWidgetContainer.isWidgetPage(i)) {
widgetPageExists = true;
break;
}
}
if (!widgetPageExists) {
- final int addPageIndex = getAddPageIndex();
+ final int insertPageIndex = getInsertPageIndex();
- Resources res = getContext().getResources();
- ComponentName defaultAppWidget = new ComponentName(
- res.getString(R.string.widget_default_package_name),
- res.getString(R.string.widget_default_class_name));
+ final boolean userAddedWidgetsEnabled = !widgetsDisabledByDpm();
+ boolean addedDefaultAppWidget = false;
- // Note: we don't support configuring the widget
- int appWidgetId = mAppWidgetHost.allocateAppWidgetId();
- boolean bindSuccessful = false;
- try {
- mAppWidgetManager.bindAppWidgetId(appWidgetId, defaultAppWidget);
- bindSuccessful = true;
- } catch (IllegalArgumentException e) {
- Log.e(TAG, "Error when trying to bind default AppWidget: " + e);
+ if (!mSafeModeEnabled) {
+ if (userAddedWidgetsEnabled) {
+ int appWidgetId = allocateIdForDefaultAppWidget();
+ if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
+ addedDefaultAppWidget = addWidget(appWidgetId, insertPageIndex, true);
+ }
+ } else {
+ // note: even if widgetsDisabledByDpm() returns true, we still bind/create
+ // the default appwidget if possible
+ int appWidgetId = mLockPatternUtils.getFallbackAppWidgetId();
+ if (appWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
+ appWidgetId = allocateIdForDefaultAppWidget();
+ if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
+ mLockPatternUtils.writeFallbackAppWidgetId(appWidgetId);
+ }
+ }
+ if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
+ addedDefaultAppWidget = addWidget(appWidgetId, insertPageIndex, false);
+ if (!addedDefaultAppWidget) {
+ mAppWidgetHost.deleteAppWidgetId(appWidgetId);
+ mLockPatternUtils.writeFallbackAppWidgetId(
+ AppWidgetManager.INVALID_APPWIDGET_ID);
+ }
+ }
+ }
}
+
// Use the built-in status/clock view if we can't inflate the default widget
- if (!(bindSuccessful && addWidget(appWidgetId, addPageIndex + 1))) {
- addDefaultStatusWidget(addPageIndex + 1);
+ if (!addedDefaultAppWidget) {
+ addDefaultStatusWidget(insertPageIndex);
}
- mAppWidgetContainer.onAddView(
- mAppWidgetContainer.getChildAt(addPageIndex + 1), addPageIndex + 1);
+
+ // trigger DB updates only if user-added widgets are enabled
+ if (!mSafeModeEnabled && userAddedWidgetsEnabled) {
+ mAppWidgetContainer.onAddView(
+ mAppWidgetContainer.getChildAt(insertPageIndex), insertPageIndex);
+ }
}
}
@@ -1143,30 +1236,42 @@
private CameraWidgetFrame findCameraPage() {
for (int i = mAppWidgetContainer.getChildCount() - 1; i >= 0; i--) {
- if (isCameraPage(i)) {
+ if (mAppWidgetContainer.isCameraPage(i)) {
return (CameraWidgetFrame) mAppWidgetContainer.getChildAt(i);
}
}
return null;
}
- private boolean isWidgetPage(int pageIndex) {
- View v = mAppWidgetContainer.getChildAt(pageIndex);
- if (v != null && v instanceof KeyguardWidgetFrame) {
- KeyguardWidgetFrame kwf = (KeyguardWidgetFrame) v;
- return kwf.getContentAppWidgetId() != AppWidgetManager.INVALID_APPWIDGET_ID;
+ private int getStickyWidget() {
+ // The first time we query the persistent state. From that point, we use a locally updated
+ // notion of the sticky widget page.
+ if (!mPersitentStickyWidgetLoaded) {
+ mLocalStickyWidget = mLockPatternUtils.getStickyAppWidgetIndex();
+ mPersitentStickyWidgetLoaded = true;
}
- return false;
+ return mLocalStickyWidget;
}
- private boolean isCameraPage(int pageIndex) {
- View v = mAppWidgetContainer.getChildAt(pageIndex);
- return v != null && v instanceof CameraWidgetFrame;
+ public void updateStickyWidget(int index) {
+ if (index < 0 || index >= mAppWidgetContainer.getChildCount()) {
+ return;
+ }
+ if (mAppWidgetContainer.isAddPage(index)) {
+ return;
+ }
+ if (mAppWidgetContainer.isCameraPage(index)) {
+ return;
+ }
+ if (isMusicPage(index)) {
+ return;
+ }
+
+ mLocalStickyWidget = index;
}
- private boolean isAddPage(int pageIndex) {
- View v = mAppWidgetContainer.getChildAt(pageIndex);
- return v != null && v.getId() == R.id.keyguard_add_widget;
+ boolean isMusicPage(int pageIndex) {
+ return pageIndex >= 0 && pageIndex == getWidgetPosition(R.id.keyguard_transport_control);
}
private int getAppropriateWidgetPage(boolean isMusicPlaying) {
@@ -1179,18 +1284,18 @@
}
// if we have a valid sticky widget, show it
- int stickyWidgetIndex = mLockPatternUtils.getStickyAppWidgetIndex();
+ int stickyWidgetIndex = getStickyWidget();
if (stickyWidgetIndex > -1
&& stickyWidgetIndex < mAppWidgetContainer.getChildCount()
- && !isAddPage(stickyWidgetIndex)
- && !isCameraPage(stickyWidgetIndex)) {
+ && !mAppWidgetContainer.isAddPage(stickyWidgetIndex)
+ && !mAppWidgetContainer.isCameraPage(stickyWidgetIndex)) {
if (DEBUG) Log.d(TAG, "Valid sticky widget found, show page " + stickyWidgetIndex);
return stickyWidgetIndex;
}
// else show the right-most widget (except for camera)
int rightMost = mAppWidgetContainer.getChildCount() - 1;
- if (isCameraPage(rightMost)) {
+ if (mAppWidgetContainer.isCameraPage(rightMost)) {
rightMost--;
}
if (DEBUG) Log.d(TAG, "Show right-most page " + rightMost);
@@ -1198,18 +1303,10 @@
}
private void saveStickyWidgetIndex() {
- int stickyWidgetIndex = mAppWidgetContainer.getCurrentPage();
- if (isAddPage(stickyWidgetIndex)) {
- stickyWidgetIndex++;
+ if (DEBUG) Log.d(TAG, "saveStickyWidgetIndex: " + mLocalStickyWidget);
+ if (mPersitentStickyWidgetLoaded && mLocalStickyWidget >= 0) {
+ mLockPatternUtils.setStickyAppWidgetIndex(mLocalStickyWidget);
}
- if (isCameraPage(stickyWidgetIndex)) {
- stickyWidgetIndex--;
- }
- if (stickyWidgetIndex < 0 || stickyWidgetIndex >= mAppWidgetContainer.getChildCount()) {
- stickyWidgetIndex = -1;
- }
- if (DEBUG) Log.d(TAG, "saveStickyWidgetIndex: " + stickyWidgetIndex);
- mLockPatternUtils.setStickyAppWidgetIndex(stickyWidgetIndex);
}
private void enableUserSelectorIfNecessary() {
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityViewFlipper.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityViewFlipper.java
index 3d4cb19..c92c791 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityViewFlipper.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityViewFlipper.java
@@ -128,22 +128,24 @@
@Override
public void showBouncer(int duration) {
+ KeyguardSecurityView active = getSecurityView();
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
if (child instanceof KeyguardSecurityView) {
KeyguardSecurityView ksv = (KeyguardSecurityView) child;
- ksv.showBouncer(child.getVisibility() == View.VISIBLE ? duration : 0);
+ ksv.showBouncer(ksv == active ? duration : 0);
}
}
}
@Override
public void hideBouncer(int duration) {
+ KeyguardSecurityView active = getSecurityView();
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
if (child instanceof KeyguardSecurityView) {
KeyguardSecurityView ksv = (KeyguardSecurityView) child;
- ksv.hideBouncer(child.getVisibility() == View.VISIBLE ? duration : 0);
+ ksv.hideBouncer(ksv == active ? duration : 0);
}
}
}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityViewHelper.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityViewHelper.java
index 2ccdc1d..294bc3d 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityViewHelper.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityViewHelper.java
@@ -42,7 +42,7 @@
}
if (bouncerFrame != null) {
if (duration > 0) {
- Animator anim = ObjectAnimator.ofInt(bouncerFrame, "alpha", 255);
+ Animator anim = ObjectAnimator.ofInt(bouncerFrame, "alpha", 0, 255);
anim.setDuration(duration);
anim.start();
} else {
@@ -67,7 +67,7 @@
}
if (bouncerFrame != null) {
if (duration > 0) {
- Animator anim = ObjectAnimator.ofInt(bouncerFrame, "alpha", 0);
+ Animator anim = ObjectAnimator.ofInt(bouncerFrame, "alpha", 255, 0);
anim.setDuration(duration);
anim.start();
} else {
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewBase.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewBase.java
index 9e3424d..6fcacd3 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewBase.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewBase.java
@@ -260,4 +260,5 @@
KeyguardViewMediator.ViewMediatorCallback viewMediatorCallback) {
mViewMediatorCallback = viewMediatorCallback;
}
+
}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java
index e53358b..922ced2 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java
@@ -25,6 +25,7 @@
private KeyguardWidgetPager mKeyguardWidgetPager;
private ChallengeLayout mChallengeLayout;
+ private KeyguardHostView mKeyguardHostView;
private int[] mTmpPoint = new int[2];
private int[] mTmpLoc = new int[2];
@@ -49,7 +50,8 @@
int mChallengeTop = 0;
- public KeyguardViewStateManager() {
+ public KeyguardViewStateManager(KeyguardHostView hostView) {
+ mKeyguardHostView = hostView;
}
public void setPagedView(KeyguardWidgetPager pagedView) {
@@ -145,6 +147,10 @@
// We only modify the page state if it is not currently under control by the slider.
// This prevents conflicts.
+ if (mKeyguardHostView != null) {
+ mKeyguardHostView.updateStickyWidget(newPageIndex);
+ }
+
// If the page hasn't switched, don't bother with any of this
if (mCurrentPage == newPageIndex) return;
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java
index 9f0c5bd..f20b8d4 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java
@@ -22,9 +22,9 @@
import android.animation.PropertyValuesHolder;
import android.animation.TimeInterpolator;
import android.appwidget.AppWidgetHostView;
+import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProviderInfo;
import android.content.Context;
-import android.content.res.Resources;
import android.os.Handler;
import android.os.HandlerThread;
import android.util.AttributeSet;
@@ -38,7 +38,6 @@
import android.view.accessibility.AccessibilityManager;
import android.widget.FrameLayout;
-import com.android.internal.R;
import com.android.internal.widget.LockPatternUtils;
import java.util.ArrayList;
@@ -69,8 +68,6 @@
private int mPage = 0;
private Callbacks mCallbacks;
- private boolean mCameraWidgetEnabled;
-
private int mWidgetToResetAfterFadeOut;
// Bouncer
@@ -97,10 +94,6 @@
setPageSwitchListener(this);
- Resources r = getResources();
- mCameraWidgetEnabled = r.getBoolean(R.bool.kg_enable_camera_default_widget);
- mCenterSmallWidgetsVertically =
- r.getBoolean(com.android.internal.R.bool.kg_center_small_widgets_vertically);
mBackgroundWorkerThread = new HandlerThread("KeyguardWidgetPager Worker");
mBackgroundWorkerThread.start();
mBackgroundWorkerHandler = new Handler(mBackgroundWorkerThread.getLooper());
@@ -502,35 +495,31 @@
}
}
+ public boolean isWidgetPage(int pageIndex) {
+ if (pageIndex < 0 || pageIndex >= getChildCount()) {
+ return false;
+ }
+ View v = getChildAt(pageIndex);
+ if (v != null && v instanceof KeyguardWidgetFrame) {
+ KeyguardWidgetFrame kwf = (KeyguardWidgetFrame) v;
+ return kwf.getContentAppWidgetId() != AppWidgetManager.INVALID_APPWIDGET_ID;
+ }
+ return false;
+ }
+
@Override
void boundByReorderablePages(boolean isReordering, int[] range) {
if (isReordering) {
- if (isAddWidgetPageVisible()) {
+ // Remove non-widget pages from the range
+ while (range[1] > range[0] && !isWidgetPage(range[1])) {
+ range[1]--;
+ }
+ while (range[0] < range[1] && !isWidgetPage(range[0])) {
range[0]++;
}
- if (isMusicWidgetVisible()) {
- range[1]--;
- }
- if (isCameraWidgetVisible()) {
- range[1]--;
- }
}
}
- /*
- * Special widgets
- */
- boolean isAddWidgetPageVisible() {
- // TODO: Make proper test once we decide whether the add-page is always showing
- return true;
- }
- boolean isMusicWidgetVisible() {
- return mViewStateManager.getTransportState() != KeyguardViewStateManager.TRANSPORT_GONE;
- }
- boolean isCameraWidgetVisible() {
- return mCameraWidgetEnabled;
- }
-
protected void reorderStarting() {
showOutlinesAndSidePages();
}
@@ -782,4 +771,19 @@
mZoomInOutAnim.start();
}
}
+
+ boolean isAddPage(int pageIndex) {
+ View v = getChildAt(pageIndex);
+ return v != null && v.getId() == com.android.internal.R.id.keyguard_add_widget;
+ }
+
+ boolean isCameraPage(int pageIndex) {
+ View v = getChildAt(pageIndex);
+ return v != null && v instanceof CameraWidgetFrame;
+ }
+
+ @Override
+ protected boolean shouldSetTopAlignedPivotForWidget(int childIndex) {
+ return !isCameraPage(childIndex) && super.shouldSetTopAlignedPivotForWidget(childIndex);
+ }
}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/MultiPaneChallengeLayout.java b/policy/src/com/android/internal/policy/impl/keyguard/MultiPaneChallengeLayout.java
index 3bc39eb..97e7f95 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/MultiPaneChallengeLayout.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/MultiPaneChallengeLayout.java
@@ -16,21 +16,22 @@
package com.android.internal.policy.impl.keyguard;
+import com.android.internal.R;
+
import android.animation.Animator;
-import android.animation.AnimatorSet;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.content.Context;
+import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Rect;
import android.util.AttributeSet;
+import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
-import com.android.internal.R;
-
public class MultiPaneChallengeLayout extends ViewGroup implements ChallengeLayout {
private static final String TAG = "MultiPaneChallengeLayout";
@@ -47,7 +48,8 @@
private OnBouncerStateChangedListener mBouncerListener;
private final Rect mTempRect = new Rect();
- private final Context mContext;
+
+ private final DisplayMetrics mDisplayMetrics;
private final OnClickListener mScrimClickListener = new OnClickListener() {
@Override
@@ -67,13 +69,14 @@
public MultiPaneChallengeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
- mContext = context;
-
final TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.MultiPaneChallengeLayout, defStyleAttr, 0);
mOrientation = a.getInt(R.styleable.MultiPaneChallengeLayout_orientation,
HORIZONTAL);
a.recycle();
+
+ final Resources res = getResources();
+ mDisplayMetrics = res.getDisplayMetrics();
}
@Override
@@ -169,15 +172,32 @@
mScrimView.setOnClickListener(mScrimClickListener);
}
+ private int getVirtualHeight(LayoutParams lp, int height, int heightUsed) {
+ int virtualHeight = height;
+ final View root = getRootView();
+ if (root != null) {
+ // This calculation is super dodgy and relies on several assumptions.
+ // Specifically that the root of the window will be padded in for insets
+ // and that the window is LAYOUT_IN_SCREEN.
+ virtualHeight = mDisplayMetrics.heightPixels - root.getPaddingTop();
+ }
+ if (lp.childType == LayoutParams.CHILD_TYPE_WIDGET ||
+ lp.childType == LayoutParams.CHILD_TYPE_USER_SWITCHER) {
+ // Always measure the widget pager/user switcher as if there were no IME insets
+ // on the window. We want to avoid resizing widgets when possible as it can
+ // be ugly/expensive. This lets us simply clip them instead.
+ return virtualHeight - heightUsed;
+ }
+ return Math.min(virtualHeight - heightUsed, height);
+ }
+
@Override
- protected void onMeasure(int widthSpec, int heightSpec) {
+ protected void onMeasure(final int widthSpec, final int heightSpec) {
if (MeasureSpec.getMode(widthSpec) != MeasureSpec.EXACTLY ||
MeasureSpec.getMode(heightSpec) != MeasureSpec.EXACTLY) {
throw new IllegalArgumentException(
"MultiPaneChallengeLayout must be measured with an exact size");
}
- float squashedLayoutThreshold =
- mContext.getResources().getDimension(R.dimen.kg_squashed_layout_threshold);
final int width = MeasureSpec.getSize(widthSpec);
final int height = MeasureSpec.getSize(heightSpec);
@@ -213,32 +233,26 @@
mUserSwitcherView = child;
if (child.getVisibility() == GONE) continue;
- if (height < squashedLayoutThreshold) {
- int zero = MeasureSpec.makeMeasureSpec(0, MeasureSpec.EXACTLY);
- measureChild(child, zero, zero);
- } else {
- int adjustedWidthSpec = widthSpec;
- int adjustedHeightSpec = heightSpec;
- if (lp.maxWidth >= 0) {
- adjustedWidthSpec = MeasureSpec.makeMeasureSpec(
- Math.min(lp.maxWidth, MeasureSpec.getSize(widthSpec)),
- MeasureSpec.EXACTLY);
- }
- if (lp.maxHeight >= 0) {
- adjustedHeightSpec = MeasureSpec.makeMeasureSpec(
- Math.min(lp.maxHeight, MeasureSpec.getSize(heightSpec)),
- MeasureSpec.EXACTLY);
- }
- // measureChildWithMargins will resolve layout direction for the LayoutParams
- measureChildWithMargins(child, adjustedWidthSpec, 0, adjustedHeightSpec, 0);
- // Only subtract out space from one dimension. Favor vertical.
- // Offset by 1.5x to add some balance along the other edge.
- if (Gravity.isVertical(lp.gravity)) {
- heightUsed += child.getMeasuredHeight() * 1.5f;
- } else if (Gravity.isHorizontal(lp.gravity)) {
- widthUsed += child.getMeasuredWidth() * 1.5f;
- }
+ int adjustedWidthSpec = widthSpec;
+ int adjustedHeightSpec = heightSpec;
+ if (lp.maxWidth >= 0) {
+ adjustedWidthSpec = MeasureSpec.makeMeasureSpec(
+ Math.min(lp.maxWidth, width), MeasureSpec.EXACTLY);
+ }
+ if (lp.maxHeight >= 0) {
+ adjustedHeightSpec = MeasureSpec.makeMeasureSpec(
+ Math.min(lp.maxHeight, height), MeasureSpec.EXACTLY);
+ }
+ // measureChildWithMargins will resolve layout direction for the LayoutParams
+ measureChildWithMargins(child, adjustedWidthSpec, 0, adjustedHeightSpec, 0);
+
+ // Only subtract out space from one dimension. Favor vertical.
+ // Offset by 1.5x to add some balance along the other edge.
+ if (Gravity.isVertical(lp.gravity)) {
+ heightUsed += child.getMeasuredHeight() * 1.5f;
+ } else if (Gravity.isHorizontal(lp.gravity)) {
+ widthUsed += child.getMeasuredWidth() * 1.5f;
}
} else if (lp.childType == LayoutParams.CHILD_TYPE_SCRIM) {
setScrimView(child);
@@ -258,6 +272,8 @@
continue;
}
+ final int virtualHeight = getVirtualHeight(lp, height, heightUsed);
+
int adjustedWidthSpec;
int adjustedHeightSpec;
if (lp.centerWithinArea > 0) {
@@ -266,19 +282,19 @@
(int) ((width - widthUsed) * lp.centerWithinArea + 0.5f),
MeasureSpec.EXACTLY);
adjustedHeightSpec = MeasureSpec.makeMeasureSpec(
- MeasureSpec.getSize(heightSpec) - heightUsed, MeasureSpec.EXACTLY);
+ virtualHeight, MeasureSpec.EXACTLY);
} else {
adjustedWidthSpec = MeasureSpec.makeMeasureSpec(
- MeasureSpec.getSize(widthSpec) - widthUsed, MeasureSpec.EXACTLY);
+ width - widthUsed, MeasureSpec.EXACTLY);
adjustedHeightSpec = MeasureSpec.makeMeasureSpec(
- (int) ((height - heightUsed) * lp.centerWithinArea + 0.5f),
+ (int) (virtualHeight * lp.centerWithinArea + 0.5f),
MeasureSpec.EXACTLY);
}
} else {
adjustedWidthSpec = MeasureSpec.makeMeasureSpec(
- MeasureSpec.getSize(widthSpec) - widthUsed, MeasureSpec.EXACTLY);
+ width - widthUsed, MeasureSpec.EXACTLY);
adjustedHeightSpec = MeasureSpec.makeMeasureSpec(
- MeasureSpec.getSize(heightSpec) - heightUsed, MeasureSpec.EXACTLY);
+ virtualHeight, MeasureSpec.EXACTLY);
}
if (lp.maxWidth >= 0) {
adjustedWidthSpec = MeasureSpec.makeMeasureSpec(
@@ -331,6 +347,9 @@
boolean adjustPadding) {
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+ final int heightUsed = padding.top + padding.bottom - getPaddingTop() - getPaddingBottom();
+ height = getVirtualHeight(lp, height, heightUsed);
+
final int gravity = Gravity.getAbsoluteGravity(lp.gravity, getLayoutDirection());
final boolean fixedLayoutSize = lp.centerWithinArea > 0;
@@ -382,8 +401,7 @@
}
break;
case Gravity.CENTER_VERTICAL:
- final int paddedHeight = height - padding.top - padding.bottom;
- top = padding.top + (paddedHeight - childHeight) / 2;
+ top = padding.top + (height - childHeight) / 2;
bottom = top + childHeight;
break;
}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/PagedView.java b/policy/src/com/android/internal/policy/impl/keyguard/PagedView.java
index 8f47578..2f25835 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/PagedView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/PagedView.java
@@ -34,6 +34,7 @@
import android.os.Parcel;
import android.os.Parcelable;
import android.util.AttributeSet;
+import android.util.DisplayMetrics;
import android.util.Log;
import android.view.InputDevice;
import android.view.KeyEvent;
@@ -577,6 +578,10 @@
computeScrollHelper();
}
+ protected boolean shouldSetTopAlignedPivotForWidget(int childIndex) {
+ return mTopAlignPageWhenShrinkingForBouncer;
+ }
+
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (!mIsDataReady || getChildCount() == 0) {
@@ -593,8 +598,10 @@
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
// NOTE: We multiply by 1.5f to account for the fact that depending on the offset of the
// viewport, we can be at most one and a half screens offset once we scale down
- int parentWidthSize = (int) (1.5f * parent.getMeasuredWidth());
- int parentHeightSize = parent.getMeasuredHeight();
+ DisplayMetrics dm = getResources().getDisplayMetrics();
+ int maxSize = Math.max(dm.widthPixels, dm.heightPixels);
+ int parentWidthSize = (int) (1.5f * maxSize);
+ int parentHeightSize = maxSize;
int scaledWidthSize = (int) (parentWidthSize / mMinScale);
int scaledHeightSize = (int) (parentHeightSize / mMinScale);
mViewport.set(0, 0, widthSize, heightSize);
@@ -651,7 +658,7 @@
MeasureSpec.makeMeasureSpec(heightSize - verticalPadding, childHeightMode);
child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
- if (mTopAlignPageWhenShrinkingForBouncer) {
+ if (shouldSetTopAlignedPivotForWidget(i)) {
child.setPivotX(child.getWidth() / 2);
child.setPivotY(0f);
}
@@ -1015,6 +1022,17 @@
return (x > (getViewportOffsetX() + getViewportWidth() - getRelativeChildOffset(mCurrentPage) + mPageSpacing));
}
+ /** Returns whether x and y originated within the buffered/unbuffered viewport */
+ private boolean isTouchPointInViewport(int x, int y, boolean buffer) {
+ if (buffer) {
+ mTmpRect.set(mViewport.left - mViewport.width() / 2, mViewport.top,
+ mViewport.right + mViewport.width() / 2, mViewport.bottom);
+ return mTmpRect.contains(x, y);
+ } else {
+ return mViewport.contains(x, y);
+ }
+ }
+
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (DISABLE_TOUCH_INTERACTION) {
@@ -1093,7 +1111,11 @@
mTouchState = TOUCH_STATE_REST;
mScroller.abortAnimation();
} else {
- mTouchState = TOUCH_STATE_SCROLLING;
+ if (isTouchPointInViewport((int) mDownMotionX, (int) mDownMotionY, true)) {
+ mTouchState = TOUCH_STATE_SCROLLING;
+ } else {
+ mTouchState = TOUCH_STATE_REST;
+ }
}
// check if this can be the beginning of a tap on the side of the pages
@@ -1115,6 +1137,10 @@
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
resetTouchState();
+ // Just intercept the touch event on up if we tap outside the strict viewport
+ if (!isTouchPointInViewport((int) mLastMotionX, (int) mLastMotionY, false)) {
+ return true;
+ }
break;
case MotionEvent.ACTION_POINTER_UP:
@@ -1139,24 +1165,19 @@
* user moves their touch point too far.
*/
protected void determineScrollingStart(MotionEvent ev, float touchSlopScale) {
- /*
- * Locally do absolute value. mLastMotionX is set to the y value
- * of the down event.
- */
+ // Disallow scrolling if we don't have a valid pointer index
final int pointerIndex = ev.findPointerIndex(mActivePointerId);
+ if (pointerIndex == -1) return;
- if (pointerIndex == -1) {
- return;
- }
+ // Disallow scrolling if we started the gesture from outside the viewport
+ final float x = ev.getX(pointerIndex);
+ final float y = ev.getY(pointerIndex);
+ if (!isTouchPointInViewport((int) x, (int) y, true)) return;
// If we're only allowing edge swipes, we break out early if the down event wasn't
// at the edge.
- if (mOnlyAllowEdgeSwipes && !mDownEventOnEdge) {
- return;
- }
+ if (mOnlyAllowEdgeSwipes && !mDownEventOnEdge) return;
- final float x = ev.getX(pointerIndex);
- final float y = ev.getY(pointerIndex);
final int xDiff = (int) Math.abs(x - mLastMotionX);
final int yDiff = (int) Math.abs(y - mLastMotionY);
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java b/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java
index 16ec8c5..c709a5f 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java
@@ -26,8 +26,6 @@
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.FloatProperty;
@@ -62,7 +60,6 @@
// Drawn to show the drag handle in closed state; crossfades to the challenge view
// when challenge is fully visible
- private Drawable mFrameDrawable;
private boolean mEdgeCaptured;
private DisplayMetrics mDisplayMetrics;
@@ -76,6 +73,8 @@
// Range: 0 (fully hidden) to 1 (fully visible)
private float mChallengeOffset = 1.f;
private boolean mChallengeShowing = true;
+ private boolean mChallengeShowingTargetState = true;
+ private boolean mWasChallengeShowing = true;
private boolean mIsBouncing = false;
private final Scroller mScroller;
@@ -127,8 +126,6 @@
private ObjectAnimator mHandleAnimation;
private ObjectAnimator mFrameAnimation;
- private final Rect mTempRect = new Rect();
-
private boolean mHasGlowpad;
// We have an internal and external version, and we and them together.
@@ -149,23 +146,6 @@
}
};
- static final Property<SlidingChallengeLayout, Float> FRAME_ALPHA =
- new FloatProperty<SlidingChallengeLayout>("frameAlpha") {
- @Override
- public void setValue(SlidingChallengeLayout view, float value) {
- if (view.mFrameDrawable != null) {
- view.mFrameAlpha = value;
- view.mFrameDrawable.setAlpha((int) (value * 0xFF));
- view.mFrameDrawable.invalidateSelf();
- }
- }
-
- @Override
- public Float get(SlidingChallengeLayout view) {
- return view.mFrameAlpha;
- }
- };
-
// True if at least one layout pass has happened since the view was attached.
private boolean mHasLayout;
@@ -310,46 +290,6 @@
mHandleAnimation.start();
}
- void animateFrame(final boolean visible, final boolean full) {
- if (mFrameDrawable == null) return;
-
- final float targetAlpha = visible ? (full ? 1.f : 0.5f) : 0.f;
- if (mFrameAnimation != null && targetAlpha != mFrameAnimationTarget) {
- mFrameAnimation.cancel();
- mFrameAnimationTarget = Float.MIN_VALUE;
- }
- if (targetAlpha == mFrameAlpha || targetAlpha == mFrameAnimationTarget) {
- return;
- }
- mFrameAnimationTarget = targetAlpha;
-
- mFrameAnimation = ObjectAnimator.ofFloat(this, FRAME_ALPHA, targetAlpha);
- mFrameAnimation.setInterpolator(sHandleFadeInterpolator);
- mFrameAnimation.setDuration(HANDLE_ANIMATE_DURATION);
- mFrameAnimation.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mFrameAnimationTarget = Float.MIN_VALUE;
-
- if (!visible && full && mChallengeView != null) {
- // Mess with padding/margin to remove insets on the bouncer frame.
- mChallengeView.setPadding(0, 0, 0, 0);
- LayoutParams lp = (LayoutParams) mChallengeView.getLayoutParams();
- lp.leftMargin = lp.rightMargin = getChallengeMargin(true);
- mChallengeView.setLayoutParams(lp);
- }
- mFrameAnimation = null;
- }
-
- @Override
- public void onAnimationCancel(Animator animation) {
- mFrameAnimationTarget = Float.MIN_VALUE;
- mFrameAnimation = null;
- }
- });
- mFrameAnimation.start();
- }
-
private void sendInitialListenerUpdates() {
if (mScrollListener != null) {
int challengeTop = mChallengeView != null ? mChallengeView.getTop() : 0;
@@ -409,9 +349,6 @@
mScrollState = state;
animateHandle(state == SCROLL_STATE_IDLE && !mChallengeShowing);
- if (!mIsBouncing) {
- animateFrame(false, false);
- }
if (mScrollListener != null) {
mScrollListener.onScrollStateChanged(state);
}
@@ -419,7 +356,8 @@
}
void completeChallengeScroll() {
- setChallengeShowing(mChallengeOffset != 0);
+ setChallengeShowing(mChallengeShowingTargetState);
+ mChallengeOffset = mChallengeShowing ? 1.f : 0.f;
setScrollState(SCROLL_STATE_IDLE);
mChallengeInteractiveInternal = true;
mChallengeView.setLayerType(LAYER_TYPE_NONE, null);
@@ -532,6 +470,7 @@
@Override
public void showBouncer() {
if (mIsBouncing) return;
+ mWasChallengeShowing = mChallengeShowing;
mIsBouncing = true;
showChallenge(true);
if (mScrimView != null) {
@@ -543,18 +482,11 @@
// Mess with padding/margin to inset the bouncer frame.
// We have more space available to us otherwise.
if (mChallengeView != null) {
- if (mFrameDrawable == null || !mFrameDrawable.getPadding(mTempRect)) {
- mTempRect.set(0, 0, 0, 0);
- }
- mChallengeView.setPadding(mTempRect.left, mTempRect.top, mTempRect.right,
- mTempRect.bottom);
final LayoutParams lp = (LayoutParams) mChallengeView.getLayoutParams();
lp.leftMargin = lp.rightMargin = getChallengeMargin(false);
mChallengeView.setLayoutParams(lp);
}
- animateFrame(true, true);
-
if (mBouncerListener != null) {
mBouncerListener.onBouncerStateChanged(true);
}
@@ -563,7 +495,7 @@
@Override
public void hideBouncer() {
if (!mIsBouncing) return;
- showChallenge(false);
+ if (!mWasChallengeShowing) showChallenge(false);
mIsBouncing = false;
if (mScrimView != null) {
mScrimView.setVisibility(GONE);
@@ -571,7 +503,6 @@
if (mChallengeView != null) {
mChallengeView.hideBouncer(HANDLE_ANIMATE_DURATION);
}
- animateFrame(false, true);
if (mBouncerListener != null) {
mBouncerListener.onBouncerStateChanged(false);
}
@@ -861,7 +792,6 @@
mChallengeView.setVisibility(mChallengeShowing ? VISIBLE : INVISIBLE);
}
// We're going to play silly games with the frame's background drawable later.
- mFrameDrawable = mChallengeView.getBackground();
if (!mHasLayout) {
// Set up the margin correctly based on our content for the first run.
mHasGlowpad = child.findViewById(R.id.keyguard_selector_view) != null;
@@ -971,9 +901,6 @@
}
if (!mHasLayout) {
- if (mFrameDrawable != null) {
- mFrameDrawable.setAlpha(0);
- }
mHasLayout = true;
}
}
@@ -1187,6 +1114,7 @@
}
if (mHasLayout) {
+ mChallengeShowingTargetState = show;
final int layoutBottom = getLayoutBottom();
animateChallengeTo(show ? layoutBottom :
layoutBottom + mChallengeView.getHeight() - mChallengeBottomBound, velocity);
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 06594090..4659c9d 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -10347,6 +10347,10 @@
public void lockNow(Bundle options) {
mPolicy.lockNow(options);
}
+
+ public boolean isSafeModeEnabled() {
+ return mSafeMode;
+ }
void dumpPolicyLocked(PrintWriter pw, String[] args, boolean dumpAll) {
pw.println("WINDOW MANAGER POLICY STATE (dumpsys window policy)");
diff --git a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
index da736b7..fa2cb50 100644
--- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
+++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
@@ -446,6 +446,11 @@
public void lockNow(Bundle options) {
// TODO Auto-generated method stub
}
+
+ @Override
+ public boolean isSafeModeEnabled() {
+ return false;
+ }
@Override
public IBinder getFocusedWindowToken() {