frameworks/base
修訂 | d369253fab4986f4136f5035c10abc0f5f52c947 (tree) |
---|---|
時間 | 2016-10-06 00:46:44 |
作者 | Chih-Wei Huang <cwhuang@linu...> |
Commiter | Chih-Wei Huang |
Merge tag 'android-7.0.0_r7' into nougat-x86
Android 7.0.0 Release 7 (NRD91D)
@@ -628,8 +628,8 @@ public abstract class AccessibilityService extends Service { | ||
628 | 628 | if (connection == null) { |
629 | 629 | return false; |
630 | 630 | } |
631 | - List<MotionEvent> events = MotionEventGenerator.getMotionEventsFromGestureDescription( | |
632 | - gesture, 100); | |
631 | + List<GestureDescription.GestureStep> steps = | |
632 | + MotionEventGenerator.getGestureStepsFromGestureDescription(gesture, 100); | |
633 | 633 | try { |
634 | 634 | synchronized (mLock) { |
635 | 635 | mGestureStatusCallbackSequence++; |
@@ -641,8 +641,8 @@ public abstract class AccessibilityService extends Service { | ||
641 | 641 | callback, handler); |
642 | 642 | mGestureStatusCallbackInfos.put(mGestureStatusCallbackSequence, callbackInfo); |
643 | 643 | } |
644 | - connection.sendMotionEvents(mGestureStatusCallbackSequence, | |
645 | - new ParceledListSlice<>(events)); | |
644 | + connection.sendGesture(mGestureStatusCallbackSequence, | |
645 | + new ParceledListSlice<>(steps)); | |
646 | 646 | } |
647 | 647 | } catch (RemoteException re) { |
648 | 648 | throw new RuntimeException(re); |
@@ -21,6 +21,8 @@ import android.annotation.NonNull; | ||
21 | 21 | import android.graphics.Path; |
22 | 22 | import android.graphics.PathMeasure; |
23 | 23 | import android.graphics.RectF; |
24 | +import android.os.Parcel; | |
25 | +import android.os.Parcelable; | |
24 | 26 | import android.view.InputDevice; |
25 | 27 | import android.view.MotionEvent; |
26 | 28 | import android.view.MotionEvent.PointerCoords; |
@@ -303,13 +305,37 @@ public final class GestureDescription { | ||
303 | 305 | } |
304 | 306 | } |
305 | 307 | |
306 | - private static class TouchPoint { | |
308 | + /** | |
309 | + * The location of a finger for gesture dispatch | |
310 | + * | |
311 | + * @hide | |
312 | + */ | |
313 | + public static class TouchPoint implements Parcelable { | |
314 | + private static final int FLAG_IS_START_OF_PATH = 0x01; | |
315 | + private static final int FLAG_IS_END_OF_PATH = 0x02; | |
316 | + | |
307 | 317 | int mPathIndex; |
308 | 318 | boolean mIsStartOfPath; |
309 | 319 | boolean mIsEndOfPath; |
310 | 320 | float mX; |
311 | 321 | float mY; |
312 | 322 | |
323 | + public TouchPoint() { | |
324 | + } | |
325 | + | |
326 | + public TouchPoint(TouchPoint pointToCopy) { | |
327 | + copyFrom(pointToCopy); | |
328 | + } | |
329 | + | |
330 | + public TouchPoint(Parcel parcel) { | |
331 | + mPathIndex = parcel.readInt(); | |
332 | + int startEnd = parcel.readInt(); | |
333 | + mIsStartOfPath = (startEnd & FLAG_IS_START_OF_PATH) != 0; | |
334 | + mIsEndOfPath = (startEnd & FLAG_IS_END_OF_PATH) != 0; | |
335 | + mX = parcel.readFloat(); | |
336 | + mY = parcel.readFloat(); | |
337 | + } | |
338 | + | |
313 | 339 | void copyFrom(TouchPoint other) { |
314 | 340 | mPathIndex = other.mPathIndex; |
315 | 341 | mIsStartOfPath = other.mIsStartOfPath; |
@@ -317,12 +343,94 @@ public final class GestureDescription { | ||
317 | 343 | mX = other.mX; |
318 | 344 | mY = other.mY; |
319 | 345 | } |
346 | + | |
347 | + @Override | |
348 | + public int describeContents() { | |
349 | + return 0; | |
350 | + } | |
351 | + | |
352 | + @Override | |
353 | + public void writeToParcel(Parcel dest, int flags) { | |
354 | + dest.writeInt(mPathIndex); | |
355 | + int startEnd = mIsStartOfPath ? FLAG_IS_START_OF_PATH : 0; | |
356 | + startEnd |= mIsEndOfPath ? FLAG_IS_END_OF_PATH : 0; | |
357 | + dest.writeInt(startEnd); | |
358 | + dest.writeFloat(mX); | |
359 | + dest.writeFloat(mY); | |
360 | + } | |
361 | + | |
362 | + public static final Parcelable.Creator<TouchPoint> CREATOR | |
363 | + = new Parcelable.Creator<TouchPoint>() { | |
364 | + public TouchPoint createFromParcel(Parcel in) { | |
365 | + return new TouchPoint(in); | |
366 | + } | |
367 | + | |
368 | + public TouchPoint[] newArray(int size) { | |
369 | + return new TouchPoint[size]; | |
370 | + } | |
371 | + }; | |
372 | + } | |
373 | + | |
374 | + /** | |
375 | + * A step along a gesture. Contains all of the touch points at a particular time | |
376 | + * | |
377 | + * @hide | |
378 | + */ | |
379 | + public static class GestureStep implements Parcelable { | |
380 | + public long timeSinceGestureStart; | |
381 | + public int numTouchPoints; | |
382 | + public TouchPoint[] touchPoints; | |
383 | + | |
384 | + public GestureStep(long timeSinceGestureStart, int numTouchPoints, | |
385 | + TouchPoint[] touchPointsToCopy) { | |
386 | + this.timeSinceGestureStart = timeSinceGestureStart; | |
387 | + this.numTouchPoints = numTouchPoints; | |
388 | + this.touchPoints = new TouchPoint[numTouchPoints]; | |
389 | + for (int i = 0; i < numTouchPoints; i++) { | |
390 | + this.touchPoints[i] = new TouchPoint(touchPointsToCopy[i]); | |
391 | + } | |
392 | + } | |
393 | + | |
394 | + public GestureStep(Parcel parcel) { | |
395 | + timeSinceGestureStart = parcel.readLong(); | |
396 | + Parcelable[] parcelables = | |
397 | + parcel.readParcelableArray(TouchPoint.class.getClassLoader()); | |
398 | + numTouchPoints = (parcelables == null) ? 0 : parcelables.length; | |
399 | + touchPoints = new TouchPoint[numTouchPoints]; | |
400 | + for (int i = 0; i < numTouchPoints; i++) { | |
401 | + touchPoints[i] = (TouchPoint) parcelables[i]; | |
402 | + } | |
403 | + } | |
404 | + | |
405 | + @Override | |
406 | + public int describeContents() { | |
407 | + return 0; | |
408 | + } | |
409 | + | |
410 | + @Override | |
411 | + public void writeToParcel(Parcel dest, int flags) { | |
412 | + dest.writeLong(timeSinceGestureStart); | |
413 | + dest.writeParcelableArray(touchPoints, flags); | |
414 | + } | |
415 | + | |
416 | + public static final Parcelable.Creator<GestureStep> CREATOR | |
417 | + = new Parcelable.Creator<GestureStep>() { | |
418 | + public GestureStep createFromParcel(Parcel in) { | |
419 | + return new GestureStep(in); | |
420 | + } | |
421 | + | |
422 | + public GestureStep[] newArray(int size) { | |
423 | + return new GestureStep[size]; | |
424 | + } | |
425 | + }; | |
320 | 426 | } |
321 | 427 | |
322 | 428 | /** |
323 | 429 | * Class to convert a GestureDescription to a series of MotionEvents. |
430 | + * | |
431 | + * @hide | |
324 | 432 | */ |
325 | - static class MotionEventGenerator { | |
433 | + public static class MotionEventGenerator { | |
326 | 434 | /** |
327 | 435 | * Constants used to initialize all MotionEvents |
328 | 436 | */ |
@@ -341,38 +449,52 @@ public final class GestureDescription { | ||
341 | 449 | private static PointerCoords[] sPointerCoords; |
342 | 450 | private static PointerProperties[] sPointerProps; |
343 | 451 | |
344 | - static List<MotionEvent> getMotionEventsFromGestureDescription( | |
452 | + static List<GestureStep> getGestureStepsFromGestureDescription( | |
345 | 453 | GestureDescription description, int sampleTimeMs) { |
346 | - final List<MotionEvent> motionEvents = new ArrayList<>(); | |
454 | + final List<GestureStep> gestureSteps = new ArrayList<>(); | |
347 | 455 | |
348 | 456 | // Point data at each time we generate an event for |
349 | 457 | final TouchPoint[] currentTouchPoints = |
350 | 458 | getCurrentTouchPoints(description.getStrokeCount()); |
351 | - // Point data sent in last touch event | |
352 | - int lastTouchPointSize = 0; | |
353 | - final TouchPoint[] lastTouchPoints = | |
354 | - getLastTouchPoints(description.getStrokeCount()); | |
355 | - | |
459 | + int currentTouchPointSize = 0; | |
356 | 460 | /* Loop through each time slice where there are touch points */ |
357 | 461 | long timeSinceGestureStart = 0; |
358 | 462 | long nextKeyPointTime = description.getNextKeyPointAtLeast(timeSinceGestureStart); |
359 | 463 | while (nextKeyPointTime >= 0) { |
360 | - timeSinceGestureStart = (lastTouchPointSize == 0) ? nextKeyPointTime | |
464 | + timeSinceGestureStart = (currentTouchPointSize == 0) ? nextKeyPointTime | |
361 | 465 | : Math.min(nextKeyPointTime, timeSinceGestureStart + sampleTimeMs); |
362 | - int currentTouchPointSize = description.getPointsForTime(timeSinceGestureStart, | |
466 | + currentTouchPointSize = description.getPointsForTime(timeSinceGestureStart, | |
363 | 467 | currentTouchPoints); |
468 | + gestureSteps.add(new GestureStep(timeSinceGestureStart, currentTouchPointSize, | |
469 | + currentTouchPoints)); | |
470 | + | |
471 | + /* Move to next time slice */ | |
472 | + nextKeyPointTime = description.getNextKeyPointAtLeast(timeSinceGestureStart + 1); | |
473 | + } | |
474 | + return gestureSteps; | |
475 | + } | |
476 | + | |
477 | + public static List<MotionEvent> getMotionEventsFromGestureSteps(List<GestureStep> steps) { | |
478 | + final List<MotionEvent> motionEvents = new ArrayList<>(); | |
479 | + | |
480 | + // Number of points in last touch event | |
481 | + int lastTouchPointSize = 0; | |
482 | + TouchPoint[] lastTouchPoints; | |
483 | + | |
484 | + for (int i = 0; i < steps.size(); i++) { | |
485 | + GestureStep step = steps.get(i); | |
486 | + int currentTouchPointSize = step.numTouchPoints; | |
487 | + lastTouchPoints = getLastTouchPoints( | |
488 | + Math.max(lastTouchPointSize, currentTouchPointSize)); | |
364 | 489 | |
365 | 490 | appendMoveEventIfNeeded(motionEvents, lastTouchPoints, lastTouchPointSize, |
366 | - currentTouchPoints, currentTouchPointSize, timeSinceGestureStart); | |
491 | + step.touchPoints, currentTouchPointSize, step.timeSinceGestureStart); | |
367 | 492 | lastTouchPointSize = appendUpEvents(motionEvents, lastTouchPoints, |
368 | - lastTouchPointSize, currentTouchPoints, currentTouchPointSize, | |
369 | - timeSinceGestureStart); | |
493 | + lastTouchPointSize, step.touchPoints, currentTouchPointSize, | |
494 | + step.timeSinceGestureStart); | |
370 | 495 | lastTouchPointSize = appendDownEvents(motionEvents, lastTouchPoints, |
371 | - lastTouchPointSize, currentTouchPoints, currentTouchPointSize, | |
372 | - timeSinceGestureStart); | |
373 | - | |
374 | - /* Move to next time slice */ | |
375 | - nextKeyPointTime = description.getNextKeyPointAtLeast(timeSinceGestureStart + 1); | |
496 | + lastTouchPointSize, step.touchPoints, currentTouchPointSize, | |
497 | + step.timeSinceGestureStart); | |
376 | 498 | } |
377 | 499 | return motionEvents; |
378 | 500 | } |
@@ -88,5 +88,5 @@ interface IAccessibilityServiceConnection { | ||
88 | 88 | |
89 | 89 | void setSoftKeyboardCallbackEnabled(boolean enabled); |
90 | 90 | |
91 | - void sendMotionEvents(int sequence, in ParceledListSlice events); | |
91 | + void sendGesture(int sequence, in ParceledListSlice gestureSteps); | |
92 | 92 | } |
@@ -259,6 +259,7 @@ public class FingerprintManager { | ||
259 | 259 | public static class AuthenticationResult { |
260 | 260 | private Fingerprint mFingerprint; |
261 | 261 | private CryptoObject mCryptoObject; |
262 | + private int mUserId; | |
262 | 263 | |
263 | 264 | /** |
264 | 265 | * Authentication result |
@@ -267,9 +268,10 @@ public class FingerprintManager { | ||
267 | 268 | * @param fingerprint the recognized fingerprint data, if allowed. |
268 | 269 | * @hide |
269 | 270 | */ |
270 | - public AuthenticationResult(CryptoObject crypto, Fingerprint fingerprint) { | |
271 | + public AuthenticationResult(CryptoObject crypto, Fingerprint fingerprint, int userId) { | |
271 | 272 | mCryptoObject = crypto; |
272 | 273 | mFingerprint = fingerprint; |
274 | + mUserId = userId; | |
273 | 275 | } |
274 | 276 | |
275 | 277 | /** |
@@ -286,6 +288,12 @@ public class FingerprintManager { | ||
286 | 288 | * @hide |
287 | 289 | */ |
288 | 290 | public Fingerprint getFingerprint() { return mFingerprint; } |
291 | + | |
292 | + /** | |
293 | + * Obtain the userId for which this fingerprint was authenticated. | |
294 | + * @hide | |
295 | + */ | |
296 | + public int getUserId() { return mUserId; } | |
289 | 297 | }; |
290 | 298 | |
291 | 299 | /** |
@@ -792,7 +800,7 @@ public class FingerprintManager { | ||
792 | 800 | sendAcquiredResult((Long) msg.obj /* deviceId */, msg.arg1 /* acquire info */); |
793 | 801 | break; |
794 | 802 | case MSG_AUTHENTICATION_SUCCEEDED: |
795 | - sendAuthenticatedSucceeded((Fingerprint) msg.obj); | |
803 | + sendAuthenticatedSucceeded((Fingerprint) msg.obj, msg.arg1 /* userId */); | |
796 | 804 | break; |
797 | 805 | case MSG_AUTHENTICATION_FAILED: |
798 | 806 | sendAuthenticatedFailed(); |
@@ -840,9 +848,10 @@ public class FingerprintManager { | ||
840 | 848 | } |
841 | 849 | } |
842 | 850 | |
843 | - private void sendAuthenticatedSucceeded(Fingerprint fp) { | |
851 | + private void sendAuthenticatedSucceeded(Fingerprint fp, int userId) { | |
844 | 852 | if (mAuthenticationCallback != null) { |
845 | - final AuthenticationResult result = new AuthenticationResult(mCryptoObject, fp); | |
853 | + final AuthenticationResult result = | |
854 | + new AuthenticationResult(mCryptoObject, fp, userId); | |
846 | 855 | mAuthenticationCallback.onAuthenticationSucceeded(result); |
847 | 856 | } |
848 | 857 | } |
@@ -981,8 +990,8 @@ public class FingerprintManager { | ||
981 | 990 | } |
982 | 991 | |
983 | 992 | @Override // binder call |
984 | - public void onAuthenticationSucceeded(long deviceId, Fingerprint fp) { | |
985 | - mHandler.obtainMessage(MSG_AUTHENTICATION_SUCCEEDED, fp).sendToTarget(); | |
993 | + public void onAuthenticationSucceeded(long deviceId, Fingerprint fp, int userId) { | |
994 | + mHandler.obtainMessage(MSG_AUTHENTICATION_SUCCEEDED, userId, 0, fp).sendToTarget(); | |
986 | 995 | } |
987 | 996 | |
988 | 997 | @Override // binder call |
@@ -26,7 +26,7 @@ import android.os.UserHandle; | ||
26 | 26 | oneway interface IFingerprintServiceReceiver { |
27 | 27 | void onEnrollResult(long deviceId, int fingerId, int groupId, int remaining); |
28 | 28 | void onAcquired(long deviceId, int acquiredInfo); |
29 | - void onAuthenticationSucceeded(long deviceId, in Fingerprint fp); | |
29 | + void onAuthenticationSucceeded(long deviceId, in Fingerprint fp, int userId); | |
30 | 30 | void onAuthenticationFailed(long deviceId); |
31 | 31 | void onError(long deviceId, int error); |
32 | 32 | void onRemoved(long deviceId, int fingerId, int groupId); |
@@ -559,6 +559,15 @@ public class Process { | ||
559 | 559 | ZygoteState zygoteState, ArrayList<String> args) |
560 | 560 | throws ZygoteStartFailedEx { |
561 | 561 | try { |
562 | + // Throw early if any of the arguments are malformed. This means we can | |
563 | + // avoid writing a partial response to the zygote. | |
564 | + int sz = args.size(); | |
565 | + for (int i = 0; i < sz; i++) { | |
566 | + if (args.get(i).indexOf('\n') >= 0) { | |
567 | + throw new ZygoteStartFailedEx("embedded newlines not allowed"); | |
568 | + } | |
569 | + } | |
570 | + | |
562 | 571 | /** |
563 | 572 | * See com.android.internal.os.ZygoteInit.readArgumentList() |
564 | 573 | * Presently the wire format to the zygote process is: |
@@ -575,13 +584,8 @@ public class Process { | ||
575 | 584 | writer.write(Integer.toString(args.size())); |
576 | 585 | writer.newLine(); |
577 | 586 | |
578 | - int sz = args.size(); | |
579 | 587 | for (int i = 0; i < sz; i++) { |
580 | 588 | String arg = args.get(i); |
581 | - if (arg.indexOf('\n') >= 0) { | |
582 | - throw new ZygoteStartFailedEx( | |
583 | - "embedded newlines not allowed"); | |
584 | - } | |
585 | 589 | writer.write(arg); |
586 | 590 | writer.newLine(); |
587 | 591 | } |
@@ -590,11 +594,16 @@ public class Process { | ||
590 | 594 | |
591 | 595 | // Should there be a timeout on this? |
592 | 596 | ProcessStartResult result = new ProcessStartResult(); |
597 | + | |
598 | + // Always read the entire result from the input stream to avoid leaving | |
599 | + // bytes in the stream for future process starts to accidentally stumble | |
600 | + // upon. | |
593 | 601 | result.pid = inputStream.readInt(); |
602 | + result.usingWrapper = inputStream.readBoolean(); | |
603 | + | |
594 | 604 | if (result.pid < 0) { |
595 | 605 | throw new ZygoteStartFailedEx("fork() failed"); |
596 | 606 | } |
597 | - result.usingWrapper = inputStream.readBoolean(); | |
598 | 607 | return result; |
599 | 608 | } catch (IOException ex) { |
600 | 609 | zygoteState.close(); |
@@ -354,7 +354,7 @@ public class LockPatternUtils { | ||
354 | 354 | return false; |
355 | 355 | } |
356 | 356 | } catch (RemoteException re) { |
357 | - return true; | |
357 | + return false; | |
358 | 358 | } |
359 | 359 | } |
360 | 360 |
@@ -435,7 +435,7 @@ public class LockPatternUtils { | ||
435 | 435 | return false; |
436 | 436 | } |
437 | 437 | } catch (RemoteException re) { |
438 | - return true; | |
438 | + return false; | |
439 | 439 | } |
440 | 440 | } |
441 | 441 |
@@ -433,7 +433,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { | ||
433 | 433 | } |
434 | 434 | } |
435 | 435 | |
436 | - private void handleFingerprintAuthenticated() { | |
436 | + private void handleFingerprintAuthenticated(int authUserId) { | |
437 | 437 | try { |
438 | 438 | final int userId; |
439 | 439 | try { |
@@ -442,6 +442,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { | ||
442 | 442 | Log.e(TAG, "Failed to get current user id: ", e); |
443 | 443 | return; |
444 | 444 | } |
445 | + if (userId != authUserId) { | |
446 | + Log.d(TAG, "Fingerprint authenticated for wrong user: " + authUserId); | |
447 | + return; | |
448 | + } | |
445 | 449 | if (isFingerprintDisabled(userId)) { |
446 | 450 | Log.d(TAG, "Fingerprint disabled by DPM for userId: " + userId); |
447 | 451 | return; |
@@ -725,7 +729,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { | ||
725 | 729 | |
726 | 730 | @Override |
727 | 731 | public void onAuthenticationSucceeded(AuthenticationResult result) { |
728 | - handleFingerprintAuthenticated(); | |
732 | + handleFingerprintAuthenticated(result.getUserId()); | |
729 | 733 | } |
730 | 734 | |
731 | 735 | @Override |
@@ -21,6 +21,7 @@ import static android.accessibilityservice.AccessibilityServiceInfo.DEFAULT; | ||
21 | 21 | import android.Manifest; |
22 | 22 | import android.accessibilityservice.AccessibilityService; |
23 | 23 | import android.accessibilityservice.AccessibilityServiceInfo; |
24 | +import android.accessibilityservice.GestureDescription; | |
24 | 25 | import android.accessibilityservice.IAccessibilityServiceClient; |
25 | 26 | import android.accessibilityservice.IAccessibilityServiceConnection; |
26 | 27 | import android.annotation.NonNull; |
@@ -2755,7 +2756,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { | ||
2755 | 2756 | } |
2756 | 2757 | |
2757 | 2758 | @Override |
2758 | - public void sendMotionEvents(int sequence, ParceledListSlice events) { | |
2759 | + public void sendGesture(int sequence, ParceledListSlice gestureSteps) { | |
2759 | 2760 | synchronized (mLock) { |
2760 | 2761 | if (mSecurityPolicy.canPerformGestures(this)) { |
2761 | 2762 | final long endMillis = |
@@ -2769,9 +2770,16 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { | ||
2769 | 2770 | } |
2770 | 2771 | } |
2771 | 2772 | if (mMotionEventInjector != null) { |
2772 | - mMotionEventInjector.injectEvents((List<MotionEvent>) events.getList(), | |
2773 | - mServiceInterface, sequence); | |
2774 | - return; | |
2773 | + List<GestureDescription.GestureStep> steps = gestureSteps.getList(); | |
2774 | + List<MotionEvent> events = GestureDescription.MotionEventGenerator | |
2775 | + .getMotionEventsFromGestureSteps(steps); | |
2776 | + // Confirm that the motion events end with an UP event. | |
2777 | + if (events.get(events.size() - 1).getAction() == MotionEvent.ACTION_UP) { | |
2778 | + mMotionEventInjector.injectEvents(events, mServiceInterface, sequence); | |
2779 | + return; | |
2780 | + } else { | |
2781 | + Slog.e(LOG_TAG, "Gesture is not well-formed"); | |
2782 | + } | |
2775 | 2783 | } else { |
2776 | 2784 | Slog.e(LOG_TAG, "MotionEventInjector installation timed out"); |
2777 | 2785 | } |
@@ -1215,6 +1215,9 @@ public class LockSettingsService extends ILockSettings.Stub { | ||
1215 | 1215 | private VerifyCredentialResponse doVerifyPattern(String pattern, boolean hasChallenge, |
1216 | 1216 | long challenge, int userId) throws RemoteException { |
1217 | 1217 | checkPasswordReadPermission(userId); |
1218 | + if (TextUtils.isEmpty(pattern)) { | |
1219 | + throw new IllegalArgumentException("Pattern can't be null or empty"); | |
1220 | + } | |
1218 | 1221 | CredentialHash storedHash = mStorage.readPatternHash(userId); |
1219 | 1222 | return doVerifyPattern(pattern, storedHash, hasChallenge, challenge, userId); |
1220 | 1223 | } |
@@ -1306,6 +1309,9 @@ public class LockSettingsService extends ILockSettings.Stub { | ||
1306 | 1309 | private VerifyCredentialResponse doVerifyPassword(String password, boolean hasChallenge, |
1307 | 1310 | long challenge, int userId) throws RemoteException { |
1308 | 1311 | checkPasswordReadPermission(userId); |
1312 | + if (TextUtils.isEmpty(password)) { | |
1313 | + throw new IllegalArgumentException("Password can't be null or empty"); | |
1314 | + } | |
1309 | 1315 | CredentialHash storedHash = mStorage.readPasswordHash(userId); |
1310 | 1316 | return doVerifyPassword(password, storedHash, hasChallenge, challenge, userId); |
1311 | 1317 | } |
@@ -3797,6 +3797,15 @@ public final class ActivityManagerService extends ActivityManagerNative | ||
3797 | 3797 | app.killedByAm = false; |
3798 | 3798 | checkTime(startTime, "startProcess: starting to update pids map"); |
3799 | 3799 | synchronized (mPidsSelfLocked) { |
3800 | + ProcessRecord oldApp; | |
3801 | + // If there is already an app occupying that pid that hasn't been cleaned up | |
3802 | + if ((oldApp = mPidsSelfLocked.get(startResult.pid)) != null && !app.isolated) { | |
3803 | + // Clean up anything relating to this pid first | |
3804 | + Slog.w(TAG, "Reusing pid " + startResult.pid | |
3805 | + + " while app is still mapped to it"); | |
3806 | + cleanUpApplicationRecordLocked(oldApp, false, false, -1, | |
3807 | + true /*replacingPid*/); | |
3808 | + } | |
3800 | 3809 | this.mPidsSelfLocked.put(startResult.pid, app); |
3801 | 3810 | if (isActivityProcess) { |
3802 | 3811 | Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); |
@@ -5012,7 +5021,8 @@ public final class ActivityManagerService extends ActivityManagerNative | ||
5012 | 5021 | private final void handleAppDiedLocked(ProcessRecord app, |
5013 | 5022 | boolean restarting, boolean allowRestart) { |
5014 | 5023 | int pid = app.pid; |
5015 | - boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); | |
5024 | + boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1, | |
5025 | + false /*replacingPid*/); | |
5016 | 5026 | if (!kept && !restarting) { |
5017 | 5027 | removeLruProcessLocked(app); |
5018 | 5028 | if (pid > 0) { |
@@ -16654,7 +16664,8 @@ public final class ActivityManagerService extends ActivityManagerNative | ||
16654 | 16664 | * app that was passed in must remain on the process lists. |
16655 | 16665 | */ |
16656 | 16666 | private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, |
16657 | - boolean restarting, boolean allowRestart, int index) { | |
16667 | + boolean restarting, boolean allowRestart, int index, boolean replacingPid) { | |
16668 | + Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid); | |
16658 | 16669 | if (index >= 0) { |
16659 | 16670 | removeLruProcessLocked(app); |
16660 | 16671 | ProcessList.remove(app.pid); |
@@ -16785,7 +16796,9 @@ public final class ActivityManagerService extends ActivityManagerNative | ||
16785 | 16796 | if (!app.persistent || app.isolated) { |
16786 | 16797 | if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP, |
16787 | 16798 | "Removing non-persistent process during cleanup: " + app); |
16788 | - removeProcessNameLocked(app.processName, app.uid); | |
16799 | + if (!replacingPid) { | |
16800 | + removeProcessNameLocked(app.processName, app.uid); | |
16801 | + } | |
16789 | 16802 | if (mHeavyWeightProcess == app) { |
16790 | 16803 | mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, |
16791 | 16804 | mHeavyWeightProcess.userId, 0)); |
@@ -20996,7 +21009,7 @@ public final class ActivityManagerService extends ActivityManagerNative | ||
20996 | 21009 | // Ignore exceptions. |
20997 | 21010 | } |
20998 | 21011 | } |
20999 | - cleanUpApplicationRecordLocked(app, false, true, -1); | |
21012 | + cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/); | |
21000 | 21013 | mRemovedProcesses.remove(i); |
21001 | 21014 | |
21002 | 21015 | if (app.persistent) { |
@@ -302,6 +302,11 @@ public final class BroadcastQueue { | ||
302 | 302 | boolean didSomething = false; |
303 | 303 | final BroadcastRecord br = mPendingBroadcast; |
304 | 304 | if (br != null && br.curApp.pid == app.pid) { |
305 | + if (br.curApp != app) { | |
306 | + Slog.e(TAG, "App mismatch when sending pending broadcast to " | |
307 | + + app.processName + ", intended target is " + br.curApp.processName); | |
308 | + return false; | |
309 | + } | |
305 | 310 | try { |
306 | 311 | mPendingBroadcast = null; |
307 | 312 | processCurBroadcastLocked(br, app); |
@@ -39,9 +39,9 @@ public abstract class AuthenticationClient extends ClientMonitor { | ||
39 | 39 | public abstract void resetFailedAttempts(); |
40 | 40 | |
41 | 41 | public AuthenticationClient(Context context, long halDeviceId, IBinder token, |
42 | - IFingerprintServiceReceiver receiver, int callingUserId, int groupId, long opId, | |
42 | + IFingerprintServiceReceiver receiver, int targetUserId, int groupId, long opId, | |
43 | 43 | boolean restricted, String owner) { |
44 | - super(context, halDeviceId, token, receiver, callingUserId, groupId, restricted, owner); | |
44 | + super(context, halDeviceId, token, receiver, targetUserId, groupId, restricted, owner); | |
45 | 45 | mOpId = opId; |
46 | 46 | } |
47 | 47 |
@@ -65,7 +65,7 @@ public abstract class AuthenticationClient extends ClientMonitor { | ||
65 | 65 | Fingerprint fp = !getIsRestricted() |
66 | 66 | ? new Fingerprint("" /* TODO */, groupId, fingerId, getHalDeviceId()) |
67 | 67 | : null; |
68 | - receiver.onAuthenticationSucceeded(getHalDeviceId(), fp); | |
68 | + receiver.onAuthenticationSucceeded(getHalDeviceId(), fp, getTargetUserId()); | |
69 | 69 | } |
70 | 70 | } catch (RemoteException e) { |
71 | 71 | Slog.w(TAG, "Failed to notify Authenticated:", e); |
@@ -501,7 +501,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe | ||
501 | 501 | if (DEBUG) Slog.v(TAG, "startAuthentication(" + opPackageName + ")"); |
502 | 502 | |
503 | 503 | AuthenticationClient client = new AuthenticationClient(getContext(), mHalDeviceId, token, |
504 | - receiver, callingUserId, groupId, opId, restricted, opPackageName) { | |
504 | + receiver, mCurrentUserId, groupId, opId, restricted, opPackageName) { | |
505 | 505 | @Override |
506 | 506 | public boolean handleFailedAttempt() { |
507 | 507 | mFailedAttempts++; |
@@ -22,6 +22,12 @@ import android.util.Log; | ||
22 | 22 | import java.io.IOException; |
23 | 23 | import java.net.HttpURLConnection; |
24 | 24 | import java.net.URL; |
25 | + | |
26 | +import libcore.io.IoUtils; | |
27 | + | |
28 | +import java.io.ByteArrayOutputStream; | |
29 | +import java.io.InputStream; | |
30 | +import java.io.IOException; | |
25 | 31 | import java.util.Properties; |
26 | 32 | import java.util.Random; |
27 | 33 | import java.util.concurrent.TimeUnit; |
@@ -37,6 +43,7 @@ public class GpsXtraDownloader { | ||
37 | 43 | |
38 | 44 | private static final String TAG = "GpsXtraDownloader"; |
39 | 45 | private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); |
46 | + private static final long MAXIMUM_CONTENT_LENGTH_BYTES = 1000000; // 1MB. | |
40 | 47 | private static final String DEFAULT_USER_AGENT = "Android"; |
41 | 48 | private static final int CONNECTION_TIMEOUT_MS = (int) TimeUnit.SECONDS.toMillis(30); |
42 | 49 |
@@ -124,7 +131,19 @@ public class GpsXtraDownloader { | ||
124 | 131 | return null; |
125 | 132 | } |
126 | 133 | |
127 | - return Streams.readFully(connection.getInputStream()); | |
134 | + try (InputStream in = connection.getInputStream()) { | |
135 | + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); | |
136 | + byte[] buffer = new byte[1024]; | |
137 | + int count; | |
138 | + while ((count = in.read(buffer)) != -1) { | |
139 | + bytes.write(buffer, 0, count); | |
140 | + if (bytes.size() > MAXIMUM_CONTENT_LENGTH_BYTES) { | |
141 | + if (DEBUG) Log.d(TAG, "XTRA file too large"); | |
142 | + return null; | |
143 | + } | |
144 | + } | |
145 | + return bytes.toByteArray(); | |
146 | + } | |
128 | 147 | } catch (IOException ioe) { |
129 | 148 | if (DEBUG) Log.d(TAG, "Error downloading gps XTRA: ", ioe); |
130 | 149 | } finally { |
@@ -136,3 +155,4 @@ public class GpsXtraDownloader { | ||
136 | 155 | } |
137 | 156 | |
138 | 157 | } |
158 | + |