Merge "Transfer large bitmaps using ashmem. Bug: 5224703"
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index d193d6e..31740ef 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -12093,6 +12093,39 @@
}
/**
+ * Finds a view by its unuque and stable accessibility id.
+ *
+ * @param accessibilityId The searched accessibility id.
+ * @return The found view.
+ */
+ final View findViewByAccessibilityId(int accessibilityId) {
+ if (accessibilityId < 0) {
+ return null;
+ }
+ return findViewByAccessibilityIdTraversal(accessibilityId);
+ }
+
+ /**
+ * Performs the traversal to find a view by its unuque and stable accessibility id.
+ *
+ * <strong>Note:</strong>This method does not stop at the root namespace
+ * boundary since the user can touch the screen at an arbitrary location
+ * potentially crossing the root namespace bounday which will send an
+ * accessibility event to accessibility services and they should be able
+ * to obtain the event source. Also accessibility ids are guaranteed to be
+ * unique in the window.
+ *
+ * @param accessibilityId The accessibility id.
+ * @return The found view.
+ */
+ View findViewByAccessibilityIdTraversal(int accessibilityId) {
+ if (getAccessibilityViewId() == accessibilityId) {
+ return this;
+ }
+ return null;
+ }
+
+ /**
* Look for a child view with the given tag. If this view has the given
* tag, return this view.
*
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index fb0d80a..5b4a6f8 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -821,6 +821,24 @@
}
}
+ @Override
+ View findViewByAccessibilityIdTraversal(int accessibilityId) {
+ View foundView = super.findViewByAccessibilityIdTraversal(accessibilityId);
+ if (foundView != null) {
+ return foundView;
+ }
+ final int childrenCount = mChildrenCount;
+ final View[] children = mChildren;
+ for (int i = 0; i < childrenCount; i++) {
+ View child = children[i];
+ foundView = child.findViewByAccessibilityIdTraversal(accessibilityId);
+ if (foundView != null) {
+ return foundView;
+ }
+ }
+ return null;
+ }
+
/**
* {@inheritDoc}
*/
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 9cb4e5e..a9a0347d 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -74,7 +74,6 @@
import android.widget.Scroller;
import com.android.internal.policy.PolicyManager;
-import com.android.internal.util.Predicate;
import com.android.internal.view.BaseSurfaceHolder;
import com.android.internal.view.IInputMethodCallback;
import com.android.internal.view.IInputMethodSession;
@@ -4462,9 +4461,6 @@
final class AccessibilityInteractionController {
private static final int POOL_SIZE = 5;
- private FindByAccessibilitytIdPredicate mFindByAccessibilityIdPredicate =
- new FindByAccessibilitytIdPredicate();
-
private ArrayList<AccessibilityNodeInfo> mTempAccessibilityNodeInfoList =
new ArrayList<AccessibilityNodeInfo>();
@@ -4551,11 +4547,8 @@
AccessibilityNodeInfo info = null;
try {
- FindByAccessibilitytIdPredicate predicate = mFindByAccessibilityIdPredicate;
- predicate.init(accessibilityId);
- View root = ViewRootImpl.this.mView;
- View target = root.findViewByPredicate(predicate);
- if (target != null && target.getVisibility() == View.VISIBLE) {
+ View target = findViewByAccessibilityId(accessibilityId);
+ if (target != null) {
info = target.createAccessibilityNodeInfo();
}
} finally {
@@ -4794,25 +4787,12 @@
if (root == null) {
return null;
}
- mFindByAccessibilityIdPredicate.init(accessibilityId);
- View foundView = root.findViewByPredicate(mFindByAccessibilityIdPredicate);
- if (foundView == null || foundView.getVisibility() != View.VISIBLE) {
+ View foundView = root.findViewByAccessibilityId(accessibilityId);
+ if (foundView != null && foundView.getVisibility() != View.VISIBLE) {
return null;
}
return foundView;
}
-
- private final class FindByAccessibilitytIdPredicate implements Predicate<View> {
- public int mSearchedId;
-
- public void init(int searchedId) {
- mSearchedId = searchedId;
- }
-
- public boolean apply(View view) {
- return (view.getAccessibilityViewId() == mSearchedId);
- }
- }
}
private class SendWindowContentChangedAccessibilityEvent implements Runnable {
diff --git a/core/java/android/widget/AnalogClock.java b/core/java/android/widget/AnalogClock.java
index 84ebec3..63a0870 100644
--- a/core/java/android/widget/AnalogClock.java
+++ b/core/java/android/widget/AnalogClock.java
@@ -25,6 +25,7 @@
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.os.Handler;
+import android.text.format.DateUtils;
import android.text.format.Time;
import android.util.AttributeSet;
import android.view.View;
@@ -228,6 +229,8 @@
mMinutes = minute + second / 60.0f;
mHour = hour + mMinutes / 60.0f;
mChanged = true;
+
+ updateContentDescription(mCalendar);
}
private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
@@ -243,4 +246,11 @@
invalidate();
}
};
+
+ private void updateContentDescription(Time time) {
+ final int flags = DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_24HOUR;
+ String contentDescription = DateUtils.formatDateTime(mContext,
+ time.toMillis(false), flags);
+ setContentDescription(contentDescription);
+ }
}
diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java
index 7444d46..f52e773 100644
--- a/core/java/android/widget/TimePicker.java
+++ b/core/java/android/widget/TimePicker.java
@@ -237,9 +237,7 @@
}
// set the content descriptions
- if (AccessibilityManager.getInstance(mContext).isEnabled()) {
- setContentDescriptions();
- }
+ setContentDescriptions();
}
@Override
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 4a38775..a793abb 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -24,11 +24,15 @@
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.hardware.Camera;
+import android.hardware.Camera.CameraInfo;
import android.os.FileObserver;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
+import android.os.SystemProperties;
import android.os.storage.IMountService;
import android.provider.Settings;
import android.security.KeyStore;
@@ -434,7 +438,7 @@
* Calls back SetupFaceLock to delete the gallery file when the lock type is changed
*/
void deleteGallery() {
- if(isBiometricEnabled()) {
+ if(usingBiometricWeak()) {
Intent intent = new Intent().setClassName("com.android.facelock",
"com.android.facelock.SetupFaceLock");
intent.putExtra("deleteGallery", true);
@@ -677,6 +681,9 @@
return quality;
}
+ /**
+ * @return true if the lockscreen method is set to biometric weak
+ */
public boolean usingBiometricWeak() {
int quality =
(int) getLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
@@ -810,7 +817,7 @@
|| backupMode == DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
return savedPasswordExists() && (passwordEnabled ||
- (isBiometricEnabled() && backupEnabled));
+ (usingBiometricWeak() && backupEnabled));
}
/**
@@ -824,16 +831,36 @@
return getBoolean(Settings.Secure.LOCK_PATTERN_ENABLED)
&& (getLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING)
== DevicePolicyManager.PASSWORD_QUALITY_SOMETHING ||
- (isBiometricEnabled() && backupEnabled));
+ (usingBiometricWeak() && backupEnabled));
}
/**
- * @return Whether biometric weak lock is enabled.
+ * @return Whether biometric weak lock is installed and that the front facing camera exists
*/
- public boolean isBiometricEnabled() {
- // TODO: check if it's installed
- return getLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING)
- == DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK;
+ public boolean isBiometricWeakInstalled() {
+ // Check that the system flag was set
+ if (!SystemProperties.getBoolean("ro.lockscreen.facelock_enabled", false)) {
+ return false;
+ }
+
+ // Check that it's installed
+ PackageManager pm = mContext.getPackageManager();
+ try {
+ pm.getPackageInfo("com.android.facelock", PackageManager.GET_ACTIVITIES);
+ } catch (PackageManager.NameNotFoundException e) {
+ return false;
+ }
+
+ // Check that the camera is enabled
+ if (!pm.hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT)) {
+ return false;
+ }
+ if (getDevicePolicyManager().getCameraDisabled(null)) {
+ return false;
+ }
+
+
+ return true;
}
/**
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
index f970ff3..ca5d274 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -531,7 +531,8 @@
((KeyguardScreen) mUnlockScreen).onResume();
}
- if (mLockPatternUtils.usingBiometricWeak()) {
+ if (mLockPatternUtils.usingBiometricWeak() &&
+ mLockPatternUtils.isBiometricWeakInstalled()) {
mHandler.sendEmptyMessage(MSG_SHOW_FACELOCK_AREA_VIEW);
} else {
mHandler.sendEmptyMessage(MSG_HIDE_FACELOCK_AREA_VIEW);
@@ -1014,7 +1015,8 @@
// Binds to FaceLock service, but does not tell it to start
public void bindToFaceLock() {
- if (mLockPatternUtils.usingBiometricWeak()) {
+ if (mLockPatternUtils.usingBiometricWeak() &&
+ mLockPatternUtils.isBiometricWeakInstalled()) {
if (!mBoundToFaceLockService) {
if (DEBUG) Log.d(TAG, "before bind to FaceLock service");
mContext.bindService(new Intent(IFaceLockInterface.class.getName()),
@@ -1030,7 +1032,8 @@
// Tells FaceLock to stop and then unbinds from the FaceLock service
public void stopAndUnbindFromFaceLock() {
- if (mLockPatternUtils.usingBiometricWeak()) {
+ if (mLockPatternUtils.usingBiometricWeak() &&
+ mLockPatternUtils.isBiometricWeakInstalled()) {
stopFaceLock();
if (mBoundToFaceLockService) {
@@ -1079,7 +1082,8 @@
// Tells the FaceLock service to start displaying its UI and perform recognition
public void startFaceLock(IBinder windowToken, int x, int y, int h, int w)
{
- if (mLockPatternUtils.usingBiometricWeak()) {
+ if (mLockPatternUtils.usingBiometricWeak() &&
+ mLockPatternUtils.isBiometricWeakInstalled()) {
synchronized (mFaceLockServiceRunningLock) {
if (!mFaceLockServiceRunning) {
if (DEBUG) Log.d(TAG, "Starting FaceLock");
@@ -1099,7 +1103,8 @@
// Tells the FaceLock service to stop displaying its UI and stop recognition
public void stopFaceLock()
{
- if (mLockPatternUtils.usingBiometricWeak()) {
+ if (mLockPatternUtils.usingBiometricWeak() &&
+ mLockPatternUtils.isBiometricWeakInstalled()) {
// Note that attempting to stop FaceLock when it's not running is not an issue.
// FaceLock can return, which stops it and then we try to stop it when the
// screen is turned off. That's why we check.